interface ViewCreator {
	new (): UIBaseComponent
}

interface ViewFunc<T extends UIBaseComponent> {
	(uiView: T, node: eui.UILayer): void
}

/**
 * UI根节点
 */
class UIController extends eui.UILayer {
	private static _instance: UIController;
	static get instance(): UIController {
		if (!this._instance) {
			this._instance = new UIController();
		}
		return this._instance
	};
	/**最底层UI */
	private _innerLayer: eui.UILayer;

	/** 最底层UI */
	public get innerLayer(): eui.UILayer { return this._innerLayer; }

	private _alertLayer: eui.UILayer;
	/** 提示层 */
	public get alertLayer(): eui.UILayer { return this._alertLayer; }

	private _popupLayer: eui.UILayer;
	/** 提示层 */
	public get popupLayer(): eui.UILayer { return this._popupLayer; }

	private _mainLayer: eui.UILayer;
	/** 主要ui层 */
	public get mainLayer(): eui.UILayer { return this._mainLayer; }

	private _barLayer: eui.UILayer;
	/** 栏目ui层 */
	public get barLayer(): eui.UILayer { return this._barLayer; }

	private constructor() {
		super();
		//注入自定义的素材解析器
		egret.registerImplementation("eui.IAssetAdapter", new AssetAdapter());
		egret.registerImplementation("eui.IThemeAdapter", new ThemeAdapter());
		this._innerLayer = new eui.UILayer();
		this._innerLayer.touchChildren = true;
		this._alertLayer = new eui.UILayer();
		this._alertLayer.touchThrough = true;
		this._popupLayer = new eui.UILayer();
		this._popupLayer.touchThrough = true;
		this._barLayer = new eui.UILayer();
		this._barLayer.touchThrough = true;
		this._mainLayer = new eui.UILayer();
		this.addChild(this._innerLayer);
		this.addChild(this._mainLayer);
		this.addChild(this._barLayer);
		this.addChild(this._alertLayer);
		this.addChild(this._popupLayer);
	}

	protected createChildren(): void {
		super.createChildren();
	}
	/**
	 * @param {ViewCreator} view UI类
	 * @param {ViewFunc} func 方法回调，对UI类或UI根节点UIController进行处理，传入参数1为UI实例对象，参数2为主UI节点实例
	 * @returns {UIBaseComponent} 返回处理后的UI实例对象
	 * 创建UI并添加到主UI节点下，随后调用传入的方法对UI进行处理
	 */
	createInnerView<T extends UIBaseComponent>(ctor: ViewCreator, func?: ViewFunc<T>): T {
		let view = new ctor();
		this._innerLayer.addChild(view);
		if (func) {
			func(<T>view, this._innerLayer);
		}
		return <T>view;
	}

	/**
	 * @param {ViewCreator} view UI类
	 * @param {ViewFunc} func 方法回调，对UI类或UI根节点UIController进行处理，传入参数1为UI实例对象，参数2为主UI节点实例
	 * @returns {UIBaseComponent} 返回处理后的UI实例对象
	 * 创建UI并添加到主UI节点下，随后调用传入的方法对UI进行处理
	 */
	createView<T extends UIBaseComponent>(ctor: ViewCreator, func?: ViewFunc<T>): T {
		let view = new ctor();
		this._mainLayer.addChild(view);
		if (func) {
			func(<T>view, this._mainLayer);
		}
		return <T>view;
	}

	/**
	 * @param {ViewCreator} view UI类
	 * @param {ViewFunc} func 方法回调，对UI类或UI根节点UIController进行处理，传入参数1为UI实例对象，参数2为主UI节点实例
	 * @returns {UIBaseComponent} 返回处理后的UI实例对象
	 * 创建UI并添加到栏目UI节点下，随后调用传入的方法对UI进行处理
	 */
	createBarView<T extends UIBaseComponent>(ctor: ViewCreator, func?: ViewFunc<T>): T {
		let view = new ctor();
		this._barLayer.addChild(view);
		if (func) {
			func(<T>view, this._barLayer);
		}
		return <T>view;
	}

	/**
	 * @param {ViewCreator} view UI类
	 * @param {ViewFunc} func 方法回调，对UI类或UI根节点UIController进行处理，传入参数1为UI实例对象，参数2为提示UI节点实例
	 * @returns {UIBaseComponent} 返回处理后的UI实例对象
	 * 创建UI并添加到提示UI节点下，随后调用传入的方法对UI进行处理
	 */
	alertView<T extends UIBaseComponent>(ctor: ViewCreator, func?: ViewFunc<T>): T {
		let view = new ctor();
		this.alertLayer.addChild(view);
		if (func) {
			func(<T>view, this.alertLayer);
		}
		return <T>view;
	}

	/**
	 * @param {ViewCreator} view UI类
	 * @param {ViewFunc} func 方法回调，对UI类或UI根节点UIController进行处理，传入参数1为UI实例对象，参数2为提示UI节点实例
	 * @returns {UIBaseComponent} 返回处理后的UI实例对象
	 * 创建UI并添加到提示UI节点下，随后调用传入的方法对UI进行处理
	 */
	popupView<T extends UIBaseComponent>(ctor: ViewCreator, func?: ViewFunc<T>): T {
		let view = new ctor();
		this.popupLayer.addChild(view);
		if (func) {
			func(<T>view, this.popupLayer);
		}
		return <T>view;
	}

	/**
	 * 关闭界面
	 */
	closeView(view: UIBaseComponent): void {
		view.onClose();
		view.parent && view.parent.removeChild(view);
	}

}