import { BattleUtil } from "../../tower/data/BattleUtil";
import { DataBase } from "../../tower/data/DataBase";
import { EnemyBornData, MapData, PosData } from "../../tower/data/MapData";
import { ZombieMapConf } from "../conf/ZombieMapConf";
import { ZombieBuffData, ZombieBuffDataPool } from "./ZombieBuffData";
import { ZombieBulletData, ZombieBulletDataPool } from "./ZombieBulletData";
import { ZombieEnemyData, ZombieEnemyDataPool } from "./ZombieEnemyData";
import { ZombieHeroData, ZombieHeroDataPool } from "./ZombieHeroData";

//地图格子 单例
export class ZombieMapData extends MapData {
    protected static instance:ZombieMapData;

    static GetInstance():ZombieMapData{
        if(!ZombieMapData.instance){
            ZombieMapData.instance = new ZombieMapData();
        }
        return ZombieMapData.instance;
    }
    //析构
    static Dispose(){
        ZombieMapData.instance = null;
    }

    
    init(typeID:number){

        this.typeID = typeID;
        this.size = new BattleUtil.Vector2(10,50);
        //this.sizeUnit = new BattleUtil.Vector2(70,70);
        this.length = this.size.x*this.size.y;

        for(let i = 0; i < this.length; i++){
            this.mapPosList.push(this.getPosition(i))
        }
        // for(let i=0;i<this.length;i++){
        //     this.pointList[i] = [];
        // }

        //读表
        this.normalRold = ZombieMapConf.data[typeID.toString()].RoldJsonArr;

        this.endPosition = 250;
        this.attackPosition = ZombieMapConf.data[typeID.toString()].AttackPositionArray;

        let EnemyJsonArr = ZombieMapConf.data[typeID.toString()].EnemyJsonArr;
        EnemyJsonArr.forEach((enemyObj)=>{
            if(enemyObj.length < 7) return;
            for(let j=0;j<enemyObj[5];j++){

                let enemyBornData:EnemyBornData = {
                    bornTime: enemyObj[0] + enemyObj[6]*j,
                    positionID: this.normalRold[enemyObj[4]][0],
                    typeID: enemyObj[2],
                    level: enemyObj[3],
                    roldID: enemyObj[4]
                }
                if(this.enemyBornMap.has(enemyBornData.bornTime)){
                    this.enemyBornMap.get(enemyBornData.bornTime).push(enemyBornData);
                }else{
                    if(this.bornNeedTime < enemyBornData.bornTime){
                        this.bornNeedTime = enemyBornData.bornTime;
                    }
                    this.enemyBornMap.set(enemyBornData.bornTime,[enemyBornData]);
                }
            }
            
        })

        this.attackPosDataMap.clear()
        this.attackPosition.forEach((v,k)=>{
            //this.pointList[pos.x][pos.y] = 1;
            let podID = Number(v)
            let posData:PosData = {
                hero: null,
                posID: podID,
                pos: this.getPosition(podID)
            }


            this.attackPosDataMap.set(v,posData);

        })

        this.curTurn = 0;
        //游戏是否结束
        this._battleEnd = false;
        this._bWin = false;
        
    }

    reset(typeID:number){

        this.typeID = typeID;

        this.attackPosDataMap.clear();
        //所有存活的敌人
        this.enemyDataList.splice(0,this.enemyDataList.length);
        //所有子弹
        this.bulletList.splice(0,this.bulletList.length);
    
        this.buffMap.clear();
    
        
        //操作列表  number表示帧数
        this.actionMap.clear();

        console.log("clear!!")


        //读表
        this.normalRold = ZombieMapConf.data[typeID.toString()].RoldJsonArr;

        this.endPosition = 250;
        this.attackPosition = ZombieMapConf.data[typeID.toString()].AttackPositionArray;

        this.enemyBornMap.clear();
        let EnemyJsonArr = ZombieMapConf.data[typeID.toString()].EnemyJsonArr;
        EnemyJsonArr.forEach((enemyObj)=>{
            if(enemyObj.length < 7) return;
            for(let j=0;j<enemyObj[5];j++){
                let enemyBornData:EnemyBornData = {
                    bornTime: enemyObj[0] + enemyObj[6]*j,
                    positionID: this.normalRold[enemyObj[4]][0],
                    typeID: enemyObj[2],
                    level: enemyObj[3],
                    roldID: enemyObj[4]
                }
                if(this.enemyBornMap.has(enemyBornData.bornTime)){
                    this.enemyBornMap.get(enemyBornData.bornTime).push(enemyBornData);
                }else{
                    if(this.bornNeedTime < enemyBornData.bornTime){
                        this.bornNeedTime = enemyBornData.bornTime;
                    }
                    this.enemyBornMap.set(enemyBornData.bornTime,[enemyBornData]);
                }
            }
            
        })

        this.attackPosDataMap.clear()
        this.attackPosition.forEach((v,k)=>{
            //this.pointList[pos.x][pos.y] = 1;
            let podID = Number(v)
            let posData:PosData = {
                hero: null,
                posID: podID,
                pos: this.getPosition(podID)
            }


            this.attackPosDataMap.set(v,posData);

        })

        this.curTurn = 0;
        this._battleEnd = false;
        this._bWin = false;
    }
    
