
const { ccclass, property } = cc._decorator;
@ccclass
/**
 * UI管理类
 * @author 冯聪
 */
export default class UISystem extends cc.Component {

    /** panel父节点 */
    private panelParent: cc.Node = null;
    /** 是否正在打开界面 */
    private isPanelOpening: boolean = false;
    /** 是否界面正在关闭 */
    private isPanelClosing: boolean = false;
    /** 当前打开的UIPanel */
    private curOnPanelDic: { [key: string]: cc.Node } = {};
    /** 上一个打开的界面名称 */
    private lastOpenPanelName: string = "";

    onLoad() {
        mk.ui = this;
    }

    start() {
        if (!this.panelParent) {
            this.panelParent = this.node;
        }
    }

    /**
     * 打开panel界面
     * @param panelUrl  界面名称全路径
     * @param openAction 打开之后的操(需不需要关闭其他界面)
     */
    openPanel(panelUrl: string, openAction: OpenActionType = OpenActionType.normal): Promise<any> {
        let arr = panelUrl.split("/");
        let panelName = arr[arr.length - 1];

        let self = this;
        if (self.isPanelOpening || self.getCurOnPanel(panelName)) {
            return;
        }

        self.isPanelOpening = true;

        return new Promise((resolve, reject) => {

            mk.loader.load(`${panelUrl}`, cc.Prefab)
                .then((prefab) => {

                    self.isPanelOpening = false;
                    let node_panel = cc.instantiate(prefab);
                    self.curOnPanelDic[panelName] = node_panel;

                    if (self.panelParent) {
                        self.panelParent = self.node;
                    }

                    //如果父节点不存在，就默认把该节点定为panel的父节点
                    if (!self.panelParent) {
                        console.error("[UISystem] UI的父节点panelParent为null,请检查脚本挂载情况");
                        return;
                    }

                    self.panelParent.addChild(node_panel);

                    switch (openAction) {
                        case OpenActionType.normal:
                            break;
                        case OpenActionType.closeLast:
                            if (self.lastOpenPanelName) {
                                self.closePanel(self.lastOpenPanelName);
                            }
                            break;
                        case OpenActionType.closeOther:
                            let keys = Object.keys(self.curOnPanelDic).filter((key) => { key != panelName });
                            for (var i = 0; i < keys.length; i++) {
                                let key = keys[i];
                                self.closePanel(key);
                            }
                            break;
                    }

                    self.lastOpenPanelName = panelName;

                    //返回panel
                    resolve(node_panel);
                })
                .catch((err) => {
                    self.isPanelOpening = false;
                    reject(err);
                })
        });
    }

    /**
     * 获取当前打开的panel界面
     * @param panelName 界面名称
     */
    getCurOnPanel(panelName: string): cc.Node {
        return this.curOnPanelDic[panelName];
    }

    /**
     * 关闭panel界面
     * @param panelName 界面名称
     * @param callBack  关闭之后回调
     */
    closePanel(panelName: string, callBack: Function = null) {
        if (this.isPanelClosing || !this.getCurOnPanel(panelName)) {
            return;
        }
        this.isPanelClosing = true;

        let node_panel = this.getCurOnPanel(panelName);

        // 是否存在关闭动画
        let comp_anim = node_panel.getComponent('EffectOpenAndClose');
        if (comp_anim) {
            comp_anim.hideEffect(this.destroyNode.bind(this, node_panel, panelName, callBack));
        } else {
            this.destroyNode(node_panel, panelName, callBack);
        }
    }

    private destroyNode(node_panel, panelName, callBack) {
        node_panel.destroy();
        delete this.curOnPanelDic[panelName];
        this.isPanelClosing = false;
        callBack && callBack();
    }
}

/** 界面打开操作 */
export enum OpenActionType {
    /** 普通不操作 */
    normal = 0,
    /** 关闭其他 */
    closeOther = 1,
    /** 关闭上一个 */
    closeLast = 2
}