import { ResMgr } from "../res/resMgr";
import { ConfigConst } from "../cfg/ConfigDef";
import { ConfigMgr } from "../cfg/configMgr";
import { Utils } from "../common/utils";
import MoveDest from "../update/moveDest";

interface INest {
    num: number;
    delay: number;
    behavior: number;
    pos: string;
}

export interface IBehavior {
    next: number;
    loop: number;
    time: number;
    path: number;
}

interface IPath {
    type: number;
    value: string;
}


enum NestState {
    init,
    moving,
}


export class Nest {
    data: INest;
    parent: cc.Node;
    selfNode: cc.Node;
    pathData: IPath;

    step: number = 0;
    behaviors: IBehavior[];
    state: NestState = NestState.init;
    nextTime: number;

    constructor(data, parent: cc.Node) {
        this.data = data;
        this.parent = parent;

        let node = new cc.Node('nest');
        node.setPosition(Utils.pos2vec2(this.data.pos));
        parent.addChild(node);
        this.selfNode = node;

        cc.director.getScheduler().enableForTarget(this);

        let behaviorId: any = this.data.behavior;
        let arr = [];
        while (behaviorId != '' && behaviorId > 0) {
            let bdata = ConfigMgr.inst.getCfgById(ConfigConst.behavior, behaviorId) as IBehavior;
            arr.push(bdata);
            behaviorId = bdata.next;
        }

        this.behaviors = arr;

    }

    async begin() {
        this.step = 0;
        await this.oneBehavior();
        // cc.director.getScheduler().schedule(this.update, this, 1, cc.macro.REPEAT_FOREVER, 0, false);
        cc.director.getScheduler().scheduleUpdate(this, 1, false);
    }

    update(dt) {
        if(this.state != NestState.moving) return;
        if(Date.now() <= this.nextTime) return;

        let flag = true;
        for (let index = 0; index < this.selfNode.children.length; index++) {
            const element = this.selfNode.children[index];
            let cMoveDest = element.getComponent(MoveDest);
            if(!cMoveDest.isDone()){
                flag = false;
                break;
            }
        }

        if(flag) {
            this.nextBehavior();
        }
    }

    end() {
        cc.director.getScheduler().unscheduleUpdate(this);
    }

    private async oneBehavior() {
        let bdata = this.behaviors[this.step];
        
        this.state = NestState.init;

        if(this.step == 0){
            let res = await ResMgr.inst.getPrefab('monster/monster');
            for (let index = 0; index < this.data.num; index++) {
                let node = new cc.Node('monsterPath');
                this.selfNode.addChild(node);
                ResMgr.inst.createNode(res, node);
                node.addComponent(MoveDest);
            }
        }
        if(bdata.path as unknown != '') {
            let pathData = ConfigMgr.inst.getCfgById(ConfigConst.path, bdata.path) as IPath;
            for (let index = 0; index < this.selfNode.childrenCount; index++) {
                let node = this.selfNode.children[index];
                let monsterNode = node.children[0];
    
                let monsterSize = monsterNode.getContentSize();
        
                let cMoveDest = node.getComponent(MoveDest);
                let dest = Utils.pos2vec2(pathData.value);
                cMoveDest.destination = dest;
                cMoveDest.speed = dest.mag() / bdata.time;
    
                let angle = cc.v2(0, -1).signAngle(dest) / Math.PI * 180;
                monsterNode.angle = Math.round(angle * 100) / 100;
    
                let normalDest = dest.normalize();
                monsterNode.y = -index * monsterSize.height * normalDest.y;
                monsterNode.x = -index * monsterSize.width * normalDest.x;
            }
        }


        this.state = NestState.moving;
        this.nextTime = Date.now() + bdata.time * 1000;
    }

    nextBehavior(){
        this.step ++;
        if(this.step >= this.behaviors.length) {
            this.end();
        }
        else{
            this.oneBehavior();
        }
    }
}
