var layer = 'keywords'
var imageResolution = 480

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

function updatePlayerRect(video, frame, config) {
    var top, rect = frame.getBoundingClientRect();
    if (config.root && config.mode != "single") {
        var root_rect = config.root.getBoundingClientRect();
        //console.log('rect.top', rect.top, 'window.scrollY', window.scrollY, 'root_rect.top', root_rect.top)
        top = rect.top - root_rect.top
        video.style.left = ''
    } else {
        top = rect.top + window.scrollY
        video.style.left = rect.x + 'px'
    }
    video.style.top = top + 'px'
    video.style.display = 'block';
    video.style.maxWidth = rect.width + 'px'
}

function updatePlayer(video, frame, currentTime, out, src, config) {
    video.style.opacity = 0
    //console.log('update player', currentTime, out, src)
    updatePlayerRect(video, frame, config)
    if (src && config.loaded) {
        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._root = config.root
    video._frame = frame
    if (config.mode == "single") {
        video._text = frame.parentElement.querySelector('.text')
    } else {
        video._text = null
    }
    const show = event => {
        video.style.opacity = 1
        video.muted = muted
        video.removeEventListener('seeked', show)
    }
    video.addEventListener('seeked', show)
    video.play()
}


function timeupdate(event) {
    if (event.target.dataset.out && event.target.dataset.in) {
        var in_= parseFloat(event.target.dataset.in)
        var out_= parseFloat(event.target.dataset.out)
        var currentTime = event.target.currentTime
        if (event.target._text) {
            event.target._text.querySelectorAll('.annotation').forEach(annot => {
                var ain = parseFloat(annot.dataset.in)
                var aout = parseFloat(annot.dataset.out)
                if (ain <= currentTime && aout > currentTime) {
                    annot.style.display = ''
                } else {
                    annot.style.display = 'none'
                }
            })

        }
        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, ascroll) {
    var info = document.createElement('div')
    if (config.title) {
        var h1 = document.createElement('h1')
        h1.innerHTML = config.title
        info.appendChild(h1)
    }
    if (config.byline) {
        var h2 = document.createElement('h2')
        h2.innerHTML = config.byline
        info.appendChild(h2)
    }
    if (config.annotations.length && config.body) {
        var div = document.createElement('div')
        div.classList.add('intro')
        div.innerHTML = config.body
        info.appendChild(div)
    }
    ascroll.appendChild(info)
    if (!config.annotations.length && config.body) {
        var div = document.createElement('div')
        div.innerHTML = config.body
        ascroll.appendChild(div)
    }
    return info
}

function renderAnnotation(config, video, root, clip) {
    var div = document.createElement('div')
    div.classList.add('annotation')
    var annotation = clip.annotations[0]
    var color1 = `hsl(${clip.color1.hue}, 60%, 15%)`
    var color2 = `hsl(${clip.color2.hue}, 60%, 15%)`
    if (!config.first) {
        config.first = annotation
        config.info.style.background = color1
    }
    div.style.background = `linear-gradient(to bottom, ${color1}, ${color2})`;
    var figcaption = ''
    if (annotation.title) {
        var title = annotation.title
        var txt = `${title}`
        figcaption = `<figcaption><a href="${pandoraURL}/${annotation.id}" target="_blank">${txt}</a></figcaption>`
    }
    var values = []
    clip.annotations.forEach(a => {
        values.push(a.value.replace(/src="\//g, `src="${streamPrefix}/`).replace(/href="\//g, `href="${pandoraURL}/`))
    })
    values = values.join('<br><br>')
    div.innerHTML = `
        <div class="frame">
            <figure>
                <img src="${streamPrefix}/${annotation.id.split('/')[0]}/${imageResolution}p${annotation.in}.jpg">
                ${figcaption}
            </figure>
        </div>
        <div class="text">${values}</div>
    `
    root.appendChild(div)
    var frame = div.querySelector('.frame')
    document.addEventListener('scroll', onVisibilityChange(div.querySelector('.frame'), function(visible) {
        var src
        if (clip.src) {
            src = clip.src
        } else if (config.edit) {
            src = `${streamPrefix}/${annotation.id.split('/')[0]}/480p.webm`
        }
        if (config.loaded && visible) {
            updatePlayer(video, frame, annotation['in'], annotation['out'], src, config)
        }
    }))
    window.addEventListener('resize', () => {
        var visible = video._frame == frame;
        if (config.loaded && visible) {
            updatePlayerRect(video, frame, config)
        }
    }, false);
}

function renderAnnotations(config) {
    //console.log('renderAnnotations', config.item, config.annotations.length)
    var ascroll = config.root ? config.root : document.querySelector('#ascroll')
    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 = true
    if (config.item) {
        setVideoSrc(video, `${streamPrefix}/${config.item}/480p.webm`)
    }
    video.addEventListener('timeupdate', timeupdate)
    video.addEventListener('touchstart', showOverlay)
    video.addEventListener('mouseover', showOverlay)
    var box = document.createElement('div')
    box.classList.add('vbox')
    box.appendChild(video)
    ascroll.appendChild(box)

    config.info = formatInfo(config, ascroll)
    config.annotations.forEach(annotation => {
        renderAnnotation(config, video, ascroll, annotation)
    })
    config.loaded = true
    if (config.first) {
        let frame = ascroll.querySelector('.annotation .frame')
        if (frame) {
            var src
            if (config.edit) {
                src = `${streamPrefix}/${config.first.id.split('/')[0]}/480p.webm`
            }
            updatePlayer(video, frame, config.first['in'], config.first['out'], src, config)
        }
    }
}

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 = {}
        var clips = {}
        response.data.items.forEach(clip => {
            colors[clip.id] = clip
        })
        var previous

        annotations.forEach(annotation => {
            var clipId = annotation.clipId || annotation.id.split('/')[0] + '/' + annotation.in.toFixed(3)  + '-'+ annotation.out.toFixed(3)
            if (!colors[clipId]) {
                console.log('no match for clip', clipId)
                return
            }
            clips[clipId] = clips[clipId] || {
                id: clipId,
                color1:  colors[clipId],
                annotations: []
            }
            clips[clipId].annotations.push(annotation)
            annotation.color1 = colors[clipId]
            if(previous && previous.id != clipId) {
                previous.color2 = clips[clipId].color1
            }
            if (!previous || previous.id != clipId) {
                previous = clips[clipId]
            }
        })
        var clips = Object.values(clips)
        if (clips.length) {
            clips[clips.length - 1].color2 = clips[0].color1
        }
        //return annotations
        return clips
    })
}

async function loadAnnotations(config) {
    var layers = config.layer || config.layers || []
    if (!Array.isArray(layers)) {
        layers = [layers]
    }
    if (config.item && !layers.length) {
        // load player only view
        config.annotations = [
            {
                "in": config["in"],
                "out": config["out"],
                "id": config["item"] + "/" + config["in"].toFixed(3)  + '-'+ config.out.toFixed(3),
                "annotations": [{
                    "id": config["item"] + "/" + config["in"].toFixed(3)  + '-'+ config.out.toFixed(3),
                    "value": "",
                    "in": config["in"],
                    "out": config["out"],
                }],
                "color1": "",
                "color2": "",
            }
        ]
        return config
    } else if (config.item) {
        return pandoraAPI('get', {id: config.item, keys: [
            'layers'
        ]}).then(response => {
            var annotations = []
            layers.forEach(layer => {
                if (!response.data.layers[layer]) {
                    console.log("ERROR", config.item, layer, "missing", config.root)
                }
                response.data.layers[layer] && response.data.layers[layer].forEach(annotation => {
                    annotation.clipId = annotation.id.split('/')[0] + '/' + annotation.in.toFixed(3)  + '-'+ annotation.out.toFixed(3)
                    if (!(config.user && annotation.user != config.user) && isInside(config, annotation)) {
                        annotations.push(annotation)
                    }
                })
            })
            return 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
                    }
                })
                return config
            })
        })
    } else {
        var cited = {}
        if (config.edit) {
            return 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
                    }
                    layers.forEach(layer => {
                        clip.layers[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)
                                //}
                            }
                        })
                    })
                })
                return loadClips(annotations).then(annotations => {
                    config.annotations = annotations
                    config.cited = Object.values(cited)
                    return config
                })
            })
        } else {
            if (!config.annotations) {
                config.annotations = []
            }
            return config
       }
    }
}


