import { playSound } from './../ctrls/soundCtrl';
import { GarbageTypes } from './GarbageTypes';
import { GCache } from '../../libs/tc/util/GCache';

import Scene from "../views/Scene";
import GameConst from "../GameConst";
import Garbage from './Garbage';
import Waiting from '../waiting/Waiting';
import SceneCtrl from '../ctrls/sceneCtrl';
import { ModuleTypes } from '../types/sceneTypes';
import GarbageConfig from './GarbageConfig';
import MovieClipCtrl from '../ctrls/MovieClipCtrl';

export default class PlayScene extends Scene {

    protected get skinKey() { return "Play" }

    public bg: eui.Image;
    public idler0: eui.Image;
    public idler1: eui.Image;
    public idler2: eui.Image;
    public idler3: eui.Image;
    public idler4: eui.Image;
    public idler5: eui.Image;
    public idler6: eui.Image;
    public leaves: eui.Image;
    public countDownBg: eui.Image;
    public scoreBg: eui.Image;
    public countDownTxt: eui.Label;
    public scoreTxt: eui.Label;
    public conveyor0: eui.Component;
    public conveyor1: eui.Component;
    public wetWaste: eui.Rect;
    public harmfulWaste: eui.Rect;
    public dryWaste: eui.Rect;
    public recoverableWaste: eui.Rect;
    public musicOn: eui.Image;
    public musicOff: eui.Image;
    public countDownGroup: eui.Group;
    public num3: eui.Image;
    public num2: eui.Image;
    public num1: eui.Image;
    public go: eui.Image;
    public guideGroup: eui.Group;
    public guideEle: eui.Image;


    private conveyorsPool: any[] = [];
    private countTime = 45;
    private score: number = 0;
    private GarbageConfig: any[] = GarbageConfig.config;
    private currTarget: Garbage;
    private currTargetBase: Garbage;
    private timer: any;
    private countDownCount: number = 45;

    constructor() {
        super();
        this.initUI();

    }

    initUI() {
        // 初始化引导
        this.initGuide();

        if (GameConst.isPlayMusic) {

            window['playMusic']("bgMusic", true);
            this['musicOn'].visible = true;
            this['musicOff'].visible = false;
        } else {
            window['playMusic']("bgMusic", false);
            this['musicOn'].visible = false;
            this['musicOff'].visible = true;
        }
    }


    // 引导倒计时 3 2 1 go!
    private guideCount() {
        this.num3.alpha = 1;
        let n3 = egret.Tween.get(this.num3);

        if (GameConst.isPlayMusic) {

            playSound("numCountDown");
        }

        n3.to({ scaleX: 0.8, scaleY: 0.8 }, 200).to({ scaleX: 1, scaleY: 1 }, 100).wait(500).to({ scaleX: 0, scaleY: 0 }, 200).call(() => {
            this.num2.alpha = 1;
            let n2 = egret.Tween.get(this.num2);
            if (GameConst.isPlayMusic) {

                playSound("numCountDown");
            }
            n2.to({ scaleX: 0.8, scaleY: 0.8 }, 200).to({ scaleX: 1, scaleY: 1 }, 100).wait(500).to({ scaleX: 0, scaleY: 0 }, 200).call(() => {
                this.num1.alpha = 1;
                let n1 = egret.Tween.get(this.num1);
                if (GameConst.isPlayMusic) {

                    playSound("numCountDown");
                }
                n1.to({ scaleX: 0.8, scaleY: 0.8 }, 200).to({ scaleX: 1, scaleY: 1 }, 100).wait(500).to({ scaleX: 0, scaleY: 0 }, 200).call(() => {
                    this.go.alpha = 1;
                    let go = egret.Tween.get(this.go);
                    if (GameConst.isPlayMusic) {
                        window["playMusic"]("go");
                    }
                    go.to({ scaleX: 0.8, scaleY: 0.8 }, 200).to({ scaleX: 1, scaleY: 1 }, 100).wait(500).call(() => {
                        this.countDownGroup.visible = false;
                        this.startCount();
                        // 初始化传送带
                        this.initConveyors();
                    })
                })
            })
        })
    }

