
import { destroyLayers, layers } from "../module/views/layers";
import { RES } from "../module/RES";
import { changeScene, destroyAllCtrls, hideWaiting, showPanel, showToast, showWaiting } from "../module/ctrls";
import MusicBtn from "./common/MusicBtn";

import { ResJson } from "./ResJson";
import { destroyTbNetData, sendTbNet, TbNetName } from "./TaoBaoNet";
import { SkinJson } from "./SkinJson";
import { G_EVENT } from "./common/G_EVENT";
import { Tools } from "./Tools";
import { LevonoGameScene } from "./scenes/LevonoGameScene/LevonoGameScene";
import { GameDiffConfig } from "./scenes/LevonoGameScene/GameEle";

/**
 * 全局事件，为了和小程序交互
 * 有可能多处页面用到，所以单开
 */
export const GDispatcher = new FYGE.EventDispatcher();

export class Main {
    //主舞台
    stage: FYGE.Stage;
    private requestID;
    private _pause: boolean;
    private canvas: HTMLCanvasElement

    constructor(canvas: HTMLCanvasElement, PAGE) {
        Tools.PAGE = PAGE;
        var sysInfo;
        //淘宝小程序环境就用canvas初始化
        if (!window) {//自行处理吧，这么判断也不保险，万一淘宝小程序加进了window
            FYGE.initedByCanvas(canvas)//里面会设置env为tb，这个很重要
            //@ts-ignore 存在my就初始化
            sysInfo = my.getSystemInfoSync()
        }
        //建舞台
        var stage = new FYGE.Stage(
            canvas,
            750,//设计宽度，按设计搞给的就行
            1624,//设计高度
            sysInfo && sysInfo.windowWidth || document.body.clientWidth,
            sysInfo && sysInfo.windowHeight || document.body.clientHeight,
            FYGE.RENDERER_TYPE.WEBGL,
            true  //视窗居中裁切
        );
        this.stage = stage;
        this.canvas = canvas;//赋值下，为了下面的destroy的cancelAnimationFrame
        //stage初始化
        stage.addEventListener(FYGE.Event.INIT_STAGE, this.onAddToStage, this);
        //帧率
        // var stats = new FYGE.Stats("canva4stats");
        //循环
        var self = this;
        // console.log(FYGE)
        loop();

        function loop() {
            if (!self._pause) {
                // stats.begin();
                FYGE.Tween.flush()
                stage.flush();
                // stats.end();
            }
            //@ts-ignore
            // self.requestID = FYGE.getRequestAnimationFrame()(loop);
            //为了兼容多page的canvas
            FYGE.getEnv() == "tb" ? self.requestID = canvas.requestAnimationFrame(loop) :
                self.requestID = window.requestAnimationFrame(loop);
        }
    }

    /**
     * 在小程序显示时调用onShow
     */
    run() {
        this._pause = false;
        //@ts-ignore Tween计时清零
        FYGE.Tween._lastTime = null;

        GDispatcher.dispatchEvent({ type: G_EVENT.ON_SHOW });
    }

    /**
     * 在小程序隐藏时调用onHide
     */
    pause() {
        // this._pause = true;//先不暂停了
        GDispatcher.dispatchEvent({ type: G_EVENT.ON_HIDE });
    }

    /**
     * 添加全局事件，用于小程序的交互调用
     * 一直很犹豫要不要放在main的实例里，还是和Main同级导出，还有上面的pause，run，下面的事件等
     * @param name
     * @param fun
     * @param thisObj
     */
    addGlobalEvent(name: string, fun: Function, thisObj?: any, once: boolean = false) {
        if (once) {
            GDispatcher.once(name, fun, thisObj)
        } else {
            GDispatcher.addEventListener(name, fun, thisObj)
        }
    }

    /**
     * 派发全局事件，用于小程序的交互调用
     * @param name 可以是事件名，也可以是事件
     * @param data
     */
    dispatchGlobalEvent(name: string | any, data?: any) {
        GDispatcher.dispatchEvent(name, data)
    }

    /**
     * 移除全局事件，用于小程序交互调用
     * @param name
     * @param fun
     * @param thisObj
     */
    removeGlobalEvent(name: string, fun: Function, thisObj?: any) {
        GDispatcher.removeEventListener(name, fun, thisObj)
    }

    // 在小程序页面卸载时调用onUnload，多次销毁后会有问题，再检查
    async destroy() {
        // Tween都移除，注意吧，可能原先的也被移除,,对于多page时注意，会把其他页面的也去掉
        FYGE.Tween.removeAllTweens()
        // 停掉计时器
        //@ts-ignore 为了兼容多page的canvas
        FYGE.getEnv() == "tb" ? this.canvas.cancelAnimationFrame(this.requestID) :
            window.cancelAnimationFrame(this.requestID);
        
        // 层级销毁
        destroyLayers()
        // 销毁控制器
        destroyAllCtrls();

        // 舞台销毁
        // this.stage.destroy();
        // 全局事件置空
        GDispatcher.removeAllEventListener();
        // 淘宝环境网络数据记录清空
        destroyTbNetData();
        // web环境其实没必要
        // destroyWebNetData()
    }

    public static async onPreloadResource() {
        return new Promise<void>(async (r) => {
            RES.loadConfig(ResJson);
            // 皮肤配置加载
            RES.loadSkinConfig(SkinJson);
            await RES.loadAllGroup()
            r()
        })
    }

    private async onAddToStage() {
        //初始化层级
        layers.init(this.stage);
        console.log("初始化层级完成")
        // 初始化资源配置
        RES.loadConfig(ResJson);
        console.log("初始化资源配置完成")
        // 皮肤配置加载
        RES.loadSkinConfig(SkinJson);
        console.log("初始化皮肤配置完成")
        // 加载通用资源
        await RES.loadGroup("common");
        RES.loadAllGroup()
        console.log("通用资源加载完成")
        // h5环境时，隐藏加载中
        if (FYGE.getEnv() == "web" && document.getElementById("__loading__")) document.getElementById("__loading__").style.display = "none";

        console.log('getGlobalData')
        // await Tools.getGlobalData()

        // const baseSuccess = await Tools.getActivityBaseInfo();
        // if (!baseSuccess) {
        //     showToast("获取活动信息失败");
        //     return;
        // }

        // const gameSuccess = await Tools.getGameInfo();
        // if (!gameSuccess) {
        //     showToast("获取游戏信息失败");
        //     return;
        // }

        // await Promise.all([
        //     sendTbNet(TbNetName.doIndex)
        // ])
        
        // 初始化
        GameDiffConfig.initGameDiff(Tools.PAGE.GameConfig)
        changeScene(LevonoGameScene, {
            ...Tools.PAGE
        });
    }
}

if (!String.prototype.repeat) {
    String.prototype.repeat = function (count) {
        const str = '' + this;
        count = (count >> 0);
        const t = (count > 1 ? this.repeat(str, count / 2) : '');
        return t + (count % 2 ? t + str : t);
    }
}