   getNormalRold(id:number):Array<number>{
       return this.normalRold[id%this.normalRold.length];
   }

   //根据id获取坐标 取值范围[0,this.length-1]
   getPosition(id:number):BattleUtil.Vector2{
       if(id<0 || id>=this.length) return null;
       let pos = new BattleUtil.Vector2(0,0);
       pos.x = id%this.size.x;
       pos.y = Math.floor(id/this.size.x);
       return pos;
   }

   //添加到地图上
   addHero(typeID:number,level:number,posID:number){
        let hero = ZombieHeroDataPool.getObject()
        hero.init(typeID,level,posID);
        console.log(typeof(posID),posID)
       if(this.attackPosDataMap.has(posID)){
            let posData = this.attackPosDataMap.get(posID)
            let posHero = posData.hero;
            if(posHero){
                posHero.clear();
                ZombieHeroDataPool.putObject(posHero);
            }
            posData.hero = hero
           hero.position = posData.pos;
       }
       return hero;
   }
   //移除地图上指定位置的英雄
   removeHero(posID:number){

        if(this.attackPosDataMap.has(posID)){
            let posData = this.attackPosDataMap.get(posID);
            let posHero = posData.hero;
            if(posHero){
                posHero.clear();
                ZombieHeroDataPool.putObject(posHero);
            }
            posData.hero = null;
        }
   }


   /**
    *添加敌人 
    * @param typeID 敌人类型
    * @param level 敌人等级
    * @param roldID 敌人行走路径
    * @param bronPos 敌人在路径上哪个点走
    */
   addEnemy(typeID:number,level:number,roldID:number,bronPos:number){
        let enemy = ZombieEnemyDataPool.getObject()
        let rold = this.getNormalRold(roldID);
        enemy.init(typeID,level,rold);
        this.enemyDataList.push(enemy);
        enemy.position = this.getPosition(bronPos);
        enemy.speedVector = new BattleUtil.Vector2(0,0);

        
        enemy.speedVector = this.getEnemySpeedVector(enemy);
        
        enemy.posID = bronPos;

        return enemy;
   }
   //移除地图上指定的敌人
   removeEnemy(enemy:ZombieEnemyData){
        let index = this.enemyDataList.indexOf(enemy);
        if(index>=0){
            this.enemyDataList.splice(index,1);
        }
        enemy.clear();
        ZombieEnemyDataPool.putObject(enemy);
   }

   getEnemySpeedVector(enemy:ZombieEnemyData):BattleUtil.Vector2{
        let oldPos = this.mapPosList[enemy.posID]
        let newPos = this.mapPosList[enemy.nextPosID]
        if(newPos){
            let direction = BattleUtil.Vector2.Sub(newPos,oldPos)
            direction.multiply(enemy.speedCur)
            return direction;
        }
        return new BattleUtil.Vector2(0,0);
   }

    addBuff(buffID:number,duration:number,valueList:Array<number>,src:DataBase,target:DataBase){
        let buff:ZombieBuffData = this.buffMap.get(buffID)
        if(buff == null){
            buff = ZombieBuffDataPool.getObject()
            buff.init(buffID,duration,valueList,src,target)
            this.buffMap.set(buff.ID,buff)
            if(target instanceof ZombieEnemyData){
                target.addBuff(buff)
            }
        }
        return buff;
    }

    removeBuff(ID:number){
        let buff:ZombieBuffData = this.buffMap.get(ID)
        if(buff != null){
            let target = buff.targetDataBase
            if(target instanceof ZombieEnemyData){
                target.removeBuff(buff)
            }
            buff.clear()
            ZombieBuffDataPool.putObject(buff)
            this.buffMap.delete(ID)
        }
    }

    addBullet(typeID:number,srcHero:ZombieHeroData,targetEnemy:ZombieEnemyData){
        let bullet:ZombieBulletData = ZombieBulletDataPool.getObject()
        bullet.init(typeID,srcHero,targetEnemy)
        this.bulletList.push(bullet)
        return bullet;
    }

    removeBullet(bullet:ZombieBulletData){
        let index = this.bulletList.indexOf(bullet);
        if(index>=0){
            this.bulletList.splice(index,1);
        }
        bullet.clear();
        ZombieBulletDataPool.putObject(bullet);
   }


   clear(){
        this.attackPosDataMap.forEach((posData,posID)=>{
            if(posData.hero){
                posData.hero.clear();
                ZombieHeroDataPool.putObject(posData.hero);
            }
        })
        this.attackPosDataMap.clear();
        this.enemyDataList.forEach((enemy)=>{
            enemy.clear();
            ZombieEnemyDataPool.putObject(enemy);
        })
        this.enemyDataList = [];
        // this.bulletList.forEach((bullet)=>{
        //     bullet.clear();
        //     BulletDataPool.putObject(bullet);
        // })
        // this.bulletList = [];

        this.buffMap.forEach((buff)=>{
            buff.clear();
            ZombieBuffDataPool.putObject(buff);
        })
   }

}