    private startCount() {
        this.timer = new egret.Timer(1000, this.countDownCount);
        //注册事件侦听器
        this.timer.addEventListener(egret.TimerEvent.TIMER, this.timerUpdate, this);
        this.timer.addEventListener(egret.TimerEvent.TIMER_COMPLETE, this.timerComFunc, this);
        //开始计时
        this.timer.start();
    }

    // 更新时间显示
    private timerUpdate() {
        this.countDownCount--;
        this.countDownTxt.text = this.countDownCount + "S";
    }

    private timerComFunc() {
        this.countDownTxt.text = "0S";
        // 移除所有Tween
        egret.Tween.removeAllTweens();
        this.gameOver();
    }

    initGuide() {
        let guideTips = MovieClipCtrl.instance.getMovieClipByName("guideTips_0")
        this.guideGroup.addChild(guideTips)


        if (!GCache.readCache("isGuide")) {
            GCache.writeCache("isGuide", true)
            this.guideGroup.visible = true;
            guideTips.play(-1);
            this.guideEle.addEventListener(egret.TouchEvent.TOUCH_BEGIN, this.onBegin_guideEle, this);
        } else {
            this.onTap_guideGroup();
        }
    }

    private guideTarget: any;
    onBegin_guideEle(e) {
        e.$target.visible = false;
        this.currTargetBase = e.$target;
        let type = e.$target.type;
        let source = e.$target.source;
        let garbage = new Garbage(source);
        garbage.type = type;
        garbage.anchorOffsetX = 30;
        garbage.anchorOffsetY = 30;
        garbage.x = e.stageX;
        garbage.y = e.stageY;
        garbage.removeEventListener(egret.TouchEvent.TOUCH_BEGIN, this.onBegin_guideEle, this);
        this.addEventListener(egret.TouchEvent.TOUCH_MOVE, this.onMove_guideEle, this);
        this.addEventListener(egret.TouchEvent.TOUCH_CANCEL, this.onEnd_guideEle, this);
        this.addEventListener(egret.TouchEvent.TOUCH_END, this.onEnd_guideEle, this);
        this.addChild(garbage);
        this.guideTarget = garbage;
        MovieClipCtrl.instance.getMovieClipByName("guideTips_0").visible = false;
    }

    onMove_guideEle(e) {
        if (this.guideTarget) {
            this.guideTarget.x = e.stageX;
            this.guideTarget.y = e.stageY;
        }
    }

    onEnd_guideEle(e) {
        const condition: boolean = this.guideTarget ? GameConst.contain(this.recoverableWaste, this.guideTarget) : false;
        if (condition) {
            this.guideEle.removeEventListener(egret.TouchEvent.TOUCH_BEGIN, this.onBegin_guideEle, this);
            this.removeEventListener(egret.TouchEvent.TOUCH_MOVE, this.onMove_guideEle, this);
            this.removeEventListener(egret.TouchEvent.TOUCH_CANCEL, this.onEnd_guideEle, this);
            this.removeEventListener(egret.TouchEvent.TOUCH_END, this.onEnd_guideEle, this);
            if (this.guideTarget) {
                this.guideTarget.scaling = true
                egret.Tween.get(this.guideTarget)
                    .to({ scaleX: 0, scaleY: 0 }, 200)
                    .call(() => {
                        this.onTap_guideGroup();
                    })

            }

        } else {
            this.guideEle.scaleX = 0;
            this.guideEle.scaleY = 0;
            egret.Tween.get(this.guideEle)
                .to({ scaleX: 1, scaleY: 1 }, 200)
            this.guideEle.visible = true;
            if (this.guideTarget) {
                egret.Tween.get(this.guideTarget)
                    .to({ scaleX: 0, scaleY: 0 }, 200)
                    .call(() => {
                        this.removeChild(this.guideTarget);
                        this.guideTarget = null;
                    })
            }

            MovieClipCtrl.instance.getMovieClipByName("guideTips_0").visible = true;
            this.guideEle.addEventListener(egret.TouchEvent.TOUCH_BEGIN, this.onBegin_guideEle, this);
        }
    }


