/**
 * 当初始化组件时。
 * @callback OnInitComponentCallback
 * @public
 */

/**
 * 当加载资源时。
 * @callback OnLoadResourceComponentCallback
 * @public
 */

/**
 * 当卸载资源时。
 * @callback OnUnloadResourceComponentCallback
 * @public
 */

/**
 * 当更新组件时。
 * @callback OnUpdateComponentCallback
 * @param {number} deltaTime 以秒为单位的时间增量。
 * @public
 */

/**
 * 获取中心位置。
 * @callback GetCenterFunction
 * @param {Array<number>} target 用于保存结果的目标数组。
 * @returns {Array<number>} 目标数组的引用。
 * @public
 */

/**
 * 将自身位置转换为世界位置。
 * @callback SelfToWorldFunction
 * @param {Array<number>} position 世界位置。
 * @param {boolean} ignoreScale 为true表示忽略缩放。
 * @param {Array<number>} target 用于保存结果的目标数组。
 * @returns {Array<number>} 目标数组的引用。
 * @public
 */

/**
 * 将世界位置转换为屏幕位置。
 * @callback WorldToScreenFunction
 * @param {Array<number>} position 世界位置。
 * @param {Array<number>} target 用于保存结果的目标数组。
 * @returns {Array<number>} 目标数组的引用。
 * @public
 */

/**
 * @typedef {object} RenderLayout
 * @property {GetCenterFunction} getCenter
 * @property {SelfToWorldFunction} selfToWorld
 * @property {WorldToScreenFunction} worldToScreen
 * @private
 */

/**
 * 当渲染组件时。
 * @callback OnRenderComponentCallback
 * @param {RenderLayout} layout 布局信息
 * @public
 */

/**
 * 当父对象改变时。
 * @callback OnParentChangeComponentCallback
 * @param {THING.BaseObject} parent 新的父对象。
 * @public
 */

/**
 * 当组件调整大小时。
 * @callback OnResizeComponentCallback
 * @param {number} width 以像素为单位的宽度。
 * @param {number} height 以像素为单位的高度。
 * @public
 */

/**
 * 当刷新组件时。
 * @callback OnRefreshComponentCallback
 * @public
 */

/**
 * 当活动状态改变时。
 * @callback OnActiveChangeComponentCallback
 * @param {boolean} value 活动状态。
 * @public
 */

/**
 * 当(主体)可见性改变时。
 * @callback OnVisibleChangeComponentCallback
 * @param {boolean} value 可见状态。
 * @public
 */

/**
 * 当复制组件时。
 * @callback OnCopyComponentCallback
 * @param {THING.BaseComponent} component 组件。
 * @public
 */

/**
 * 当添加子对象时。
 * @callback OnAddChildComponentCallback
 * @param {THING.BaseObject} object 子对象。
 * @public
 */

/**
 * 当移除子对象时。
 * @callback OnRemoveChildComponentCallback
 * @param {THING.BaseObject} object 子对象。
 * @public
 */

/**
 * 当添加组件之前。
 * @callback OnBeforeAddComponentCallback
 * @param {THING.BaseObject} object 子对象。
 * @public
 */

/**
 * 当添加组件之后。
 * @callback OnAfterAddComponentCallback
 * @public
 */

/**
 * 当移除组件之前。
 * @callback OnBeforeRemoveComponentCallback
 * @public
 */

/**
 * 当移除组件之后。
 * @callback OnAfterRemoveComponentCallback
 * @public
 */

/**
 * 当导入数据时。
 * @callback OnImportComponentCallback
 * @param {object} param 参数。
 * @public
 */

/**
 * 当导出数据时。
 * @callback OnExportComponentCallback
 * @returns {object}
 * @public
 */

/**
 * @class BaseComponent
 * 基础组件。
 * @memberof THING
 * @public
 */
class BaseComponent {

