import ConfigManager from "./configs/ConfigManager";
import { GUIManager } from "./gui/GUIManager";
import IInitiator from "./initiators/IInitiator";
import InitiatorEvent from "./initiators/InitiatorEvent";
import LoadingView from "./loadingView/LoadingView";
import { SoundManager } from "./sounds/SoundManager";

const {ccclass, property} = cc._decorator;

@ccclass
export default class GEngine extends cc.Component
{
    @property(cc.Node)
    layerRoot:cc.Node=null;

    private __initiators:IInitiator[];
    private __completeCallBack:Function;
    private __autoTick:boolean;
    private __inited:boolean;

    start():void{
        if(GEngine.single!=null){
            throw new Error("引擎单例已存在");
        }
        GEngine.instance=this;
        this.__inited=false;
    }

    /**
     * @param initiators          初始化流程
     * @param completeCallBack    完成回调
     * @param autoTick            true 内部调用心跳 false不调用
     */
    public Startup(initiators:IInitiator[],completeCallBack:Function,autoTick:boolean=true):void{
        this.__initiators=initiators;
        this.__completeCallBack=completeCallBack;
        this.__autoTick=autoTick;
        //节点静态化
        cc.game.addPersistRootNode(this.node);

        this.addComponent(SoundManager);
        
        this.__initiatorTotal=this.__initiators.length;
        this.TryNextInitiator();
    }

    update(dt:number):void{
        if(this.__inited&&this.__autoTick){
            this.Tick(dt);
        }
    }

    /**
     * 心跳
     * @param dt 
     */
    Tick(dt:number):void{
        GUIManager.single.Tick(dt);
    }

    private __initiatorTotal:number=0;
    private __currentInitiator:IInitiator;
    private TryNextInitiator():void{
        if(this.__currentInitiator!=null){
            this.__currentInitiator.RemoveAllEvent();
            this.__currentInitiator.Destroy();
            this.__currentInitiator=null;
        }
        if(this.__initiators.length>0){
            this.__currentInitiator=this.__initiators.shift();
            LoadingView.single.UpdateLabel(this.__currentInitiator.GetName());
            this.__currentInitiator.AddEvent(InitiatorEvent.EVENT_PROGRESS,this,this.InitiatorProgressEventHandler);
            this.__currentInitiator.AddEvent(InitiatorEvent.EVENT_ERROR,this,this.InitiatorErrorEventHandler);
            this.__currentInitiator.AddEvent(InitiatorEvent.EVENT_COMPLETE,this,this.InitiatorCompleteEventHandler);
            this.__currentInitiator.Start();
        }else{
            this.onComplete();
        }
    }
    
    private InitiatorProgressEventHandler(progress:number):void{
        let value:number=(this.__initiatorTotal-this.__initiators.length+progress)/this.__initiatorTotal;
        LoadingView.single.UpdateProgress(value);
    }
    
    private InitiatorErrorEventHandler(msg:string):void{
        throw new Error(msg);
    }

    private InitiatorCompleteEventHandler():void{
        cc.log(this.__currentInitiator.GetName()+"完成");
        this.TryNextInitiator();
    }

    private onComplete():void{
        if(this.__completeCallBack!=null){
            this.__completeCallBack();
            this.__completeCallBack=null;
        }
        this.__inited=true;
    }

    private static instance:GEngine;
    public static get single():GEngine{
        return this.instance;
    }
}