var id = document.location.pathname.split('/')[1];
var annotations = [];
var currentPage = 1, rendered = false
var highlightInactive = true
var selectedAnnotation

const SELECTION = 0
const HIGHLIGHT = 1


var div = document.createElement("div")
div.innerHTML = `
<button id="cropFile" class="toolbarButton cropFile hiddenLargeView" title="Highlight" tabindex="30" data-l10n-id="crop_file">
    <span data-l10n-id="crop_file_label">Highlight</span>
</button>
`
var cropFile = div.querySelector("#cropFile")

document.querySelector('#toolbarViewerRight').insertBefore(cropFile, document.querySelector('#toolbarViewerRight').firstChild)

// secondary menu
div.innerHTML = `
<button id="secondaryCropFile" class="secondaryToolbarButton visibleMediumView cropFile" title="Highlight" tabindex="50" data-l10n-id="crop">
  <span data-l10n-id="crop_label">Highlight</span>
</button>
`
var secondaryCropFile = div.querySelector("#secondaryCropFile")
document.querySelector('#secondaryToolbarButtonContainer').insertBefore(
    secondaryCropFile,
    document.querySelector('#secondaryToolbarButtonContainer').firstChild
)

function initOverlay() {
    document.querySelectorAll('#cropFile,.secondaryToolbarButton.cropFile').forEach(btn => {
        btn.addEventListener('click', event=> {
            if (highlightInactive) {
                event.target.style.background = 'red'
                highlightInactive = false
                document.querySelectorAll('.crop-overlay.inactive').forEach(element => {
                    element.classList.remove('inactive')
                })
            } else {
                event.target.style.background = ''
                highlightInactive = true
                document.querySelectorAll('.crop-overlay').forEach(element => {
                    element.classList.add('inactive')
                })
            }
        })
    })
    PDFViewerApplication.initializedPromise.then(function() {
        PDFViewerApplication.pdfViewer.eventBus.on("pagesinit", function(event) {
            /*
            document.querySelector('#viewerContainer').addEventListener('scroll', event => {
                if (window.parent && window.parent.postMessage) {
                    if (first) {
                        first = false
                    } else {
                        window.parent.postMessage({event: 'scrolled', top: event.target.scrollTop})
                    }
                }
            })
            */
        })
        PDFViewerApplication.pdfViewer.eventBus.on("pagerender", function(event) {
            var page = event.pageNumber.toString()
            var div = event.source.div
            var overlay = document.createElement('div')
            overlay.classList.add('crop-overlay')
            overlay.id = 'overlay' + page
            if (highlightInactive) {
                overlay.classList.add('inactive')
            }
            div.appendChild(overlay)

            renderHighlightSelectionOverlay(overlay, id, page, event.source)
            var highlights = document.createElement('div')
            highlights.classList.add('highlights')
            highlights.id = 'highlights' + page
            var canvas = document.createElement('canvas')
            highlights.appendChild(canvas)
            div.appendChild(highlights)
            renderHighlights(page)
        })
        PDFViewerApplication.eventBus.on('pagerendered', function(event) {
            loadAnnotations(event.pageNumber)
        })
    })
}

document.addEventListener('DOMContentLoaded', function() {
    window.PDFViewerApplication ? initOverlay() : document.addEventListener("webviewerloaded", initOverlay)
})