	/**
	 * 所有组件的基础组件,每个组件都应该继承自它。
	 */
	constructor() {
		/**
		 * 检查是否为实例化组件,true 表示在注册组件时自动创建它。
		 * @member {boolean} isInstancedComponent
		 * @memberof THING.BaseComponent
		 * @instance
		 * @static
		 * @private
		 */

		// #region Overrides

		/**
		 * 初始化时的回调函数。
		 * @member {OnInitComponentCallback} onInit
		 * @memberof THING.BaseComponent
		 * @instance
		 * @public
		 */

		/**
		 * 加载资源时的回调函数。
		 * @member {OnLoadResourceComponentCallback} onLoadResource
		 * @memberof THING.BaseComponent
		 * @instance
		 * @public
		 */

		/**
		 * 卸载资源时的回调函数。
		 * @member {OnUnloadResourceComponentCallback} onUnloadResource
		 * @memberof THING.BaseComponent
		 * @instance
		 * @public
		 */

		/**
		 * 更新时的回调函数。
		 * @member {OnUpdateComponentCallback} onUpdate
		 * @memberof THING.BaseComponent
		 * @instance
		 * @public
		 */

		/**
		 * 渲染时的回调函数。
		 * @member {OnRenderComponentCallback} onRender
		 * @memberof THING.BaseComponent
		 * @instance
		 * @private
		 */

		/**
		 * 改变父对象时的回调函数。
		 * @member {OnParentChangeComponentCallback} onParentChange
		 * @memberof THING.BaseComponent
		 * @instance
		 * @public
		 */

		/**
		 * 调整大小时的回调函数。
		 * @member {OnResizeComponentCallback} onResize
		 * @memberof THING.BaseComponent
		 * @instance
		 * @public
		 */

		/**
		 * 刷新时的回调函数。
		 * @member {OnRefreshComponentCallback} onRefresh
		 * @memberof THING.BaseComponent
		 * @instance
		 * @public
		 */

		/**
		 * 活动状态改变时的回调函数。
		 * @member {OnActiveChangeComponentCallback} onActiveChange
		 * @memberof THING.BaseComponent
		 * @instance
		 * @public
		 */

		/**
		 * 可见性改变时的回调函数。
		 * @member {OnVisibleChangeComponentCallback} onVisibleChange
		 * @memberof THING.BaseComponent
		 * @instance
		 * @public
		 */

		/**
		 * 复制时的回调函数。
		 * @member {OnCopyComponentCallback} onCopy
		 * @memberof THING.BaseComponent
		 * @instance
		 * @public
		 */

		/**
		 * 添加子对象之前的回调函数。
		 * @member {OnAddChildComponentCallback} onBeforeAddChild
		 * @memberof THING.BaseComponent
		 * @instance
		 * @public
		 */

		/**
		 * 添加子对象之后的回调函数。
		 * @member {OnAddChildComponentCallback} onAfterAddChild
		 * @memberof THING.BaseComponent
		 * @instance
		 * @public
		 */

		/**
		 * 移除子对象之前的回调函数。
		 * @member {OnRemoveChildComponentCallback} onBeforeRemoveChild
		 * @memberof THING.BaseComponent
		 * @instance
		 * @public
		 */

		/**
		 * 移除子对象之后的回调函数。
		 * @member {OnRemoveChildComponentCallback} onAfterRemoveChild
		 * @memberof THING.BaseComponent
		 * @instance
		 * @public
		 */

		/**
		 * 添加之前。
		 * @member {OnBeforeAddComponentCallback} onBeforeAdd
		 * @memberof THING.BaseComponent
		 * @instance
		 * @public
		 */

		/**
		 * 添加之后。
		 * @member {OnAfterAddComponentCallback} onAfterAdd
		 * @memberof THING.BaseComponent
		 * @instance
		 * @public
		 */

		/**
		 * 移除之前。
		 * @member {OnBeforeRemoveComponentCallback} onBeforeRemove
		 * @memberof THING.BaseComponent
		 * @instance
		 * @public
		 */

		/**
		 * 移除之后。
		 * @member {OnAfterRemoveComponentCallback} onAfterRemove
		 * @memberof THING.BaseComponent
		 * @instance
		 * @public
		 */

		/**
		 * 导入数据时。
		 * @member {OnImportComponentCallback} onImport
		 * @memberof THING.BaseComponent
		 * @instance
		 * @public
		 */

		/**
		 * 导出数据时。
		 * @member {OnExportComponentCallback} onExport
		 * @memberof THING.BaseComponent
		 * @instance
		 * @public
		 */

		// #endregion

		this._object = null;
		this._active = true;
	}

	// #region BaseComponent Interface

	/**
	 * 当添加组件时。
	 * @param {THING.BaseObject} object 对象。
	 * @public
	 */
	onAdd(object) {
		this.triggerBeforeAddCallback(object);
		this._object = object;
		this.triggerAfterAddCallback();
	}

	triggerBeforeAddCallback() {
		if (this.onBeforeAdd) {
			this.onBeforeAdd();
		}
	}

	triggerAfterAddCallback() {
		if (this.onAfterAdd) {
			this.onAfterAdd();
		}
	}

	/**
	 * 当移除组件时。
	 * @public
	 */
	onRemove() {
		this.triggerBeforeRemoveCallback();
		let object = this._object;
		this._object = null;
		this.triggerAfterRemoveCallback(object);
	}

	triggerBeforeRemoveCallback() {
		if (this.onBeforeRemove) {
			this.onBeforeRemove();
		}
	}

	triggerAfterRemoveCallback() {
		if (this.onAfterRemove) {
			this.onAfterRemove();
		}
	}

	// #endregion

	/**
	 * 激活或停用组件。
	 * @type {boolean}
	 * @public
	 */
	get active() {
		return this._active;
	}
	set active(value) {
		if (this._active == value) {
			return;
		}

		this._active = value;

		if (this.onActiveChange) {
			this.onActiveChange(value);
		}
	}

	/**
	 * 获取对象。
	 * @type {THING.BaseObject}
	 * @public
	 */
	get object() {
		return this._object;
	}

	/**
	 * 获取应用程序。
	 * @type {THING.App}
	 * @public
	 */
	get app() {
		let object = this._object;
		if (!object) {
			return null;
		}

		if (object.isApp) {
			return object;
		}
		else {
			return object.app;
		}
	}

}

export { BaseComponent }