import { BlockType } from "./Block";

// 主游戏控制类
const {ccclass, property} = cc._decorator;
@ccclass
export default class GameManager extends cc.Component {

    @property(cc.Node)
    Map: cc.Node = null;

    @property(cc.Prefab)
    Block: cc.Prefab = null;

    countTime: number;      //总倒计时
    block_Array: any;       //所有块数组
    path_Array: any;        //修筑路径
    map_Array: any;         //地图数组
    water_PathAray:any;     //洪峰路径
    map_Hight:number;       //地图高度
    map_Width:number;       //地图宽度

    onLoad () {

    }
    start () {
        this.fit();
        this.init();
    }
    //初始化数据
    init(){
        this.initMap();

    }
    //初始化地图
    initMap(){
        this.block_Array = [];
        this.path_Array = [];
        this.map_Array = [];
        this.map_Hight = 0;
        this.map_Width = 0;
        let arr = cc.fx.GameConfig.LEVEL_INFO[0][0].map;
        //将地图x,y轴切换

        this.map_Array = arr[0].map((item, i) => {
            return arr.map((val) => val[i])
        })
        this.map_Width = this.map_Array.length;
        this.map_Hight = this.map_Array[0].length;

        for(let i=0;i<this.map_Array.length;i++){
            for(let j=0; j<this.map_Array [i].length;j++){
                let block = cc.instantiate(this.Block);
                block.parent= this.Map;
                block.getComponent("Block").initData(this.map_Array [i][j]);
                if(this.map_Array [i][j] == cc.Enum(BlockType).Start) this.path_Array.push(cc.v3(i,j,cc.Enum(BlockType).Nomal));
                block.setPosition(cc.v2(-block.width*2.5 + i*block.width,block.height*4 - j*block.height));
                this.block_Array.push(block);
            }
        }
    }

    //开始后，按玩家操作，将路径中地图块放入数组中
    setMap(data){
        for(let i=0; i<data.length; i++){
            let start = this.path_Array[this.path_Array.length-1];
            switch(data[i]){
                case "up":
                    this.path_Array.push(cc.v3(start.x,start.y-1,cc.Enum(BlockType).Nomal));
                    break;
                case "down":
                    this.path_Array.push(cc.v3(start.x,start.y+1,cc.Enum(BlockType).Nomal));
                    break;
                case "left":
                    this.path_Array.push(cc.v3(start.x-1,start.y,cc.Enum(BlockType).Nomal));
                    break;
                case "right":
                    this.path_Array.push(cc.v3(start.x+1,start.y,cc.Enum(BlockType).Nomal));
                    break;
                case "reinforce":
                    this.path_Array.push(cc.v3(start.x,start.y,cc.Enum(BlockType).Reinforce));
                    break;
                case "soil":
                    this.path_Array.push(cc.v3(start.x,start.y,cc.Enum(BlockType).Xi_Soil));
                    break;
            }
        }

        this.runWater(0);
    }
    //开始执行洪峰来了的动画
    runWater(order){
        order = parseInt(order);
        if(order <= this.path_Array.length-1){
            let i = this.path_Array[order].x*this.map_Array[0].length+this.path_Array[order].y;
            let direction = "";
            let circulate = true;
            if(order == this.path_Array.length-1){
                circulate = false;
                direction = "End";
                // if(direction == "up" || direction == "right_up" || direction == "left_up"){
                //     direction = "up";
                // }
                // else if(direction == "down" || direction == "left_down" || direction == "right_down"){
                //     direction = "down";
                // }
                // else if(direction == "left" || direction == "up_left" || direction == "down_left"){
                //     direction = "left";
                // }
                // else if(direction == "right" || direction == "up_right" || direction == "down_right"){
                //     direction = "right";
                // }
            }
            else{

                if(this.path_Array[order].z == 6 && order + 1 < this.path_Array.length) {
                    direction = "Reinforce";
                    i = this.path_Array[order+1].x*this.map_Array[0].length+this.path_Array[order+1].y;
                }
                else if(order+1 < this.path_Array.length){
                    if(this.path_Array[order+1].z == 5){
                        direction = "Xi_Soil";
                    }
                    else{
                        direction = this.getDirection(order);
                    }
                }
                else{
                    direction = this.getDirection(order);
                }
            }
            // console.log(order,this.path_Array[order].x,this.path_Array[order].y,i);
            let jg = this.getBoundary(order,this.path_Array[order].x,this.path_Array[order].y,direction);

            if(direction == "" || jg == false) return;
            let target = this.block_Array[i].getComponent("Block");
            // console.log("步骤:",order,"方向",direction);
            target.setPath(direction);
            if(order > 0 && order < this.path_Array.length-1){
                if(this.path_Array[order+1].z == 5){
                    this.set_Soil(order+1);
                    circulate = false;
                    return;
                }
            }
            let data = {
                order:order,
                time:0.2,
                type:this.path_Array[order].z,
                circulate:circulate
            };
            target.runWater(data);
        }
    }
    //判断边界。或者撞山，或者湿地没有加固
    getBoundary(order,x,y,direction){
        let jg = true;
        if(x < 0 || x >= this.map_Width || y < 0 || y >= this.map_Hight){
            jg = false;
            console.log("超过边界，游戏结束");
            alert("超过边界，游戏结束");
        }
        else {
            let i = this.path_Array[order].x*this.map_Array[0].length+this.path_Array[order].y;
            let target = this.block_Array[i].getComponent("Block");
            if(target.block_Type == 3){
                jg = false;
                console.log("修筑山峰，游戏结束");
                alert("修筑山峰，游戏结束");
            }
            else if(target.block_Type == 2 && direction != "Reinforce"){
                jg = false;
                console.log("修筑未加固湿地,游戏结束");
                alert("修筑未加固湿地,游戏结束");
            }
        }
        return jg;
    }

