import { ModuleTypes } from "../types/sceneTypes";
import Panel, { IPanel } from "../views/Panel";
import Loading from "../loading/Loading";

export default class PanelCtrl {
    private _parent: eui.UILayer;
    private _mask: egret.Sprite;

    static _instance: PanelCtrl;

    private _current: Panel;

    private canvasH = 750 / window.innerWidth * window.innerHeight;
    private canvasW = 750 / window.innerWidth * window.innerWidth;

    static get instance() {
        return PanelCtrl._instance || (PanelCtrl._instance = new PanelCtrl())
    }

    public init(parent: eui.UILayer) {
        this._parent = parent;
    }

    private _panelClassMap: any;

    public registerPanelClass(name, definition) {
        this._panelClassMap = this._panelClassMap || {};
        this._panelClassMap[name] = definition;
    }

    public registerPanels(panels) {
        panels.forEach(v => this.registerPanelClass(v[0], v[1]))
    }

    /**
     * 防止连点
     * @param targe 可交互对象
     * @param dtime 延时默认500ms
     */
    public btnDelay(targe: any, dtime: number = 500) {
        targe.touchEnabled = false;
        setTimeout(() => {
            targe.touchEnabled = true;
        }, dtime);
    }

    /**
     * 显示
     * @param type 类型
     * @param data 数据
     */
    public show(type: ModuleTypes | IPanel, data?, mask = true) {
        if (this._current) {
            this._current.destroy();    /// TODO 不知道谁干的，没写这句导致事件清除不完善！自定义事件起冲突
            this.remove(this._current, true);
            this._current = null;
        }
        this._parent.visible = true;
        mask && this.addMask();

        let panel = null;

        // @ts-ignore
        if (ModuleTypes[type]) {
            // @ts-ignore
            panel = new this._panelClassMap[type](data);
        } else {
            // @ts-ignore
            panel = new type(data);
        }

        Loading.instace.show();

        this._current = panel;
        this.add(panel);
        // panel.visible = false;   /// TODO 不知道谁干的，有什么用？
        // panel.onShowAnim(); // 自定义显示动画   /// TODO 2020.12.18 放到 Panel -> onSkinComplete 即皮肤加载完成，此时可以获得弹窗皮肤的宽高，做动画更方便
        return panel;
    }

    /**
     * 加入黑色蒙层
     */
    private addMask() {
        if (!this._mask) {
            this._mask = new egret.Sprite();
            this._mask.touchEnabled = true;
            this._mask.graphics.beginFill(0, .4);
            this._mask.graphics.drawRect(0, 0, this.canvasW, this.canvasH);
            this._mask.graphics.endFill();
        }
        this._mask.alpha = 1;
        this._parent.addChild(this._mask);
    }

    private add(panel: Panel) {
        this._parent.addChild(panel);
        panel.addEventListener('onDestroy', this.onPanelHide, this);
    }

    /**
     * 移除蒙层
     */
    removeMask(rightNow = false) {
        // if (this._mask) {
        //     if (rightNow) {
        //         this._parent.removeChild(this._mask);
        //     } else
        //         egret.Tween.get(this._mask).to({ alpha: 0 }, 300, egret.Ease.quartIn).call(
        //             () => this._parent.removeChild(this._mask), this);
        // }
        this._parent.visible = false;
    }

    private remove(panel: Panel, rightNow = false) {
        if (rightNow) {
            this._parent.removeChild(panel);
            this.removeMask(rightNow);
            return;
        }

        panel.onHide().call(() => {
            this._parent.removeChild(panel);
            this.removeMask();
        });
        // /// TODO 改造自定义移除动画
        // const tw = egret.Tween.get(panel);
        // tw.to({ y: this.canvasH }, 300, egret.Ease.quartIn)
        //     .call(() => {
        //         this._parent.removeChild(panel);
        //         this.removeMask();
        //     }, this);
    }

    public removeCurrent() {
        this._current && this._parent.removeChild(this._current) && (this._current = null);
        this._mask && this.removeMask(true);
    }

    /**
     * 隐藏Panel
     * @param e
     */
    private onPanelHide(e: egret.Event) {
        const panel = e.target as Panel;
        panel.removeEventListener('onDestroy', this.onPanelHide, this);
        this.remove(panel);
        this._current = null;
    }
}
