export class GoldCoinAni extends FYGE.Container {
    start: any;
    end: any;
    imgUrl: string; //金币的图标。
    isMinus: boolean; //true为向上凸，false为向下凹。
    startCallback: any; //第一个金币动效结束后的回调函数
    endCallback: any; //最后一个金币动效结束后的回调函数
    callback:any;
    lineCoords: any; //根据起始点计算出来的贝赛曲线坐标。
    curvature: number; //0-1之间，0代表直线，1代表最弯
    goldNum: number; //动效上面金币个数。
    time: number;//动效完成时间。
    coordNum:any;//坐标串个数
    /**
     * 
     * @param start 动效起点,[120,30]
     * @param end 动效终点,[120,30]
     * @param imgUrl 动效图片
     * @param callback 每一个金币动效结束时的回调
     * @param isMinus  true为向上凸，false为向下凹。
     * @param curvature 0-1之间，0代表直线，1代表最弯
     * @param goldNum 动效上面金币个数
     * @param time 动效完成时间
     * @param coordNum 路线上的坐标串个数
     */
    constructor(
        start,
        end,
        imgUrl,
        callback?: (start,end) => void,
        isMinus = false,
        curvature = 0.8,
        goldNum = 10,
        time = 20,
        coordNum = 20,
    ) {
        super();
        this.start = start;
        this.end = end;
        this.imgUrl = imgUrl;
        this.curvature = curvature;
        this.isMinus = isMinus;
        this.goldNum = goldNum;
        this.callback = callback;
        this.coordNum = goldNum > coordNum? goldNum:coordNum;
        this.time = time;
        this.initUi();
    }
    initUi() {}

    /**
     * 重设起点和终点
     * @param start [120,30]
     * @param end [120,30]
     */
    triggerAni(start = null, end = null) {
        if(start)this.start = start;
        if(end) this.end = end;
        this.lineCoords = this.getBeiSaiCoords(this.start, this.end);
        this._produceGoldCoinAni(this.createNewGoldCoin,(goldCodeNum)=>{
            this.callback && this.callback(goldCodeNum)
        });
    }
    createNewGoldCoin = (goldNum) => {
        this._produceGoldCoinAni(() => {},(goldCodeNum) => {this.callback && this.callback(goldCodeNum)},goldNum);
    }
    /**
     *
     * @param createNewGoldCoin 金币移动时的回调函数。
     * @param callback 到达终点位置后的回调函数
     * @param goldCodeNum 产生的金币编号。
     */
    _produceGoldCoinAni(
        createNewGoldCoin?: (goldNum: number) => void,
        callback?: (goldCodeNum) => void,
        goldCodeNum = 1
    ) {
        let coin = FYGE.Sprite.fromUrl(this.imgUrl);
        this.addChild(coin);
        coin["goldCodeNum"] = goldCodeNum;
        let index = 0;
        let timer = null;
        let x = Math.floor(this.lineCoords.length/this.goldNum);
        var loop = () => {
            timer && clearTimeout(timer);
            if (index === this.lineCoords.length) {
                callback && callback( coin["goldCodeNum"] );
                this.removeChild(coin);
                return;
            }
            coin.position.set(
                this.lineCoords[index][0],
                this.lineCoords[index][1]
            );
            if( goldCodeNum < this.goldNum && ((index+1)% x === 0) ){
                goldCodeNum ++;
                createNewGoldCoin && createNewGoldCoin(goldCodeNum);
            }
            index = index + 1;
            timer = this.setTimeoutSelf(() => {
                loop();
            }, this.time);
        };
        loop();
    }
    setTimeoutSelf(cb, interval) { // 实现setTimeout功能
        let now = Date.now
        let stime = now()
        let etime = stime
        let loop = () => {
            var timeoutTimer = requestAnimationFrame(loop)
            etime = now()
            if (etime - stime >= interval) {
                cb()
                cancelAnimationFrame(timeoutTimer)
            }
        }
        loop()
    }
    /**
     * 输入起点终点坐标，得到贝塞曲线坐标
     * @param start
     * @param end
     */
    getBeiSaiCoords(start, end) {
        let x1 = start[0];
        let y1 = start[1];
        let x2 = end[0];
        let y2 = end[1];
        let x3 = (x1 + x2) / 2 + (y1 - y2) * this.curvature;
        let y3 = (y1 + y2) / 2 + (x2 - x1) * this.curvature;
        if (this.isMinus) {
            x3 = (x1 + x2) / 2 - (y1 - y2) * this.curvature;
            y3 = (y1 + y2) / 2 - (x2 - x1) * this.curvature;
        }
        let coords = [];
        let speed =Number(1/this.coordNum);
        for (let t = 0; t <= 1; t += speed) {
            var x = quadraticBezier(x1, x3, x2, t);
            var y = quadraticBezier(y1, y3, y2, t);
            coords.push([x, y]);
        }
        function quadraticBezier(p1, p3, p2, t) {
            var k = 1 - t;
            return k * k * p1 + 2 * (1 - t) * t * p3 + t * t * p2;
        }
        return coords;
    }
}