    //获取息壤的格子的方向
    getXi_Soil(order){
        var direction = null;
        //如果息壤后面还有下一步的话
        if(order + 1 < this.path_Array.length){
            direction = this.getDirection(order);
            if(direction == "up" || direction == "right_up" || direction == "left_up"){
                direction = "up";
            }
            else if(direction == "down" || direction == "left_down" || direction == "right_down"){
                direction = "down";
            }
            else if(direction == "left" || direction == "up_left" || direction == "down_left"){
                direction = "left";
            }
            else if(direction == "right" || direction == "up_right" || direction == "down_right"){
                direction = "right";
            }
        }  
        return direction;
    }
    //设置息壤
    set_Soil(order){
        var direction = this.getXi_Soil(order);
        var length = 0;
        if(direction == "right"){
            length = this.map_Width - 1;
            for(let i=this.path_Array[order].x;i<=length;i++){
                let n = i*this.map_Array[0].length+this.path_Array[order].y;
                let target = this.block_Array[n].getComponent("Block");
                if(target.block_Type == 3){
                    length = i-1;
                    i = 10000;
                    break;
                }
            }
        } 
        else if(direction == "left"){
            length = 0;
            for(let i=this.path_Array[order].x;i>=length;i--){
                let n = i*this.map_Array[0].length+this.path_Array[order].y;
                let target = this.block_Array[n].getComponent("Block");
                if(target.block_Type == 3){
                    length = i+1;
                    i = -1;
                    break;
                }
            }
        } 
        else if(direction == "up"){
            length = 0;
            for(let i=this.path_Array[order].y;i>=length;i--){
                let n = this.path_Array[order].x*this.map_Array[0].length+i;
                let target = this.block_Array[n].getComponent("Block");
                if(target.block_Type == 3){
                    length = i+1;
                    i = -1;
                    break;
                }
            }
        } 
        else if(direction == "down"){
            length = this.map_Hight - 1;
            for(let i=this.path_Array[order].y;i<=length;i++){
                let n = this.path_Array[order].x*this.map_Array[0].length+i;
                let target = this.block_Array[n].getComponent("Block");
                if(target.block_Type == 3){
                    length =  i-1;
                    i = 10000;
                    break;
                }
            }
        } 

        this.soil_Find(direction,order,length);
    }
    //查找息壤蛮遗憾路径
    soil_Find(direction,order,length){
        let start = this.path_Array[order].x;
        if(direction == "right"){
            for(let i = start; i<=length; i++){
                let n = i*this.map_Array[0].length+this.path_Array[order].y;
                let target = this.block_Array[n].getComponent("Block");
                if(i == start)  target.set_Xi_SoilType(this.getDirection(order),null);
                else {
                    let jg = null;
                    if(i == length){
                        let number = i - start -1;
                        this.changePath(order,number,false);
                        jg = order;
                    } 

                    target.set_Xi_SoilType(direction,jg);
                    
                }   
            }
        } 
        else if(direction == "left"){
            for(let i = start; i>=length; i--){
                let n = i*this.map_Array[0].length+this.path_Array[order].y;
                let target = this.block_Array[n].getComponent("Block");

                if(i == start)  target.set_Xi_SoilType(this.getDirection(order),null);
                else {
                    let jg = null;
                    if(i == length){
                        let number = i - start + 1;
                        this.changePath(order,number,false);
                        jg = order;
                    } 
                    target.set_Xi_SoilType(direction,jg);
                }
            }
        } 
        else if(direction == "up"){
            start = this.path_Array[order].y;
            for(let i = start; i>=length; i--){
                let n = this.path_Array[order].x*this.map_Array[0].length+i;
                let target = this.block_Array[n].getComponent("Block");
                if(i == start)  target.set_Xi_SoilType(this.getDirection(order),null);
                else {
                    let jg = null;
                    if(i == length){
                        let number = i - start + 1;
                        this.changePath(order,number,true);
                        jg = order;
                    } 
                    target.set_Xi_SoilType(direction,jg);
                }
            }
        } 
        else if(direction == "down"){
            start = this.path_Array[order].y;
            for(let i = start; i<=length; i++){
                let n = this.path_Array[order].x*this.map_Array[0].length+i;
                let target = this.block_Array[n].getComponent("Block");
                if(i == start)  target.set_Xi_SoilType(this.getDirection(order),null);
                else {
                    let jg = null;
                    if(i == length){
                        let number = i - start - 1;
                        this.changePath(order,number,true);
                        jg = order;
                    } 
                    target.set_Xi_SoilType(direction,jg);
                }
            }
        } 
    }

