var layer = 'keywords'
var imageResolution = 480
var videoExtension

function setVideoSrc(video, src) {
    var ext
    if (!videoExtension) {
        [
            ['video/mp4; codecs="avc1.42E01E, mp4a.40.2"', '.mp4'],
            ['video/webm; codecs="vp8, vorbis"', '.webm'],
        ].forEach(opt => {
            if (videoExtension) { return }
            if (video.canPlayType(opt[0]).replace('no', '')) {
                videoExtension = opt[1]
            }
        })
    }
    src = src.replace('.webm', videoExtension)
    if (src != video.src) {
        video.src = src
    }
}

function resize() {
    var video = document.querySelector('video')
    if (video && video._frame) {
        var rect = video._frame.getBoundingClientRect();
        video.style.top =  (rect.top + window.scrollY) + 'px'
    }
}

function updatePlayer(video, frame, currentTime, out, src) {
    var rect = frame.getBoundingClientRect();
    video.style.opacity = 0
    video.style.top =  (rect.top + window.scrollY) + 'px'
    video.style.display = 'block';
    if (src) {
        setVideoSrc(video, src)
    }
    //video.poster = frame.querySelector('img').src
    var muted = video.muted
    // video.muted = true
    video.currentTime = currentTime
    video.dataset.in = currentTime
    video.dataset.out = out
    video._frame = frame
    const show = event => {
        video.style.opacity = 1
        video.muted = muted
        video.removeEventListener('seeked', show)
    }
    video.addEventListener('seeked', show)
    video.play()
}

function isElementInViewport (el) {
    var rect = el.getBoundingClientRect();
    return (
        rect.top >= 0 &&
        rect.left >= 0 &&
        rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /* or $(window).height() */
        Math.floor(rect.right) <= (window.innerWidth || document.documentElement.clientWidth) /* or $(window).width() */
    );
}

function onVisibilityChange(el, callback) {
    var old_visible;
    return function () {
        var visible = isElementInViewport(el);
        if (visible != old_visible) {
            old_visible = visible;
            if (visible) {
                el.classList.add('visible')
            } else {
                el.classList.remove('visible')
            }
            if (typeof callback == 'function') {
                callback(visible);
            }
        }
    }
}

function scrollTo(element) {
    var delta = element.offsetTop - document.scrollingElement.scrollTop,
        duration = 1000, t = 40, n = duration / t,
        step = delta / n;

    function scroll() {
        if (document.scrollingElement.scrollTop + step > element.offsetTop) {
            document.scrollingElement.scrollTop = element.offsetTop
            n = 0
        } else {
            document.scrollingElement.scrollTop += step
        }
        n--
        if (n) setTimeout(scroll, t)
    }
    scroll()
}

function timeupdate(event) {
    var video = event.target
    var now = video.currentTime
    document.querySelectorAll('#player .annotation').forEach(annotation => {
        var display
        if (
            parseFloat(annotation.dataset['in']) < now && parseFloat(annotation.dataset['out']) > now
        ) {
            display = 'block'
        }   else {
            display = 'none'
        }
        if (annotation.style.display != display) {
            annotation.style.display = display
        }
    })
    if (event.target.dataset.out && event.target.dataset.in) {
        var in_= parseFloat(event.target.dataset.in)
        var out_= parseFloat(event.target.dataset.out)
        if (event.target.currentTime >= out_) {
            /*
            var next
            if (event.target._frame) {
                next = event.target._frame.parentElement.nextSibling
                if (next) {
                    next = next.querySelector('.frame')
                }
            }
            if (next) {
                scrollTo(next)
            } else {
                event.target.pause()
            }
            */
            if (config.pause) {
                event.target.pause()
            } else {
                event.target.currentTime = in_
            }
        }
    }
}

function formatInfo(config, player) {
    var info = document.createElement('div')
    info.classList.add('info')

    var folder = document.createElement('a')
    folder.href = '..'
    folder.innerHTML = config.folder
    var h1 = document.createElement('h1')
    h1.appendChild(folder)
    var title = document.createElement('span')
    title.innerHTML = ' - ' + config.title
    h1.appendChild(title)
    info.appendChild(h1)

    var folder = document.createElement('a')
    folder.href = '..'
    folder.innerHTML = config.folder
    var h1 = document.createElement('h1')
    h1.appendChild(folder)
    var title = document.createElement('span')
    title.innerHTML = ' - ' + config.title
    h1.appendChild(title)
    var t = document.querySelector('.topnav .item-title')
    t.appendChild(h1)


    player.appendChild(info)
    return info
}


