var KBEngine = require("kbengine");

cc.Class({
    extends: cc.Component,

    properties: {
        //控制的玩家
        player: null,
        //另一个玩家的复制体
        otherPlayer:null,
        entities: null,
        mapNode: null,
        mapName: "",
        relivePanel: null,
        reloginCount: 0,

        // 是否移动摄像机
        isMoveCamera: false,
        camera: cc.Node,
    },
    // LIFE-CYCLE CALLBACKS:
    onLoad() {
        this.entities = {};
        // 创建一个地图节点
        this.mapNode = new cc.Node();
        this.mapNode.parent = cc.find("Canvas");
        this.camera = cc.find("Canvas/Main Camera");
    },

    start() {
        // 初始化UI
        this.initUI();
        // 安装这个场景需要监听的KBE事件
        this.installEvents();
        // 监听鼠标触摸等输入输出事件
        this.installInputEvents(this);
        // 角色进入场景后相当于开始游戏
        // 选择这个角色进入游戏
        // if (KBEngine.app)
            //  KBEngine.app.player().selectAvatarGame(KBEngine.app.player().avatars.values[0].dbid);
        if (KBEngine.app)
            KBEngine.app.player().enterGame();
    },

    /* -----------------------------------------------------------------------/
    							UI 相关
    /------------------------------------------------------------------------ */
    initUI: function () {
        // ask the window size
        var size = cc.winSize;
        // debug
        new GUIDebugLayer();
    },

    /* -----------------------------------------------------------------------/
    							输入输出事件 相关
    /------------------------------------------------------------------------ */
    installInputEvents: function (target) {
        // 添加单点触摸事件监听器
        this.camera.on('touchstart', this.onTouchBegan, this);
        this.camera.on('touchmove', this.onTouchMoved, this);
    },
    onTouchMoved: function (touch, event) {
    },
    onTouchBegan: function (touch, event) {
        // var pos = touch.getLocation(), target = touch.getCurrentTarget();
        // var locationInNode = target.convertToNodeSpace(pos);
        // var s = target.getContentSize();
        // var rect = cc.rect(0, 0, s.width, s.height);
        // // 检查是否在区域内
        //  if (rect.contains(locationInNode)) 
        // {
        //     return true;
        // }
        // return false;

        //如果游戏结束。
       if(GLOBAL_DATA.GAME.gameOver) return;
        //生成
        this.onSpawnBlackLine();
    },

    /* -----------------------------------------------------------------------/
    							KBEngine 事件响应
    /------------------------------------------------------------------------ */
    installEvents: function () {
        // common
        KBEngine.Event.register("onKicked", this, "onKicked");
        KBEngine.Event.register("onDisconnected", this, "onDisconnected");
        KBEngine.Event.register("onConnectionState", this, "onConnectionState");
        KBEngine.Event.register("onReloginBaseappFailed", this, "onReloginBaseappFailed");
        KBEngine.Event.register("onReloginBaseappSuccessfully", this, "onReloginBaseappSuccessfully");
        // in world
        KBEngine.Event.register("addSpaceGeometryMapping", this, "addSpaceGeometryMapping");
        KBEngine.Event.register("onEnterWorld", this, "onEnterWorld");
        KBEngine.Event.register("onLeaveWorld", this, "onLeaveWorld");
        KBEngine.Event.register("updatePosition", this, "updatePosition");
        // in world(register by scripts)
        KBEngine.Event.register("onAvatarEnterWorld", this, "onAvatarEnterWorld");
        KBEngine.Event.register("onNewTurn", this, "_newTurn");
        KBEngine.Event.register("onSetAvatarMove", this, "set_avatarMove");
        KBEngine.Event.register("onSetAvatarState", this, "set_avatarState");
        KBEngine.Event.register("onSetAvatarSpeed", this, "set_Speed");
        KBEngine.Event.register("onReady", this, "_GameReady");
        KBEngine.Event.register("onGameOver", this, "_GameOver");

        
        KBEngine.Event.register("onServerMoveOver", this, "onServerMoveOver");
        KBEngine.Event.register("otherAvatarOnJump", this, "otherAvatarOnJump");

    },

    _GameReady: function (eid, second) {
        console.log('启动倒计时', second);
    },

    _newTurn: function (eid, second, speed, pos) {
        console.log('一轮游戏开始:', speed, pos);
        // 设置初始游戏数据
        this.player.setAvatarSpeed(speed);
        GLOBAL_DATA.GAME.setGlobalGameRun(true);
    },
    //设置速度
    set_Speed: function (eid, speed) {
        var ae = this.entities[eid];
        // console.log(ae);
        if (ae == undefined)
            return;

        //设置人物速度
        ae.setAvatarSpeed(speed);
    },
    //avatar 移动。
    set_avatarMove: function (isMove, pos) {
        // console.log(pos);
        if (this.player != null)
            this.player.moveToPosition(new cc.Vec2(pos.x * CONVERSION_DISTANCE_UNIT, pos.z * CONVERSION_DISTANCE_UNIT));
    },
    //设置avatar动画状态
    set_avatarState: function (eid, avatarType) {
        var ae = this.entities[eid];
        if (ae == undefined)
            return;
        switch (avatarType) {
            case 0:
                ae.idle();
                break;

            case 1:
                ae.run();
                break;
        }

    },

    onServerMoveOver: function (self) {
        console.log('set isEndAction');
        if (!this.player) return;
        // 游戏结束停止位置
        this.player.isEndAction = true;
    },

    _GameOver: function (win, score) {

        GLOBAL_DATA.GAME.gameOver = true;
        
        //结束时候设置两个人物当前状态
        this.player.idle();
        this.otherPlayer.idle();

        //设置游戏当前全局速度
        GLOBAL_DATA.GAME.setGlobalSpeed(0);
        //设置人物速度
        this.player.setAvatarSpeed(0);
        GLOBAL_DATA.GAME.setGlobalGameRun(false);

    },

    onSpawnBlackLine() {
        let prefabUrl = "prefabs/BlackLine";
        let self = this;
        cc.loader.loadRes(prefabUrl, function (errorMessage, loadedResource) {
            //检查资源加载
            if (errorMessage) { cc.log('载入预制资源失败, 原因:' + errorMessage); return; }
            if (!(loadedResource instanceof cc.Prefab)) { cc.log('你载入的不是预制资源!'); return; }
            //开始实例化预制资源
            var blackline = cc.instantiate(loadedResource);
            blackline.x = self.camera.position.x;
            blackline.getChildByName('LineCollider').getComponent('LineCollider').onSetWorldSceneObj(self);
            //将预制资源添加到父节点
            self.mapNode.addChild(blackline, G_Z_INDEX.blackline);
        });
    },
    //碰撞时候调用，通知服务器要增加速度
    onChangeSpeed(speed) {
        if (this.player != null) {
            //拿到人物当前的速度
            let speedTemp = this.player.speed;
            speedTemp += speed;
            //通知服务器当前增加的速度
            KBEngine.app.player().changeSpeed(speedTemp);
        }
    },
    onKicked: function (failedcode) {
    },

    onDisconnected: function () {
        GUIDebugLayer.debug.ERROR_MSG("disconnect! will try to reconnect...");
        this.reloginCount = 0;

        this.scheduleOnce(function timerfn() {
            this.onReloginBaseappTimer(this);
        }, 1);
    },

    onReloginBaseappTimer: function (self) {
        if (KBEngine.app.socket != undefined && KBEngine.app.socket != null) {
            return;
        }
        if (this.reloginCount >= 3) {
            // 切换起始到场景
            cc.director.loadScene("startScene", () => {
                console.log('进入游戏场景');
            });
            return;
        }
        this.reloginCount += 1;
        GUIDebugLayer.debug.ERROR_MSG("will try to reconnect(" + this.reloginCount + ")...");
        KBEngine.app.reloginBaseapp();
        this.scheduleOnce(function timerfn() {
            self.onReloginBaseappTimer(self);
        }, 1);
    },

    onReloginBaseappFailed: function (failedcode) {
        GUIDebugLayer.debug.ERROR_MSG("reogin is failed(断线重连失败), err=" + KBEngine.app.serverErr(failedcode));
    },

    onReloginBaseappSuccessfully: function () {
        GUIDebugLayer.debug.INFO_MSG("reogin is successfully!(断线重连成功!)");
    },

    onConnectionState: function (success) {
        if (!success)
            GUIDebugLayer.debug.ERROR_MSG("Connect(" + KBEngine.app.ip + ":" + KBEngine.app.port + ") is error! (连接错误)");
        else
            GUIDebugLayer.debug.INFO_MSG("Connect successfully, please wait...(连接成功，请等候...)");

        // 切换起始到场景
        cc.director.loadScene("startScene", () => {
            console.log('进入游戏场景');
        });
    },

    addSpaceGeometryMapping: function (resPath) {
        // 服务器space创建了几何映射（可以理解为添加了场景的具体资源信息，客户端可以使用这个信息来加载对应的场景表现）
        this.mapName = resPath;
        // 其实可以将resPath与地图tmx文件名设置为一致，那么就可以根据服务器返回的信息来加载场景
        // resPath由服务端cell/space.py中KBEngine.addSpaceGeometryMapping(self.spaceID, None, resPath)设置
        console.log('addSpaceGeometryMapping resPath:', resPath);
    },

    onAvatarEnterWorld: function (rndUUID, eid, avatar) {
        console.log('角色进入世界，创建角色精灵:', rndUUID, eid, avatar);
        // 角色进入世界，创建角色精灵
        let prefabUrl = "prefabs/player";
        let self = this;
        cc.loader.loadRes(prefabUrl, function (errorMessage, loadedResource) {
            //检查资源加载
            if (errorMessage) { cc.log('载入预制资源失败, 原因:' + errorMessage); return; }
            if (!(loadedResource instanceof cc.Prefab)) { cc.log('你载入的不是预制资源!'); return; }
            //开始实例化预制资源
            var playerPrefab = cc.instantiate(loadedResource);
            let startPos = new cc.Vec2(avatar.position.x * CONVERSION_DISTANCE_UNIT, avatar.position.z * CONVERSION_DISTANCE_UNIT);
            //设置人物的初始位置
            playerPrefab.setPosition(startPos);
            //设置相机的初始位置
            self.camera.setPosition(startPos);
            //将预制资源添加到父节点
            self.mapNode.addChild(playerPrefab, G_Z_INDEX.player);
            //获取预制资源中的js组件，并作出相应操作
            self.player = playerPrefab.getComponent('worldAvatar');
            self.player.entityID = eid;
            self.player.isControlled = true;
            //设置皮肤
            self.player.setSkinFromIndex(avatar.modelID);
            self.entities[avatar.id] = self.player;
        });

    },

    onEnterWorld: function (entity) {
        // item 实体进入客户端世界，我们需要创建一个精灵来描述整个实体的表现
        if (!entity.isPlayer()) {
            console.log('进入游戏世界，生成其他东西：onEnterWorld:', entity);
            let self = this;
            if (entity.className == "Avatar") {
                // 对手角色进入世界，创建对手
                let prefabUrl = "prefabs/player";
                let self = this;
                cc.loader.loadRes(prefabUrl, function (errorMessage, loadedResource) {
                    //检查资源加载
                    if (errorMessage) { cc.log('载入预制资源失败, 原因:' + errorMessage); return; }
                    if (!(loadedResource instanceof cc.Prefab)) { cc.log('你载入的不是预制资源!'); return; }
                    //开始实例化预制资源
                    var playerPrefab = cc.instantiate(loadedResource);
                    //  entity.position.z * CONVERSION_DISTANCE_UNIT
                    //  副本需要加上一个偏移值。x = 34
                    let startPos = new cc.Vec2(entity.position.x * CONVERSION_DISTANCE_UNIT + 34, 0);
                    //设置人物的初始位置
                    playerPrefab.setPosition(startPos);
                    //将预制资源添加到父节点
                    self.mapNode.addChild(playerPrefab, G_Z_INDEX.player - 1);
                    //获取预制资源中的js组件，并作出相应操作
                    self.otherPlayer = playerPrefab.getComponent('worldAvatar');
                    self.otherPlayer.entityID = entity.id;
                    self.otherPlayer.isControlled = false;
                    self.otherPlayer.setAvatarSpeed(entity.startSpeed * CONVERSION_SPEED_UNIT);
                    //设置皮肤
                    self.otherPlayer.setSkinFromIndex(entity.modelID);
                    self.entities[entity.id] =  self.otherPlayer;
                });
            } else {
                switch (entity.zoneType) {
                    case "min":
                        cc.loader.loadRes("prefabs/acceleraMin", function (errorMessage, loadedResource) {
                            //检查资源加载
                            if (errorMessage) { cc.log('载入预制资源失败, 原因:' + errorMessage); return; }
                            if (!(loadedResource instanceof cc.Prefab)) { cc.log('你载入的不是预制资源!'); return; }
                            //开始实例化预制资源
                            var acceleraPrefab = cc.instantiate(loadedResource);
                            acceleraPrefab.setPosition(entity.position.x * CONVERSION_DISTANCE_UNIT, 0);

                            // console.log('this.acceleraMin:',self.mapNode);
                            //将预制资源添加到父节点
                            self.mapNode.addChild(acceleraPrefab, G_Z_INDEX.accelera);

                            //获取预制资源中的js组件，并作出相应操作
                            let ae = acceleraPrefab.getComponent('worldEntity');
                            // console.log("ae::",ae);
                            self.entities[entity.id] = ae;
                        });
                        break;
                    case "line":
                        cc.loader.loadRes("prefabs/whiteLine", function (errorMessage, loadedResource) {
                            //检查资源加载
                            if (errorMessage) { cc.log('载入预制资源失败, 原因:' + errorMessage); return; }
                            if (!(loadedResource instanceof cc.Prefab)) { cc.log('你载入的不是预制资源!'); return; }
                            //开始实例化预制资源
                            var linePrefab = cc.instantiate(loadedResource);
                            linePrefab.setPosition(entity.position.x * CONVERSION_DISTANCE_UNIT, 0);

                            // console.log('this.acceleraMin:',self.mapNode);
                            //将预制资源添加到父节点
                            self.mapNode.addChild(linePrefab, G_Z_INDEX.line);

                            //获取预制资源中的js组件，并作出相应操作
                            let ae = linePrefab.getComponent('worldEntity');
                            // console.log("ae::",ae);
                            self.entities[entity.id] = ae;
                        });
                        break;
                }
            }

        }
    },

    onLeaveWorld: function (entity) {
        // 实体离开了客户端世界，通常是因为离开了玩家的AOI
        console.log('onLeaveWorld:', entity.id);
        // this.mapNode.removeChild(this.entities[entity.id]);
        // delete this.entities[entity.id];
        // if (entity.isPlayer())
        //     this.player = null;
    },

    updatePosition: function (entity) {
        // 服务器同步到实体的新位置，我们需要将实体平滑移动到指定坐标点
        var ae = this.entities[entity.id];
        if (ae == undefined)
            return;
        //entity.position.z * CONVERSION_DISTANCE_UNIT
        // ae.node.setPosition(entity.position.x*CONVERSION_DISTANCE_UNIT, 0);
        ae.moveToPosition(new cc.Vec2(entity.position.x * CONVERSION_DISTANCE_UNIT + 34, 0));
    },

    otherAvatarOnJump: function (entity) {
        var ae = this.entities[entity.id];
        if (ae == undefined)
            return;
    },

    /* -----------------------------------------------------------------------/
    							其他系统相关
    /------------------------------------------------------------------------ */

    update: function (dt) {

    }
});