    // 本局游戏的20种垃圾
    private currConfigPool: any[] = [];
    private currGamePool: any[] = [];
    private gamePoolIdx: number = 0;
    initConveyors() {

        for (let i = 0; i < 7; i++) {
            let target = this[`idler${i}`]
            egret.Tween.get(target, { loop: true })
                .to({ rotation: -360 }, 1000)
        }

        this.currConfigPool = GameConst.arr.shuffle(this.GarbageConfig);
        for (let i = 0; i < 20; i++) {
            this.currConfigPool[i].idx = i;
            this.currConfigPool[i].isRight = false;
            this.currConfigPool[i].isMistake = false;
            this.currConfigPool[i].isOnStage = false;
            this.currGamePool.push(this.currConfigPool[i]);
        }
        this.log(this.currGamePool);

        this.conveyorsPool.push(this.conveyor0);
        this.conveyorsPool.push(this.conveyor1);
        for (let i = 0; i < 5; i++) {
            let g = this.currGamePool[this.gamePoolIdx];
            this.gamePoolIdx += 1;
            let garbage = new Garbage(g.source);
            g.isOnStage = true;
            garbage.type = g.type;
            garbage.name = g.name;
            garbage.anchorOffsetX = g.width / 2;
            garbage.anchorOffsetY = g.height;
            garbage.x = 0;
            garbage.y = 90;
            this.conveyor1[`idx${i}`].addChild(garbage)
            garbage.addEventListener(egret.TouchEvent.TOUCH_BEGIN, this.onBegin_garbage, this);
        }
    }


    private isGameOver = false;
    gameOver() {
        if (this.isGameOver) {
            return
        }
        if (GameConst.isPlayMusic) {
            window['playMusic']("gameOver")
        }
        this.isGameOver = true;
        Waiting.instance.show();
        let data = { score: this.score, anwserPool: this.currGamePool }
        SceneCtrl.instance.change(ModuleTypes.OVER_SCENE, data);

    }

    initEvents() {
        super.initEvents();
        this.addEventListener(egret.Event.ENTER_FRAME, this.onEnterFrame, this);

        this.onTap(this['musicOn'], this.onTap_musicOn);
        this.onTap(this['musicOff'], this.onTap_musicOff);

    }

    onTap_guideGroup() {
        this.guideGroup.visible = false;
        this.countDownGroup.visible = true;
        this.guideCount();
    }

    onTap_musicOn(e) {
        e.stopPropagation();
        GameConst.isPlayMusic = false;
        this['musicOn'].visible = !this['musicOn'].visible;
        this['musicOff'].visible = !this['musicOff'].visible;

        window["playMusic"]("bgMusic", false);
    }

    onTap_musicOff(e) {
        e.stopPropagation();
        GameConst.isPlayMusic = true;
        this['musicOn'].visible = !this['musicOn'].visible;
        this['musicOff'].visible = !this['musicOff'].visible;

        window["playMusic"]("bgMusic", true);
    }