    //息壤过后改变修筑路径
    changePath(order,number,direction){
        for(let i = (order+1); i<this.path_Array.length; i++){
            if(!direction)this.path_Array[i].x += (number);
            else this.path_Array[i].y += (number);
        }
        // // this.path_Array[data-1].x = 5;
        // this.path_Array[data].x = 5;

    }

    changeMap(data){

    }

    //获取洪峰方向
    getDirection(order){
        var name = "";
        //入海口比较复杂单独判断
        if(order == 0){
            let nextX = this.path_Array[order+1].x - this.path_Array[order].x;
            let nextY = this.path_Array[order].y - this.path_Array[order+1].y;
            //在底边
            if(this.path_Array[order].y == this.map_Array[0].length-1){
                if(nextX == 0){
                    if(nextY == 1)name = "up";
                    else if(nextY == -1) name = "err";
                }
                else if(nextX == 1) name = "up_right";
                else if(nextX == -1) name = "up_left";
            }
            //在顶边
            else if(this.path_Array[order].y == 0){
                if(nextX == 0){
                    if(nextY == 1)name = "err";
                    else if(nextY == -1) name = "down";
                }
                else if(nextX == 1) name = "down_right";
                else if(nextX == -1) name = "down_left";
            }
            //在左边
            else if(this.path_Array[order].x == 0){
                if(nextX == 0){
                    if(nextY == 1)name = "right_up";
                    else if(nextY == -1) name = "right_down";
                }
                else if(nextX == 1) name = "right";
                else if(nextX == -1) name = "err";
            }
            //在右边
            else if(this.path_Array[order].x == this.map_Array.length-1){
                if(nextX == 0){
                    if(nextY == 1)name = "left_up";
                    else if(nextY == -1) name = "left_down";
                }
                else if(nextX == 1) name = "err";
                else if(nextX == -1) name = "left";
            }
        }
        //不是第一步，已经走过一步
        else if(order > 0){
            var next = 1;
            if(order+2 < this.path_Array.length){
                if(this.path_Array[order+1].z == 6) next = 2;
            }
         
            //用于判断此点的上一个点，是为了判断当前方块洪水七点，以及下一个移动方向，判断洪终点方向
            let nextX = this.path_Array[order+next].x - this.path_Array[order].x;
            let nextY = this.path_Array[order].y - this.path_Array[order+next].y
            let previousX = this.path_Array[order].x - this.path_Array[order-1].x;
            let previousY = this.path_Array[order-1].y - this.path_Array[order].y;
            if(previousX == 0 && previousY == 0){
                previousX = this.path_Array[order].x - this.path_Array[order-2].x;
                previousY = this.path_Array[order-2].y - this.path_Array[order].y;
            }
            if(previousX == 0 && previousY >= 1){
                if(nextX == 0){
                    if(nextY == 1)name = "up";
                    else if(nextY == -1) name = "err";
                }
                else if(nextX == 1) name = "up_right";
                else if(nextX == -1) name = "up_left";
            }
            else if(previousX == 0 && previousY <= -1){
                if(nextX == 0){
                    if(nextY == 1)name = "err";
                    else if(nextY == -1) name = "down";
                }
                else if(nextX == 1) name = "down_right";
                else if(nextX == -1) name = "down_left";
            }
            else if(previousX >= 1 && previousY == 0){
                if(nextX == 0){
                    if(nextY == 1)name = "right_up";
                    else if(nextY == -1) name = "right_down";
                }
                else if(nextX == 1) name = "right";
                else if(nextX == -1) name = "err";
            }
            else if(previousX <= -1 && previousY == 0){
                if(nextX == 0){
                    if(nextY == 1)name = "left_up";
                    else if(nextY == -1) name = "left_down";
                }
                else if(nextX == 1) name = "err";
                else if(nextX == -1) name = "left";
            }
        }

        return name ;
    }

