import { GlobalParam } from "../Net/GlobalParam";
import Sprite3D = Laya.Sprite3D;
import {LevelController} from "../Game/LevelController";
import {GameTool} from "../Util/GameTool";
import { GamePool } from "../Game/GamePool";
import { Street } from "../Game/Street";
import Dictionary from "../Util/Dictionary";
import { ParticleManager } from "../Game/ParticleManager";
import { NetInfoManager } from "../Game/NetInfoManager";
import {GuideController} from "./GuideController";
import {MoundManager} from "./MoundManager";

import Texture = Laya.Texture;

import Sprite = Laya.Sprite;
import Stage = Laya.Stage;
import Event = Laya.Event;
import Browser = Laya.Browser;
import WebGL = Laya.WebGL;

export class RoadArr {
    blocks: Array<BlockArr>;
    blockPos: Array<number>;
    constructor(blocks, blockPos) {
        this.blocks = blocks;
        this.blockPos = blockPos;
    }
}
export class BlockArr {
    things: Array<ThingArr>;
    thingPos: Array<number>;
    blockHp: Array<number>;
    constructor(things, thingPos, blockHp) {
        this.things = things;
        this.thingPos = thingPos;
        this.blockHp = blockHp;
    }
}
export class ThingArr {
    type: number;
    prrfabName: string;
    moveType: number;
    moveSpeed: number;
    x: number;
    z: number;
    towerR: boolean;
    hp: number;
    constructor(type, prrfabName, moveType, moveSpeed) {
        this.type = type;
        this.prrfabName = prrfabName;
        this.moveType = moveType;
        this.moveSpeed = moveSpeed;
    }
}
export default class StreetManager {
    private static instance: StreetManager;
    public static get Instance(): StreetManager {
        return StreetManager.instance || (StreetManager.instance = new StreetManager());
    }

    private blockDic: Dictionary;
    private cubeBlockDic: Dictionary;
    constructor() {
        this.blockDic = new Dictionary();
        this.cubeBlockDic = new Dictionary();
    }
    private BlockContainer: Sprite3D;
    public Init(BlockContainer: Sprite3D) {
        this.BlockContainer = BlockContainer;
    }
    public tarDis: number;
    public isover = false;
    public curindex = 1;
    public SetBlock() {
        this.isover = false;
        this.curindex = 1;
        this.CreateStreet();
    }

    /************************************************* */
    private texture1: string = "res/apes/monkey2.png";
    private texture2: string = "res/apes/monkey3.png";
    private flag: boolean = false;

    private ape: Sprite;
    private onAssetsLoaded(): void {
        this.ape = new Sprite();
        Laya.stage.addChild(this.ape);
        this.ape.pivot(55, 72);
        this.ape.pos(Laya.stage.width / 2, Laya.stage.height / 2);

        // 显示默认纹理
        this.switchTexture();
        this.ape.on("click", this, this.switchTexture);
    }

    private switchTexture(): void {
        var textureUrl: string = (this.flag = !this.flag) ? this.texture1 : this.texture2;

        // 更换纹理
        this.ape.graphics.clear();
        var texture: Texture = Laya.loader.getRes(textureUrl);
        this.ape.graphics.drawTexture(texture, 0, 0);

        // 设置交互区域
        this.ape.size(texture.width, texture.height);
    }
    /************************************************* */


    
    public CheckPlayerRoadPos(_zp: number) {
        if (this.isover) return;
        let d = this.tarDis - _zp;
        if (d > 0) return;
        this.StreetSwitch();
    }

    private StreetSwitch() {
        this.curindex++;
        this.CreateStreet();
    }

    CreateSprite(road: RoadArr) {
        if(GuideController.Instance._guide){
            GuideController.Instance.InitGuide(road.blockPos[0]);
        }
        let blocks = road.blocks;
        let blockPos = road.blockPos;
        let j = 0;
        for (let index = 0; index < blocks.length; index++) {
            const element = blocks[index] as BlockArr;
            const p = blockPos[index];
            let things: Array<ThingArr> = element.things
            let thingPos: Array<number> = element.thingPos;
            let blockHp: Array<number> = element.blockHp;
            let isr = blockHp.length > 1;
            for (let index = 0; index < things.length; index++) {
                const element1 = things[index] as ThingArr;
                element1.z = p;
                element1.x = thingPos[index];
                element1.towerR = isr;
                element1.hp = blockHp[index];
                j++;
                Laya.timer.frameOnce(j, this, this.Create, [element1], false);
            }
        }
    }
    Create(thing: ThingArr) {
        if (thing.type == 1 || thing.type == 2) {
            MoundManager.Instance.MakeMound(thing);
        } else {
            let p = GamePool.Instance.GetModel(thing.prrfabName);
            if (!p) return;
            this.BlockContainer.addChild(p);
            let ts = p.getComponent(Street) as Street;
            if (!ts) ts = p.addComponent(Street) as Street;
            ts.SetStreet(thing);
            this.blockDic.set(p.id, ts);
        }
    }