Ox.load({
    'UI': {
        loadCSS: false
    }
}, function() {
    Ox.$parent.bindMessage(function(data, event) {
        if (event == 'selectAnnotation') {
            var annotation = annotations.filter(function(a) { return a.id == data.id })[0]
            var delay = 0
            if (
                annotation &&
                annotation.page &&
                PDFViewerApplication.pdfViewer.currentPageNumber != annotation.page
            ) {
                PDFViewerApplication.pdfViewer.currentPageNumber = annotation.page;
                delay = 250
            }
            annotation && setTimeout(function() {
                var el = document.querySelector('.a' + annotation.id);
                if (el && !isInView(el)) {
                    document.querySelector('#viewerContainer').scrollTop = el.offsetTop + el.parentElement.offsetTop - 64;
                }
            }, delay)
            var oldSelection = selectedAnnotation
            selectedAnnotation = data.id
            selectAnnotation(data.id)
            if (oldSelection) {
                var old = annotations.filter(function(a) { return a.id == oldSelection })[0]
                if (old && old.type == HIGHLIGHT) {
                    renderHighlights(old.page)
                }
            }
        } else if (event == 'addAnnotation') {
            createAnnotation()
        } else if (event == 'addAnnotations') {
            if (data.replace) {
                document.querySelectorAll('.oml-annotation').forEach(function(a) {
                    a.remove()
                })
                annotations = []
            }
            data.annotations.forEach(function(annotation) {
                annotations.push(annotation)
                if (annotation.type == HIGHLIGHT) {
                    renderHighlights(annotation.page)
                } else {
                    renderAnnotation(annotation)
                }
            })
        } else if (event == 'removeAnnotation') {
            removeAnnotation(data.id)
        } else {
            console.log('got', event, 'data', data)
        }
    })
})

window.addEventListener('keydown', function(event) {
    if (event.key == 'Delete') {
        var selected = document.querySelector('.oml-annotation.selected')
        if (selected) {
            removeAnnotation(selected.dataset.id)
        }
    } else if (event.key == 'n' || event.keyCode == 13) {
        if (event.target.nodeName != 'INPUT') {
            var selected = document.querySelector('.oml-annotation.selected')
            if (!window.getSelection().isCollapsed) {
                createAnnotation()
            } else if (selected) {
                console.log('editNote?', selected.dataset.id)
            }
            event.stopPropagation()
            event.preventDefault()
        }
    }
})
window.addEventListener('mouseup', function(event) {
    var selection = window.getSelection()
    if (selection.isCollapsed) {
        Ox.$parent.postMessage('selectText', false)
    } else {
        Ox.$parent.postMessage('selectText', true)
    }
})

function getHighlight() {
    var pageNumber = PDFViewerApplication.pdfViewer.currentPageNumber;
    var pageIndex = pageNumber - 1;
    var page = PDFViewerApplication.pdfViewer.getPageView(pageIndex);
    var pageRect = page.canvas.getClientRects()[0];
    var selection = window.getSelection()
    var selectionRects = selection.getRangeAt(0).getClientRects();
    var viewport = page.viewport;
    var selected = Array.from(selectionRects).map(function (r) {
      return viewport.convertToPdfPoint(r.left - pageRect.x, r.top - pageRect.y).concat(
         viewport.convertToPdfPoint(r.right - pageRect.x, r.bottom - pageRect.y)); 
    });
    var text = selection.toString();
    var position = [pageNumber].concat(Ox.sort(selected.map(function(c) { return [c[1], c[0]]}))[0]);
    return {
        type: SELECTION,
        page: pageNumber,
        pageLabel: PDFViewerApplication.pdfViewer.currentPageLabel,
        position: position,
        coords: selected,
        text: text,
        id: Ox.SHA1(pageNumber.toString() + JSON.stringify(selected))
    };
}

function createAnnotation() {
    var selected = document.querySelector('.oml-annotation.selected')
    if (selected) {
        deselectAllAnnotations()
    }
    var annot = getHighlight()
    renderAnnotation(annot)
    addAnnotation(annot)
    window.getSelection().removeAllRanges();
}