    ////////////////////////////// 
    // idx //   //   //   //   //        
    /////////////////////////////
    onEnterFrame() {
        this['musicOn'].rotation += 0.5;

        if (this.score == 100) {
            this.gameOver();
        }

        this.conveyorsPool.forEach(conveyor => {
            conveyor.x -= window["speed"] || 3;
        });


        if (this.conveyorsPool.length > 1) {
            if (this.conveyorsPool[this.conveyorsPool.length - 1].x <= 764) {
                // 最后一个传送带完全进入屏幕时  往后添加一个传送带
                const conveyor = new eui.Component();
                conveyor.skinName = `ConveyorSkin`;
                conveyor.x = this.conveyorsPool[this.conveyorsPool.length - 1].x + 764;
                conveyor.y = 904.21;
                this.addChild(conveyor);
                this.conveyorsPool.push(conveyor);
            } else {
                //筛选出currGamePool里还未正确和添加在舞台上的
                let asdasd = []
                for (var n = 0; n < this.currGamePool.length; n++) {
                    let cgg = this.currGamePool[n];
                    if (!cgg.isRight && !cgg.isOnStage) {
                        asdasd.push(cgg);
                    }
                }
                //最后一个传送带
                let cc = this.conveyorsPool[this.conveyorsPool.length - 1]
                for (var m = 0; m < 5; m++) {
                    if (!cc[`idx${m}`].$children[0]) {
                        let g = asdasd.shift();
                        if (g) {
                            g.isOnStage = true;
                            let garbage = new Garbage(g.source);
                            garbage.type = g.type;
                            garbage.name = g.name;
                            garbage.anchorOffsetX = g.width / 2;
                            garbage.anchorOffsetY = g.height;
                            garbage.x = 0;
                            garbage.y = 90;
                            cc[`idx${m}`].addChild(garbage);
                            garbage.addEventListener(egret.TouchEvent.TOUCH_BEGIN, this.onBegin_garbage, this);

                        } else {
                            break
                        }
                    }
                }
            }

            // 从场景移除
            if (this.conveyorsPool[0].x < -750) {
                for (var k = 0; k < this.currGamePool.length; k++) {
                    let garbage = this.currGamePool[k]
                    let cc = this.conveyorsPool[0][`idx${4}`]
                    if (cc.$children[0]) {
                        if (garbage.name == cc.$children[0].$name) {
                            garbage.isOnStage = false;
                            GameConst.arr.removeEle(garbage, this.currGamePool);
                            this.currGamePool.push(garbage);
                            cc.removeChild(cc.$children[0])
                            break
                        }
                    }

                }
                this.conveyorsPool.shift();
            }
            else if (this.conveyorsPool[0].x < -600) {
                for (var k = 0; k < this.currGamePool.length; k++) {
                    let garbage = this.currGamePool[k]
                    let cc = this.conveyorsPool[0][`idx${3}`]
                    if (cc.$children[0]) {
                        if (garbage.name == cc.$children[0].$name) {
                            garbage.isOnStage = false;
                            GameConst.arr.removeEle(garbage, this.currGamePool);
                            this.currGamePool.push(garbage);
                            cc.removeChild(cc.$children[0])
                            break
                        }
                    }

                }
            }
            else if (this.conveyorsPool[0].x < -450) {
                for (var k = 0; k < this.currGamePool.length; k++) {
                    let garbage = this.currGamePool[k]
                    let cc = this.conveyorsPool[0][`idx${2}`]
                    if (cc.$children[0]) {
                        if (garbage.name == cc.$children[0].$name) {
                            garbage.isOnStage = false;
                            GameConst.arr.removeEle(garbage, this.currGamePool);
                            this.currGamePool.push(garbage);
                            cc.removeChild(cc.$children[0])
                            break
                        }
                    }

                }
            }
            else if (this.conveyorsPool[0].x < -300) {
                for (var k = 0; k < this.currGamePool.length; k++) {
                    let garbage = this.currGamePool[k]
                    let cc = this.conveyorsPool[0][`idx${1}`]
                    if (cc.$children[0]) {
                        if (garbage.name == cc.$children[0].$name) {
                            garbage.isOnStage = false;
                            GameConst.arr.removeEle(garbage, this.currGamePool);
                            this.currGamePool.push(garbage);
                            cc.removeChild(cc.$children[0])
                            break
                        }
                    }

                }
            }
            else if (this.conveyorsPool[0].x < -150) {
                for (var k = 0; k < this.currGamePool.length; k++) {
                    let garbage = this.currGamePool[k]
                    let cc = this.conveyorsPool[0][`idx${0}`]
                    if (cc.$children[0]) {
                        if (garbage.name == cc.$children[0].$name) {
                            garbage.isOnStage = false;
                            GameConst.arr.removeEle(garbage, this.currGamePool);
                            this.currGamePool.push(garbage);
                            cc.removeChild(cc.$children[0])
                            break
                        }
                    }

                }
            }

        }
    }