function renderAnnotation(config, video, player, annotation) {
    var div = document.createElement('div')
    div.classList.add('annotation')

    annotation.value = annotation.value.replace(/src="\//g, `src="${pandoraURL}/`).replace(/href="\//g, `href="${pandoraURL}/`)
    div.dataset['in'] = annotation['in']
    div.dataset['out'] = annotation['out']
    div.innerHTML = `
        <div class="text">${annotation.value}</div>
    `
    player.appendChild(div)
}

function renderPlayer(config) {
    var player = document.querySelector('#ascroll')
    player.id = 'player'

    config.loaded = false
    var video = document.createElement('video')
    video.classList.add('player')
    video.playsinline = true
    video.setAttribute('playsinline', 'playsinline')
    video.setAttribute('webkit-playsinline', 'webkit-playsinline')
    video.WebKitPlaysInline = true
    video.muted = false
    video.controls = true
    if (config.item) {
        setVideoSrc(video, `${streamPrefix}/${config.item}/480p.webm`)
        video.poster = `${streamPrefix}/${config.item}/480p.jpg`
    }
    video.addEventListener('timeupdate', timeupdate)
    var box = document.createElement('div')
    box.classList.add('vbox')
    box.appendChild(video)
    config.info = formatInfo(config, player)

    var stage = document.createElement('div')
    stage.classList.add('stage')
    stage.appendChild(box)

    var div = document.createElement('div')
    div.classList.add('annotations')
    config.annotations.forEach(annotation => {
        renderAnnotation(config, video, div, annotation)
    })
    stage.appendChild(div)
    player.appendChild(stage)
    config.loaded = true
}

async function loadClips(annotations) {
    var items = annotations.map(annotation => annotation.id.split('/')[0])
    items = [...new Set(items)]
    return pandoraAPI('findClips', {itemsQuery: {
        conditions: [{key: 'id', operator: '&', value: items}]
    }, range: [0, 10000], keys: [
        'id', 'hue', 'saturation', 'lightness'
    ]}).then(response => {
        var colors = {}
        response.data.items.forEach(clip => {
            colors[clip.id] = clip
        })
        var previous
        annotations.forEach(annotation => {
            var clipId = annotation.id.split('/')[0] + '/' + annotation.in.toFixed(3)  + '-'+ annotation.out.toFixed(3)
            annotation.color1 = colors[clipId]
            if(previous) {
                previous.color2 = annotation.color1
            }
            previous = annotation
        })
        if (annotations.length) {
            annotations[annotations.length - 1].color2 = annotations[0].color1
        }
        return annotations
    })
}

function loadAnnotations(config) {
    if (config.item) {
        pandoraAPI('get', {id: config.item, keys: [
            'title', 'date', 'country', 'featuring', 'layers', 'folder'
        ]}).then(response => {
            ['title', 'date', 'country', 'featuring', 'folder'].forEach(key => {
                config[key] = response.data[key]
            })
            var annotations = []
            Object.keys(response.data.layers).forEach(layer => {
                response.data.layers[layer].forEach(annotation => {
                    if (!(config.user && annotation.user != config.user)) {
                        annotations.push(annotation)
                    }
                })
            })
            loadClips(annotations).then(annotations => {
                config.annotations = annotations.filter(annotation => {
                    if (config.only_e) {
                        if (annotation.value.slice(0, 2) == 'E:') {
                            annotation.value = annotation.value.slice(2).trim()
                            return true
                        } else {
                            return false
                        }
                    } else {
                        return annotation.value.slice(0, 2) != 'E:'
                    }
                })
                renderPlayer(config)
            })
        })
    } else {
        var cited = {}
        pandoraAPI('getEdit', {id: config.edit, keys: []}).then(response => {
            var annotations = []
            response.data.clips.forEach(clip => {
                cited[clip.item] = {
                    title: clip.title,
                    director: clip.director,
                    id: clip.item
                }
                clip.layers[config.layer].forEach(annotation => {
                    if (config.user && annotation.user != config.user) {
                        return
                    }
                    ;['title', 'director', 'date'].forEach(key => {
                        annotation[key] = clip[key]
                    })
                    if (config.only_e) {
                        if (annotation.value.slice(0, 2) == 'E:') {
                            annotation.value = annotation.value.slice(2).trim()
                            annotations.push(annotation)
                        }
                    } else {
                        if (annotation.value.slice(0, 2) != 'E:') {
                            annotations.push(annotation)
                        }
                    }
                })
            })
            loadClips(annotations).then(annotations => {
                config.annotations = annotations
                config.cited = Object.values(cited)
                renderPlayer(config)
            })
        })
    }
}

config.layer = config.layer || layer
loadAnnotations(config)
window.addEventListener('resize', resize, false);