function renderAnnotation(annotation) {
    var pageIndex = annotation.page - 1;
    var page = PDFViewerApplication.pdfViewer.getPageView(pageIndex);
    if (!page || !page.canvas) {
        setTimeout(function() {
            renderAnnotation(annotation)
        }, 50)
        return
    }
    var pageElement = page.canvas.parentElement.parentElement;
    var viewport = page.viewport;
    if (annotation.type == HIGHLIGHT) {
        renderHighlights(annotation.page)
    } else if (annotation.coords) {
        pageElement.querySelectorAll('.oml-annotation').forEach(el => el.remove())
        annotation.coords.forEach(function (rect) {
            var bounds = viewport.convertToViewportRectangle(rect);
            var el = document.createElement('div');
            el.classList.add('oml-annotation')
            el.classList.add('a' + annotation.id)
            el.classList.add('page' + annotation.page)
            el.dataset.id = annotation.id
            el.setAttribute('style', 'position: absolute; background-color: yellow;opacity:0.3;' + 
                'left:' + Math.min(bounds[0], bounds[2]) + 'px; top:' + Math.min(bounds[1], bounds[3]) + 'px;' +
                'width:' + Math.abs(bounds[0] - bounds[2]) + 'px; height:' + Math.abs(bounds[1] - bounds[3]) + 'px;');

            el.addEventListener('click', function() {
                if (!el.classList.contains('selected')) {
                    selectAnnotation(annotation.id)
                    Ox.$parent.postMessage('selectAnnotation', {id: annotation.id})
                }
            });
            pageElement.appendChild(el);
        });
    } else {
       // console.log("annotation without position", annotation)
    }
}

function addAnnotation(annotation) {
    annotations.push(annotation)
    Ox.$parent.postMessage('addAnnotation', annotation)
}

function selectAnnotation(id) {
    document.querySelectorAll('.oml-annotation.selected').forEach(function(g) {
        g.classList.remove('selected')
        g.style.backgroundColor = 'yellow'
    })
    document.querySelectorAll('.oml-annotation.a' + id).forEach(function(g) {
        g.classList.add('selected')
        g.style.backgroundColor = 'blue'
    })
    annotations.forEach(a => {
        if (a.id == id && a.type == HIGHLIGHT) {
            renderHighlights(a.page)
        }
    })
}

function deselectAnnotation(id) {
    document.querySelectorAll('.oml-annotation.a' + id).forEach(function(g) {
        g.classList.remove('selected')
        g.style.backgroundColor = 'yellow'
    })
}

function deselectAllAnnotations() {
    var ids = []
    document.querySelectorAll('.oml-annotation.selected').forEach(function(g) {
        g.classList.remove('selected')
        g.style.backgroundColor = 'yellow'
        var id = $(g).parents('.oml-annotation').data('id')
        //console.log('deselect', g, id)
        if (!Ox.contains(ids, id)) {
            ids.push(id)
            Ox.$parent.postMessage('selectAnnotation', {id: null})
        }
    })
}

function removeAnnotation(id) {
    document.querySelectorAll('.oml-annotation.a' + id).forEach(function(a) {
        a.remove()
    })
    annotations = annotations.filter(function(annotation) {
        return annotation.id != id
    })
    Ox.$parent.postMessage('removeAnnotation', {id: id})
}

function loadAnnotations(page) {
    document.querySelectorAll('.oml-annotation.page' + page).forEach(function(e) {
        e.remove()
    })
    annotations.filter(function(a) {
        return a.page == page && !a.type == HIGHLIGHT
    }).forEach(function(annot) {
        renderAnnotation(annot)
    })
}

function isInView(element) {
    var docViewTop = $(window).scrollTop();
    var docViewBottom = docViewTop + $(window).height();
    var elementTop = $(element).offset().top;
    var elementBottom = elementTop + $(element).height();
    return elementTop < docViewBottom && elementBottom > docViewTop;
}