    RecoverStreet(sp: Sprite3D) {
        this.blockDic.delete(sp.id);
    }

    
    StreetAtkedCube(sp: Sprite3D) {
        sp.active = false;
        ParticleManager.Instance.ExplodeEffect(sp.transform.position);
    }

    Reset() {
        this.isover = false;
        let arr = [];
        for (const key in this.blockDic.container) {
            arr.push(key);
        }
        let j = 1;
        if (arr.length > 0) {
            for (let index = 0; index < arr.length; index++) {
                const element = arr[index];
                let s = this.blockDic.get(element) as Street;
                if (s) s.Recover();
                if (this.cubeBlockDic.has(element)) {
                    Laya.timer.frameOnce(j, this, this.StreetResetCube, [element], false);
                    j++;
                }
            }
        }
    }


    StreetAddCube(sp: Sprite3D) {
        if (this.cubeBlockDic.has(sp.id)) return;
        this.cubeBlockDic.set(sp.id, sp);
    }
    StreetResetCube(id) {
        let sp = this.cubeBlockDic.get(id) as Sprite3D;
        this.cubeBlockDic.delete(id);
        if (!sp) return;
        console.log("回收CubeBlock,", sp.name);
        for (let index = 0; index < sp.numChildren; index++) {
            const element = sp.getChildAt(index) as Sprite3D;
            element.active = true;
        }
    }

    /****************************************************** */
    private sp1: Sprite;
    private sp2: Sprite;
    private createApes(): void {
        var gap: number = 300;
        this.sp1 = new Sprite();
        this.sp1.pos((Laya.stage.width - gap) / 2, Laya.stage.height / 2);
        //设置轴心点为中心
        this.sp1.pivot(55, 72);
        Laya.stage.addChild(this.sp1);
        //不设置轴心点默认为左上角
        this.sp2 = new Sprite();
        this.sp2.pos((Laya.stage.width + gap) / 2, Laya.stage.height / 2);
        Laya.stage.addChild(this.sp2);
        Laya.timer.frameLoop(1, this, this.animate);
    }

    private animate(e: Event): void {
        this.sp1.rotation += 2;
        this.sp2.rotation += 2;
    }
    /****************************************************** */

    public CreateStreet() {
        let road_list = LevelController.Instance._level.road_list;
        if (this.curindex > road_list.length - 1) {
            this.isover = true;
            console.log("没有障碍物了")
            return;
        }
        this.tarDis = //GlobalParam.barrierRoadLength;
            this.curindex * GlobalParam.barrierRoadLength;
        let roadindex = road_list[this.curindex];
        if (roadindex == 0) return;
        let roads =NetInfoManager.Instance.GetRoad(roadindex);
        if (!roads) return;
        let blocks = GameTool.SpliteString(roads["blocks"]);
        let blockPoss = GameTool.SpliteString(roads["position"]);

        //block的位置
        let bps = [];
        let d = GlobalParam.barrierRoadLength / GlobalParam.barrierRoadAverageNum;
        blockPoss.forEach(element => {
            bps.push(this.tarDis + element * d);
        });
        //block数组
        let bbs = [];
        blocks.forEach(element => {
            let thing =NetInfoManager.Instance.GetStreet(element) ;
            let tss = GameTool.SpliteString(thing["block_things"]);
            let tps = GameTool.SpliteString(thing["thing_position"]);
            let ths = GameTool.SpliteString(thing["block_hp"]);

            let ttt = [];
            tss.forEach(element1 => {
                let t =NetInfoManager.Instance.GetThing(element1) ;
                let tt = new ThingArr(t["type"], t["prefabs"], t["dynamic_type"], t["dynamic_speed"])
                ttt.push(tt);
            });
            let things = new BlockArr(ttt, tps, ths);
            bbs.push(things);
        });
        let blockB = new RoadArr(bbs, bps);
        this.CreateSprite(blockB);
    }


}