import Manager from "./Manager/Manager"
import SoundMgr from "./Manager/SoundMgr"
import AssetMgr from "./Manager/AssetMgr"
import ViewMgr from "./Manager/ViewMgr"
import LayerMgr from "./Manager/LayerMgr"
import ModuleMgr from "./Manager/ModuleMgr"
import LoopMgr from "./Manager/LoopMgr"
import {  EventConst } from "./ConstDefine/EventConst"
import GameUpdateMgr from "./Manager/GameUpdateMgr"

let Managers=[
    LoopMgr,
    AssetMgr,
    LayerMgr,
    SoundMgr,
    ViewMgr,
    ModuleMgr,
    GameUpdateMgr
]

export default class AppFacade{
    private static mgrDic:Map<string,Manager>=new Map()

    private static mgrProgress:number=null  //模块进度
    private static progress:number=null        //总进度
    public static get Progress(){return this.progress}
    private static isInitFinish:boolean=null
    private static isDestroy:boolean=false

    private constructor(){}

    private static hideFun:any
    private static showFun:any
    
    public static onLoad(){
        console.log("onLoad")
        this.mgrProgress=0
        this.progress=0
        this.isInitFinish=false
        this.isDestroy=false
        this.hideFun=this.onHideGame.bind(this)
        this.showFun=this.onShow.bind(this)

        cc.game.on(cc.game.EVENT_SHOW, this.onShow, this)
        cc.game.on(cc.game.EVENT_HIDE, this.onHideGame, this)
    }
    
    public static async onStart(){
        console.log("onStart")
        let counter=0
        for(let mgr of Managers){
            await this.addMgr(mgr as any)
            this.mgrProgress=(++counter/Managers.length)
        }
        this.getMgr(AssetMgr).startPreLoad()
        this.mgrProgress=1
    }

    public static onUpdate(){
        if(this.isInitFinish==false){
            let assetMgr=this.getMgr(AssetMgr)
            let updateMgr=this.getMgr(GameUpdateMgr)
            if(assetMgr){
                //总进度=更新进度+模块加载进度+资源预加载进度
                this.progress=(updateMgr&&updateMgr.Progress||0)*0.5+(this.mgrProgress*0.2)+(assetMgr&&assetMgr.PreProgress*0.3||0)
                this.progress>=1&&(this.isInitFinish=true)
            }
        }else{
            for(let v of this.mgrDic.values()){
                v.update()
            }
        }
    }

    public static onLateUpdate(){
        if(this.isDestroy) return
        for(let v of this.mgrDic.values()){
            v.lateUpdate()
        }
    }

    /**
     * bug:loopMgr清理了事件，最好先释放
     */
    public static async onDestroy(){

        cc.game.off(cc.game.EVENT_SHOW, this.onShow, this)
        cc.game.off(cc.game.EVENT_HIDE, this.onHideGame, this)
        this.onHideGame()
        this.isDestroy=true

        for(let i=0;i<this.mgrDic.size;++i){
            console.log(Managers[i].TypeName)
            this.mgrDic.get(Managers[i].TypeName).release()
        }
        this.mgrDic.clear()
    }


    public static getMgr<T extends Manager>(type:{new():T;TypeName:string}):T{
        let res:T=<T>this.mgrDic.get(type.TypeName)
        return res
    }


    //IManager 要求对象继承于IManager ，用Manager要求对象有一堆属性实现
    //T 是最终存入的对象
    private static async addMgr<T extends Manager>(type:{new():T;TypeName:string}){
        let res:T=<T>this.mgrDic.get(type.TypeName)
        if(!res){
            res=new type()
            await res.start()
            this.mgrDic.set(type.TypeName,res)
        }
        return res
    }

    private static onHideGame(){
        console.log("隐藏到后退或者退出")
        cc.systemEvent.emit(EventConst.HideGame)
    }

    private static onShow(res){
        cc.systemEvent.emit(EventConst.ShowGame,res)
    }

}