function renderHighlightSelectionOverlay(root, documentId, page, source) {
    var canvas = document.createElement('canvas')
    root.appendChild(canvas)
    canvas.width = canvas.clientWidth
    canvas.height = canvas.clientHeight
    var ctx = canvas.getContext('2d');
    var viewerContainer = document.querySelector('#viewerContainer')
    var bounds = root.getBoundingClientRect();
    var base = 2048
    var scale = Math.max(bounds.height, bounds.width) / base
    var last_mousex = last_mousey = 0;
    var mousex = mousey = 0;
    var mousedown = false;
    var p = {
        top: 0,
        left: 0,
        bottom: 0,
        right: 0
    }
    var inside = false

    canvas.addEventListener('mousedown', function(e) {
        if (inside) {
            const coords = [
                [p.left, p.top, p.right, p.bottom]
            ]
            addAnnotation({
                type: HIGHLIGHT,
                id: Ox.SHA1(pageNumber.toString() + JSON.stringify(p)),
                text: "",
                page: parseInt(page),
                pageLabel: source.pageLabel,
                coords: coords,
            })
            return
        }
        let bounds = root.getBoundingClientRect();
        last_mousex = e.clientX - bounds.left;
        last_mousey = e.clientY - bounds.top;
        p.top = parseInt(last_mousey / scale)
        p.left = parseInt(last_mousex / scale)
        mousedown = true;
    });

    document.addEventListener('mouseup', function(e) {
        if (mousedown) {
            mousedown = false;
            p.bottom = parseInt(mousey / scale)
            p.right = parseInt(mousex / scale)

            if (p.top > p.bottom) {
                var t = p.top
                p.top = p.bottom
                p.bottom = t
            }
            if (p.left > p.right) {
                var t = p.left
                p.left = p.right
                p.right = t
            }
            /*
            var url = `${baseUrl}/documents/${documentId}/2048p${page},${p.left},${p.top},${p.right},${p.bottom}.jpg`
            info.url = `${baseUrl}/document/${documentId}/${page}`
            info.page = page
            if (p.left != p.right && p.top != p.bottom) {
                var context = formatOutput(info, url)
                copyToClipboard(context)
                addToRecent({
                    document: documentId,
                    page: parseInt(page),
                    title: info.title,
                    type: 'fragment',
                    link: `${baseUrl}/documents/${documentId}/${page}`,
                    src: url
                })
            }
            */
        }
    });

    canvas.addEventListener('mousemove', function(e) {
        let bounds = root.getBoundingClientRect();
        mousex = e.clientX - bounds.left;
        mousey = e.clientY - bounds.top;

        if(mousedown) {
            ctx.clearRect(0, 0, canvas.clientWidth, canvas.clientHeight)
            ctx.beginPath()
            var width = mousex - last_mousex
            var height = mousey - last_mousey
            ctx.rect(last_mousex, last_mousey, width, height)
            ctx.strokeStyle = 'black';
            ctx.lineWidth = 2;
            ctx.stroke();
        } else {
            let py = parseInt(mousey / scale)
            let px = parseInt(mousex / scale)
            if (py > p.top && py < p.bottom && px > p.left && px < p.right) {
                inside = true
                canvas.style.cursor = 'pointer'
                canvas.title = 'Click to add highlight'
            } else {
                inside = false
                canvas.style.cursor = ''
                canvas.title = ''
            }
        }
    });
}
function renderHighlights(page) {
    var pageAnnotations = annotations.filter(annotation => {
        return annotation.type == HIGHLIGHT && (!page || (annotation.page == page))
    })
    pageAnnotations.forEach(annotation => {
        let page = annotation.page
        var canvas = document.querySelector(`#highlights${page} canvas`)
        if (canvas) {
            canvas.width = canvas.clientWidth
            canvas.height = canvas.clientHeight
            var ctx = canvas.getContext('2d');
            var viewerContainer = document.querySelector('#viewerContainer')
            var bounds = canvas.parentElement.getBoundingClientRect();
            var base = 2048
            var scale = Math.max(bounds.height, bounds.width) / base
            ctx.clearRect(0, 0, canvas.clientWidth, canvas.clientHeight)
            pageAnnotations.forEach(annotation => {
                    ctx.beginPath()
                    ctx.strokeStyle = annotation.id == selectedAnnotation ? 'blue' : 'yellow';
                    ctx.lineWidth = 2;
                    annotation.coords.forEach(coord => {
                        const width = coord[2] - coord[0],
                              height = coord[3] - coord[1];
                        ctx.rect(coord[0] * scale, coord[1] * scale, width * scale, height * scale)
                    })
                    ctx.stroke();
            })

        }
    })

}