    onBegin_garbage(e) {
        e.$target.visible = false;
        this.currTargetBase = e.$target;
        let type = e.$target.type;
        let source = e.$target.source;
        let garbage = new Garbage(source);
        garbage.type = type;
        garbage.anchorOffsetX = 30;
        garbage.anchorOffsetY = 30;
        garbage.x = e.stageX;
        garbage.y = e.stageY;
        garbage.removeEventListener(egret.TouchEvent.TOUCH_BEGIN, this.onBegin_garbage, this);
        this.addEventListener(egret.TouchEvent.TOUCH_MOVE, this.onMove_garbage, this);
        this.addEventListener(egret.TouchEvent.TOUCH_CANCEL, this.onEnd_garbage, this);
        this.addEventListener(egret.TouchEvent.TOUCH_END, this.onEnd_garbage, this);
        this.addChild(garbage);
        this.currTarget = garbage;
    }

    onMove_garbage(e) {
        if (this.currTarget) {
            this.currTarget.x = e.stageX;
            this.currTarget.y = e.stageY;
        }
    }

    onEnd_garbage() {
        if (this.currTarget) {
            this.removeEventListener(egret.TouchEvent.TOUCH_MOVE, this.onMove_garbage, this);
            this.removeEventListener(egret.TouchEvent.TOUCH_CANCEL, this.onEnd_garbage, this);
            this.removeEventListener(egret.TouchEvent.TOUCH_END, this.onEnd_garbage, this);
            // 判断是否投放
            const virtualTarget = { x: this.currTarget.x, y: this.currTarget.y, width: 80, height: 80 }
            const condition0: boolean = GameConst.contain(this.harmfulWaste, virtualTarget);
            const condition1: boolean = GameConst.contain(this.dryWaste, virtualTarget);
            const condition2: boolean = GameConst.contain(this.wetWaste, virtualTarget);
            const condition3: boolean = GameConst.contain(this.recoverableWaste, virtualTarget);
            if (condition0 || condition1 || condition2 || condition3) {
                if (condition0) {
                    // 投进了有害垃圾桶
                    if (this.currTarget.type == GarbageTypes.harmfulWaste) {
                        this.log("正确")
                        this.showRightTips(315, 300);
                        this.anwserRight();
                    } else {
                        this.log("错误")
                        this.showWrongTips(315, 300);
                        this.anwserWrong();
                    }
                } else if (condition1) {
                    // 投进了干垃圾桶
                    if (this.currTarget.type == GarbageTypes.dryWaste) {
                        // 正确
                        this.log("正确")
                        this.showRightTips(600, 300);
                        this.anwserRight();
                    } else {
                        // 错误
                        this.log("错误")
                        this.showWrongTips(600, 300);
                        this.anwserWrong();
                    }
                } else if (condition2) {
                    // 投进了湿垃圾桶
                    if (this.currTarget.type == GarbageTypes.wetWaste) {
                        // 正确
                        this.log("正确")
                        this.showRightTips(315, 575);
                        this.anwserRight();
                    } else {
                        // 错误
                        this.log("错误")
                        this.showWrongTips(315, 575);
                        this.anwserWrong();
                    }
                } else if (condition3) {
                    // 投进了可回收垃圾桶
                    if (this.currTarget.type == GarbageTypes.recoverableWaste) {
                        // 正确
                        this.log("正确")
                        this.showRightTips(600, 575);
                        this.anwserRight();
                    } else {
                        // 错误
                        this.log("错误")
                        this.showWrongTips(600, 575);
                        this.anwserWrong();
                    }
                }
                egret.Tween.get(this.currTarget)
                    .to({ scaleX: 0, scaleY: 0 }, 200)
                    .call(() => {
                        this.removeChild(this.currTarget);
                        this.currTarget = null;
                    })
            } else {
                if(this.currTargetBase.parent){
                    this.currTargetBase.parent.scaleX = 0;
                    this.currTargetBase.parent.scaleY = 0;
                    egret.Tween.get(this.currTargetBase.parent)
                        .to({ scaleX: 1, scaleY: 1 }, 200)
                }
                
                this.currTargetBase.visible = true;
                egret.Tween.get(this.currTarget)
                    .to({ scaleX: 0, scaleY: 0 }, 200)
                    .call(() => {
                        this.removeChild(this.currTarget);
                        this.currTarget = null;
                    })
            }

        }
    }