function renderSingleMode(config) {
    var src
    config.annotations.forEach(annotation => {
        src = annotation.src = `${streamPrefix}/${annotation.id.split('/')[0]}/480p.webm`
    })
    var div = document.createElement('div')
    var annotation = config.annotations[0].annotations[0]
    var figcaption = ''
    div.classList.add('single-node')
    div.classList.add('annotation')
    div.innerHTML = `
        <div class="frame">
            <figure>
                <img src="${streamPrefix}/${annotation.id.split('/')[0]}/${imageResolution}p${annotation.in}.jpg">
                ${figcaption}
            </figure>
        </div>
        <div class="text"></div>
    `
    config.root.appendChild(div)
    var frame = div.querySelector('.frame')
    var text = div.querySelector('.text')
    document.addEventListener('scroll', onVisibilityChange(div.querySelector('.frame'), function(visible) {
        if (config.loaded && visible) {
            updatePlayer(config.video, frame, config['in'], config['out'], src, config)
        }
    }))
    config.annotations.forEach(clip => {
        var values = []
        clip.annotations.forEach(a => {
            values.push(a.value.replace(/src="\//g, `src="${streamPrefix}/`).replace(/href="\//g, `href="${pandoraURL}/`))
        })
        values = values.join('<br><br>')
        var annot = document.createElement('div')
        annot.classList.add('annotation')
        annot.innerHTML = values
        //console.log(clip)
        annot.dataset['in'] = clip.annotations[0]['in']
        annot.dataset['out'] = clip.annotations[0]['out']
        annot.style.display = 'none'
        text.appendChild(annot)
    })
    if (frame) {
        updatePlayer(config.video, frame, config['in'], config['out'], src, config)
    }
}


config.layer = config.layer || layer

if (false && config.annotations) {
    renderAnnotations(config)
} else {
    loadAnnotations(config).then(renderAnnotations)
}

window.addEventListener('resize', resize, false);