/**
 * Created by rockyl on 2018/11/5.
 */

import HashObject from "./HashObject";
import {Entity, } from "./Entity";
import {EngineConfig} from "../engine-config";

const interactiveMap = [
	'_dealGlobalTouchBegin',
	'_dealGlobalTouchMove',
	'_dealGlobalTouchEnd',
];

/**
 * 组件基类
 */
export class ScillaComponent extends HashObject {
	/**
	 * 所依附的实体
	 */
	entity: Entity;
	protected delayCallbacks = [];
	private _firstUpdate: boolean;

	//是否有效
	protected _enabled: boolean = EngineConfig.componentEnabled;

	/**
	 * 是否有效状态
	 */
	get enabled(): boolean {
		return this._enabled;
	}

	set enabled(value: boolean) {
		if (this._enabled !== value) {
			this._enabled = value;
			if (this.entity && this.entity.isActive) {
				if (this._enabled) {
					this.onEnable();
				} else {
					this.onDisable();
				}
			}
		}
	}

	/**
	 * 装配实体
	 * @param entity
	 */
	_setup(entity: Entity) {
		this.entity = entity;
		this.onCreate();
	}

	/**
	 * 卸载实体
	 */
	_unSetup() {
		this.entity = null;
		this.onDestroy();
	}

	/**
	 * 当组件被创建时
	 */
	onCreate() {

	}

	/**
	 * 当组件被唤醒时
	 */
	onAwake() {
		this._firstUpdate = true;
	}

	/**
	 * 当组件生效时
	 */
	onEnable(){

	}

	/**
	 * 当组件失效时
	 */
	onDisable(){

	}

	$onUpdate(t) {
		this.onUpdate(t);

		if(!this._firstUpdate){
			this.invokeDelayCallback(t);
		}
		this._firstUpdate = false;
	}

	private invokeDelayCallback(t){
		const removed = [];
		if(this.entity.name.indexOf('progress') >= 0){
			console.log();
		}
		for (let i = 0, li = this.delayCallbacks.length; i < li; i++) {
			let {callback, once} = this.delayCallbacks[i];
			if(once){
				removed.push(i);
			}
			callback.call(this, t);
		}
		for(let item of removed){
			this.delayCallbacks.splice(item, 1);
		}
	}

	/**
	 * 当时钟更新时
	 * @param t 从引擎开始到当前的毫秒数
	 */
	onUpdate(t) {

	}

	/**
	 * 当子节点的时钟更新结束后
	 */
	afterUpdate() {

	}

	/**
	 * 当组件沉睡时
	 */
	onSleep() {

	}

	/**
	 * 当组件被销毁时
	 */
	onDestroy() {

	}

	/**
	 * 当被监听的属性被修改时
	 * @param value
	 * @param key
	 * @param oldValue
	 */
	protected onModify(value, key, oldValue){

	}

	private getDelayCallback(callback){
		let result;
		for(let item of this.delayCallbacks){
			if(item.callback == callback){
				result = item;
				break;
			}
		}
		return result;
	}

	/**
	 * 执行延迟回调
	 * @param callback
	 * @param once 是否只执行一次
	 */
	callOnNextTick(callback, once = true) {
		const item = this.getDelayCallback(callback);
		if (!item) {
			this.delayCallbacks.push({callback, once});
		}
	}

	cancelOnNextTick(callback){
		const item = this.getDelayCallback(callback);
		const index = this.delayCallbacks.indexOf(item);
		if(index >= 0){
			this.delayCallbacks.splice(index, 1);
		}
	}

	/**
	 * 当交互时
	 * @param type
	 * @param event
	 */
	onInteract(type, event) {
		try {
			const hitOn = this[interactiveMap[type]](event);
			return hitOn && this['touchInterrupt'];
		} catch (e) {
			console.warn(e);
		}
	}

	_dealGlobalTouchBegin(e) {
		return this.onGlobalTouchBegin(e);
	}

	_dealGlobalTouchMove(e) {
		return this.onGlobalTouchMove(e);
	}

	_dealGlobalTouchEnd(e) {
		return this.onGlobalTouchEnd(e);
	}

	/**
	 * 当全局触摸开始
	 * @param e
	 */
	onGlobalTouchBegin(e) {

	}

	/**
	 * 当全触摸移动
	 * @param e
	 */
	onGlobalTouchMove(e) {

	}

	/**
	 * 当全触摸结束
	 * @param e
	 */
	onGlobalTouchEnd(e) {

	}

	get transform(){
		return this.entity.getComponent('components/base/Transform');
	}

	/**
	 * 向下广播
	 * 如果某组件调用后返回true，将结束整条链
	 * @param method 方法名
	 * @param level 深度，默认全部遍历
	 * @param params 参数
	 */
	broadcast(method, level = -1, ...params) {
		this.entity.broadcast(method, level, ...params);
	}

	/**
	 * 向上冒泡
	 * 如果某组件调用后返回true，将结束整条链
	 * @param method 方法名
	 * @param params 参数
	 */
	bubbling(method, ...params) {
		this.entity.bubbling(method, ...params);
	}
}
