var gameConfig = require("../GameConfig.js");
var playerConfig = require("./PlayerConfig");
var webView = require("../../WebView");
var globalConfig = require("../../Global");
var lib = require("../../Library");
var EquipmentAction = require("../../EquipmentAction");
var server = require("../../MiniGameServer");

cc.Class({
    extends: require("BasePlayerController"),
    properties: {
        mainCamera: {
            default: null,
            type: cc.Node,
            serializable: true,
        },
        mapArr: {
            default: [],
            type: [cc.Node], // type 同样写成数组，提高代码可读性
        },
        locationLine: {
            default: null,
            type: cc.Node,
            serializable: true,
        },
        staggerAudio: {
            default: null,
            type: cc.AudioClip,
        },
        resultBar: {
            default: null,
            type: cc.Node,
            serializable: true,
        },
        cheerAudio: {
            default: null,
            type: cc.AudioClip,
        },
        rival: {
            default: null,
            type: cc.Node,
            serializable: true,
        },
        //设备数据判断对象
        equipmentObj: null,
    },
    init() {//override
        this._super();
        this.locationLine.zIndex = 2;
        this.resultBarSt = this.resultBar.getComponent('ResultBar');
        this.playerConfig = playerConfig;
    },
    start()//override
    {
        this._super();
 
        if (lib.openInWebview()) {
            // 在app内Webview打开
            webView.register(this.node);
            this.node.on('onDeviceUpdateData', this.onDeviceUpdateData, this);

            //监听回调
            uni.postMessage({
                data: {
                    funName: "addDeviceUpdateListener",
                    gameData: {}
                }
            })
            //开启设备回调
            uni.postMessage({
                data: {
                    funName: "writeBLEConnectionValue",
                    gameData: {
                        value: "3" //开启设备数据
                    }
                }
            })

            //开启设备频率
            uni.postMessage({
                data: {
                    funName: "writeBLEConnectionValue",
                    gameData: {
                        value: "b" //60ms
                    }
                }
            })

            this.equipmentObj = new EquipmentAction();
            this.equipmentObj.addEventListener("resultant", (res) => {
                let data = res;
                // console.log("resultant:",data);
                if(data.type == "jump"){
                    if (!globalConfig.bAi) {
                        this.jump_lockStep();
                    }
                    else{
                        this.jump();
                    }
                    // this.jump();
                }else if(data.type == "runing"){
                    if (!globalConfig.bAi) {
                        this.speedUp_lockStep();
                    }
                    else{
                        this.jump();
                    }
                    // this.speedUp();
                }

            })
        }
    },
    update(dt) {//override
        this._super();
        //make ui and camera follow the player
        this.gmSt.ui.x = this.node.x;
        this.mainCamera.x = this.node.x;

        if (this.pStatesSt.currentProState == this.pStatesSt.pProStates.end) return;

        //indicator
        if (this.node.x - this.rival.x > 360)//forward show left bar
        {
            this.ctorSt.showIndicater(1, Math.abs(Math.round(this.node.x - this.rival.x - 38)));
        }
        else if (this.node.x - this.rival.x < -360)//backward  show right bar
        {
            this.ctorSt.showIndicater(0, Math.abs(Math.round(this.node.x - this.rival.x + 38)));
        }
        else {
            this.ctorSt.hideIndicater();
        }
        //生成主角前方地图
        this.switchMap();
    },
    switchMap() {
        if (this.node.x > this.pStatesSt.targetPoint) {
            this.mapArr[0].x += 2160;
            lib.swapLeft(this.mapArr);
            this.pStatesSt.targetPoint += 720;
        }
    },
    setEndSpeed() {//overwrite
        this.pStatesSt.intoTheEndSpeed = this.pStatesSt.currentSpeed / (this.gmSt.terminal.x - this.pStatesSt.endLineStopPoint);
    },
    passedHandrail()//overwrite
    {
        let handrail = this.pStatesSt.nextHandrail.getChildByName('Kuolan1');
        let spine = handrail.getComponent(sp.Skeleton);
        spine.setAnimation(0, 'Idl1_3', false);
        this.ctorSt.stagger(function () {
            this.pStatesSt.Combo = 0;
            this.createAndDestroyHandrail();
        }.bind(this));
        cc.audioEngine.playEffect(this.staggerAudio, 0, function () { });
    },
    createAndDestroyHandrail() {
        while (true) {
            let hurdrailPX = this.gmSt.createHandrail();
            if (hurdrailPX - this.node.x > 360 || hurdrailPX == -1) {
                break;
            }
        }
       
        //GC drawedhandrail 如果出了玩家1的视野再回收
        if (this.node.x - this.gStatesSt.drawedhandrailArr[0].x > 720) 
        {
            let deleteHandrail = this.gStatesSt.drawedhandrailArr.shift();
            this.gStatesSt.handrailGCArr.push(deleteHandrail);
        }
        //set next jump handrail设置下一个要跨越的跨栏
        if (this.gStatesSt.drawedhandrailArr.length != 0) {
            
            let nextHandrailIndex = -1;
            for(let i = 0;i<this.gStatesSt.drawedhandrailArr.length;i++)
            {
                //一开始nextHandrail是当前跨栏，当数组里找到当前跨栏后，它下一位的跨栏就是下一个跨栏
                //for now nextHandrail is current handrail, so if find current handrail in array means next index is next handrial
                if(this.pStatesSt.nextHandrail == this.gStatesSt.drawedhandrailArr[i].handrail)
                {
                    nextHandrailIndex = i;
                    break;
                }
            }
            //最后一跨栏就不设置了
            //if current handrail is last handrail do not set next handrail
            if(nextHandrailIndex!=-1 && this.gStatesSt.drawedhandrailArr.length >1)
            {
                this.pStatesSt.nextHandrail = this.gStatesSt.drawedhandrailArr[nextHandrailIndex+1].handrail;
            }
        }
        //destroy hurdrail
        let len = this.gStatesSt.handrailGCArr.length;
        for (let i = 0; i < len; i++) {
            if (this.node.x - this.gStatesSt.handrailGCArr[i].x > 720) {
                let handrail = this.gStatesSt.handrailGCArr[i];
                delete this.gStatesSt.handrailGCArr[i];
                handrail.destroy();
            }
        }
        // because delete array will left undefined element so we need to remove it from array
        for (let i = 0; i < len; i++) {
            if (this.gStatesSt.handrailGCArr[i] == undefined) {
                this.gStatesSt.handrailGCArr.splice(i);
            }
        }
    },
    enterEndline() {//override
        this._super();

        if (this.gStatesSt.arrEndPArr.length == 1) {
            this.scheduleOnce(function () {
                this.setResuletBar();
            }, 3);

            this.firework();
        }
        else {
            this.schedule(function () {
                this.resultBar.active = true;
                this.resultBar.getChildByName('Win').active = false;
                this.resultBar.getChildByName('Fail').active = true;

                this.setResuletBar();
            }, 1, 0, 0);
        }
    },
    setResuletBar() {
        this.resultBarSt.init();
        this.gmSt.unschedule(this.gmSt.countGameTime);
        this.resultBarSt.updateCostTime(this.gStatesSt.gameTime);

        this.resultBarSt.updateAvatar();
        //cal calorie
        let runUnit = 0;
        let jumpUnit = 0;
        let calorie = 0;

        if( globalConfig.calorieParams != null)
        {
            runUnit = globalConfig.calorieParams.hitUnit;
            jumpUnit = globalConfig.calorieParams.hitUnit;

            calorie = parseInt(this.pStatesSt.runTimes * runUnit + this.pStatesSt.jumpTimes * jumpUnit);
        }
        this.resultBarSt.updateCalorie(calorie);
        if (lib.openInWebview()) {
            webView.postMessage(100, this.gmSt.countGameTime, calorie);
        }
    },
    firework() {
        cc.audioEngine.playEffect(this.cheerAudio, 0, function () { });
        let firework = this.gmSt.terminal.getChildByName("Firework");
        firework.active = true;
        firework.zIndex = 1005;
    },
    speedUp_lockStep(){
        server.sendOrder(globalConfig.openid,'speedUp',this.node.x.toString(),globalConfig.roomId);
    },
    jump_lockStep()
    {
        server.sendOrder(globalConfig.openid,'jump',this.node.x.toString(),globalConfig.roomId);
    },
    jump() {//overwrite
        //super class return is not effect to sub class so we need to write if return every subclass
        // if (this.gStatesSt.drawedhandrailArr.length == 0) return;
        if (this.pStatesSt.currentState == this.pStatesSt.playerAnimState.jump) return;
        //init locationLine do once
        this.locationLine.opacity = 0;
        this.locationLine.x = this.node.x;

        //No perfect jump area
        if (this.locationLine.x > this.pStatesSt.nextHandrail.x &&
            this.locationLine.x < this.pStatesSt.nextHandrail.x + gameConfig.handrailArea1.end) {
            this.locationLine.opacity = 255;
            this.pStatesSt.currentState = this.pStatesSt.playerAnimState.jump;
            
            this.ctorSt.jump('hurdling_1', function () {
                this.pStatesSt.currentState = this.pStatesSt.playerAnimState.run;
                this.createAndDestroyHandrail();
                this.pStatesSt.passedHurdrailNum++;
                this.pStatesSt.jumpTimes++;
                this.run();
            }.bind(this),1);
            return;
        }
        //perfect jump area
        if (this.locationLine.x > this.pStatesSt.nextHandrail.x + gameConfig.handrailArea2.start &&
            this.locationLine.x < this.pStatesSt.nextHandrail.x + gameConfig.handrailArea2.end) {
            this.pStatesSt.nextHandrail.getChildByName('AccelerationBandCenter').destroy();
            this.locationLine.opacity = 255;
            this.pStatesSt.currentState = this.pStatesSt.playerAnimState.jump;
            this.ctorSt.jump('hurdling_1', function () {
                this.pStatesSt.currentState = this.pStatesSt.playerAnimState.run;
                this.createAndDestroyHandrail();
                this.pStatesSt.passedHurdrailNum++;
                this.pStatesSt.jumpTimes++;
                this.run();
                
            }.bind(this),1);

            return;
        }
    },
    //interact with device
    onDeviceUpdateData(data) {

        // console.log(data);
        //判断数据类型
        if (data.dataType == "Box") {
            // webView.onBLEBoxUpdate(data);
            let gameData = data.data;
            this.equipmentObj.updateJumpAndRun({
                acc: gameData.acc,
                gyro: gameData.gyro,
                bLimitRebound: false
            })
        }
    },
});
// mgobe