    //根据是否全面屏，做独立适配方面
    fit(){
        var jg = this.setFit();
        if(!jg){

        }
    }
    //判断全面屏
    getSetScreenResolutionFlag () {
        let size = cc.winSize;
        let width = size.width;
        let height = size.height;
        if ((height / width) > (16.2 / 9)) return false;
        return true;
    }
    //判断全面屏适配
    setFit () {
        let flag = this.getSetScreenResolutionFlag();
        if (flag) {
        } else {
        }
        return flag;
    }
    //返回首页
    backScene(){
        cc.director.loadScene("LoadScene");
    }
    //下一关，或者重新开始，或者返回上一关，根据level决定
    reStart(type){

    }
    //获取时间戳
    getTime(){
        const timestamp = new Date().getTime();
        return timestamp;
    }
    //获胜
    passLevel(){

    }
    //失败
    loseLevel(type){
        //1:  1649
        //2:  3646
        //3:  5546
        //4:  2600
        //5:  694
    }

    //开始游戏
    startGame(data){
        this.setMap(data);
    }


    //如果是倒计时 调用此方法
    updateCountDownTime () {
        if (this.countTime > 0) {
            this.countTime -= 1;
            // this.time.string =  cc.fx.GameTool.getTimeMargin(this.countTime);
            if(this.countTime < 5){
                let over = this.node.getChildByName("Over");
                cc.tween(over)
                .to(0.2,{opacity:255})
                .delay(0.1)
                .to(0.2,{opacity:0})
                .start();
            }
            if(this.countTime <= 0){
                this.unschedule(this.updateCountDownTime);
                var time = 0;
                this.gameOver(time);    
            }
        }
    }
    //上传每次操作数据

    setData(){
        cc.fx.GameTool.setGameData();
        
    }
    //上传排行榜数据
    gameOver(time){
        cc.fx.GameTool.setRank(time);
        this.node.getChildByName("GameOver").active = true;
        this.node.getChildByName("GameOver").opacity = 0;
        cc.tween(this.node.getChildByName("GameOver"))
        .to(0.4,{opacity:255})
        .delay(2)
        .to(0.4,{opacity:50})
        .call(() =>{
            cc.director.loadScene("OverScene");
        })
        .start()
    }

    clickSun(data){
    
    }

    nextWater(){

    }

    onEnable () {
        cc.fx.Notifications.on(cc.fx.Message.control, this.clickSun, this);
        cc.fx.Notifications.on(cc.fx.Message.next, this.runWater, this);
        cc.fx.Notifications.on(cc.fx.Message.startGame, this.startGame, this);
        cc.fx.Notifications.on(cc.fx.Message.changePath, this.changePath, this);
        cc.fx.Notifications.on(cc.fx.Message.changeMap, this.changeMap, this);
    }
    onDisable () {
        cc.fx.Notifications.off(cc.fx.Message.control, this.clickSun);
        cc.fx.Notifications.off(cc.fx.Message.next, this.runWater);
        cc.fx.Notifications.off(cc.fx.Message.startGame, this.startGame);
        cc.fx.Notifications.off(cc.fx.Message.changePath, this.changePath);
        cc.fx.Notifications.off(cc.fx.Message.changeMap, this.changeMap);
    }
    update (dt) {
    }
}
