/**
 * new Img2Video(opt)
 */
import 'babel-polyfill'

let requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame ||
    window.webkitRequestAnimationFrame || window.msRequestAnimationFrame || function (callback) {
        window.setTimeout(callback, 1000 / 60)
    }

let cancelAnimationFrame = window.cancelAnimationFrame || window.mozCancelAnimationFrame || function (id) {
    window.clearTimeout(id)
}
/**
 * 图片帧 转 视频（只允许全屏）
 */
class Img2Video {
    constructor(opt) {
        this.opt = opt
        this.el = document.querySelector(opt.el)
        this.ctx = this.el.getContext('2d')
        this.frameSet = opt.frameSet || 12 //每秒的帧数
        this.frames = []//帧源
        this.preloadFrames = []//预下载帧源
        this.preloadXhr = []//预下载请求
        this.frame = 0 // 当前帧下标
        this.loadedFrame = 0 // 预加载帧源数量
        this.precent = 0 // 预加载帧源百分比
        this.played = false // 播放状态
        this.preloadValue = opt.preload || 'all' // [all,none,percent]
        this.preloadPercent = this.preloadValue == 'all' ? 100 : this.preloadValue == 'none' ? 0 : this.preloadValue * 1//[100,0,percent]

        /**回调方法 */
        this.preloaded = opt.preloaded
        this.play = opt.play
        this.timeUpdate = opt.timeUpdate
        this.end = opt.end
        this.loadProgress = opt.loadProgress

        this.init()
    }
    /**
     * 初始化
     */
    init() {
        this.resizeCanvas()
        this.initPreload()
    }

    initPreload() {
        this.opt.frames.forEach(img => {
            this.frames.push(img)

            this.preloadFrames.push({
                data: img,
                loaded: false
            })
        })
        if (this.preloadPercent) {
            this.preload(false)
        }
    }
    /**
     * 预加载 返回promise
     */
    preload(all = false) {
        let preloadCount = Math.floor(this.frames.length * this.preloadPercent / 100),
            allCount = this.frames.length

        if (this.loadedFrame >= allCount - 1) return

        this.loadedPromise = new Promise((resolve, reject) => {

            this.preloadFrames.forEach((preloadFrame, index) => {
                if (all == false && index >= preloadCount - 1) {
                    return
                } else if (preloadFrame.loaded) {
                    return
                }
                let imgEle = new Image()

                imgEle.src = preloadFrame.data

                imgEle.onload = () => {
                    preloadFrame.loaded = true
                    this.loadedFrame++
                    this.precent = this.loadedFrame / allCount * 100
                    this.loadProgress && this.loadProgress(this.precent)
                    if (preloadCount && this.loadedFrame >= preloadCount - 1) {
                        resolve()
                    }
                }

                imgEle.onerror = () => {
                    imgEle.src = `${img}?_=${(new Date).getTime()}`
                }

                preloadFrame.imgEle = imgEle
            })

        }).then(this.preloaded)

        return this.loadedPromise
    }

    /**
     * 开始播放视频 返回promise
     */
    start() {
        if (this.played) return

        if (!(this.loadedFrame >= this.frames.length - 1)) {
            this.preload(true)
        }

        this.played = true

        this.play && this.play()

        this.endPromise = new Promise((resolve, reject) => {
            let frameSet = this.frameSet,
                maxFrame = this.frames.length,
                count = 0,
                playVideo = () => {
                    let frame = this.frame,
                        frameData = this.preloadFrames[frame]

                    this.requestAnimationFrameId = requestAnimationFrame(playVideo)

                    if (this.played == false) return

                    if (count % parseInt(60 / frameSet) == 0) {
                        if (frame >= maxFrame - 1) {
                            cancelAnimationFrame(this.requestAnimationFrameId)
                            resolve()
                            return
                        } else if (!frameData.loaded) {
                            return
                        }
                        this.timeUpdate && this.timeUpdate.call(this, frame)
                        this.ctx.drawImage(frameData.imgEle, 0, 0, this.el.width, this.el.height)
                        this.frame++
                    }
                    count++
                }

            this.ctx.clearRect(0, 0, this.el.width, this.el.height)

            playVideo()

        }).then(() => {
            this.played = false
        }).then(this.end)

        return this.endPromise
    }

    /**
     * 重绘当前
     */
    repaintVideo() {
        if (this.frames.length == 0) return
        this.ctx.clearRect(0, 0, this.el.width, this.el.height)
        this.ctx.drawImage(this.preloadFrames[this.frame].imgEle, 0, 0, this.el.width, this.el.height)
    }

    /**
     * 暂停
     */
    pause() {
        this.played = false
        cancelAnimationFrame(this.requestAnimationFrameId)
    }

    /**
     * 适配横屏
     */
    resizeCanvas() {
        let _resizeCanvas = () => {
            let canvas = this.el,
                canvasHeight = parseInt(window.innerWidth * 9 / 16)

            if (canvas.height == canvasHeight) return

            canvasHeight = canvasHeight > window.innerHeight ? window.innerHeight : canvasHeight

            canvas.style.width = window.innerWidth + 'px'
            canvas.style.height = canvasHeight + 'px'
            canvas.width = window.innerWidth
            canvas.height = canvasHeight

            this.repaintVideo()
        }

        window.addEventListener("resize", _resizeCanvas, false)

        _resizeCanvas()

        return this
    }
}


export default Img2Video