    anwserRight() {
        this.score += 5;
        this.scoreTxt.text = "" + this.score;

        for (var i = 0; i < this.currGamePool.length; i++) {
            let garbage = this.currGamePool[i];

            if (garbage.name == this.currTargetBase.name) {
                garbage.isRight = true;
            }
        }

        if (GameConst.isPlayMusic) {
            playSound("rightTips")
        }
    }

    anwserWrong() {
        if(this.currTargetBase.parent){
            this.currTargetBase.parent.scaleX = 0;
            this.currTargetBase.parent.scaleY = 0;
            egret.Tween.get(this.currTargetBase.parent)
                .to({ scaleX: 1, scaleY: 1 }, 200)
        }
        this.currTargetBase.visible = true;

        this.currGamePool.forEach(garbage => {
            if (garbage.name == this.currTargetBase.name) {
                garbage.isMistake = true;
                return
            }
        })

        if (GameConst.isPlayMusic) {
            window["playMusic"]("wrongTips");
        }
    }

    showWrongTips(x, y) {
        let wrongTips = new eui.Image();
        wrongTips.source = `wrongTips_png`;
        wrongTips.x = x;
        wrongTips.y = y;
        wrongTips.scaleX = 0;
        wrongTips.scaleY = 0;
        wrongTips.anchorOffsetX = 88 / 2;
        wrongTips.anchorOffsetY = 85 / 2;
        this.addChild(wrongTips);
        //缩放：0s(0%,0%)-0.1s(120%,120%)-0.17s(100%,100%);  位置：0.17s(原位) - 0.23s(左移20px) - 0.3s(原位) - 0.37s(左移20px) - 0.43(原位) ；透明度：0.6s(100 %) - 0.7s(0 %);
        egret.Tween.get(wrongTips)
            .to({ scaleX: 1.2, scaleY: 1.2 }, 100)
            .to({ scaleX: 1, scaleY: 1 }, 70)
            .to({ x: x - 20 }, 60)
            .to({ x: x }, 70)
            .to({ x: x + 20 }, 70)
            .to({ x: x }, 60)
            .wait(270)
            .to({ alpha: 0 }, 100)
            .call(() => {
                this.removeChild(wrongTips)
            })
    }

    showRightTips(x, y) {
        let RightTips = new eui.Image();
        RightTips.source = `rightTips_png`;
        RightTips.x = x;
        RightTips.y = y;
        RightTips.scaleX = 0;
        RightTips.scaleY = 0;
        RightTips.anchorOffsetX = 92 / 2;
        RightTips.anchorOffsetY = 88 / 2;
        this.addChild(RightTips);
        //缩放：0s(0%,0%)-0.1s(120%,120%)-0.17s(100%,100%); 透明度：0.5s(100 %) - 0.6s(0 %);
        egret.Tween.get(RightTips)
            .to({ scaleX: 1.2, scaleY: 1.2 }, 100)
            .to({ scaleX: 1, scaleY: 1 }, 70)
            .wait(330)
            .to({ alpha: 0 }, 100)
            .call(() => {
                this.removeChild(RightTips)
            })

        let addScore = new eui.Image();
        addScore.source = `addScore_png`;
        addScore.x = x + 100;
        addScore.y = y;
        addScore.alpha = 0;
        addScore.anchorOffsetX = 58 / 2;
        addScore.anchorOffsetY = 40 / 2;
        this.addChild(addScore);
        //位置：0s(原位)-0.5s(上移80px)；透明度：0s(0 %) - 0.1s(100 %) - 0.4s(100 %) - 0.5s(0 %);
        egret.Tween.get(addScore)
            .to({ y: y - 80 }, 550)
            .call(() => {
                this.removeChild(addScore)
            })
        egret.Tween.get(addScore)
            .to({ alpha: 1 }, 100)
            .wait(300)
            .to({ alpha: 0 }, 100)
    }

    removeEvents() {
        super.removeEvents();

        this.clearTap(this['musicOn'], this.onTap_musicOn);
        this.clearTap(this['musicOn'], this.onTap_musicOff);

        this.removeEventListener(egret.Event.ENTER_FRAME, this.onEnterFrame, this);
    }

}