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

import {Matrix, ScillaComponent, decorators} from "scilla";
import Renderer from "../renderer/Renderer";

const {dirtyFieldTrigger} = decorators;

/**
 * 可交互组件
 */
export default class InteractComponent extends ScillaComponent {
	/**
	 * 是否可交互
	 */
	@dirtyFieldTrigger
	interactable = true;

	/**
	 * 触摸中断
	 */
	touchInterrupt: boolean = false;

	protected invertMatrix = Matrix.create();
	protected localPos: any = {};
	protected isOut = true;

	private _touchBeginFlag: boolean;

	constructor() {
		super();

	}

	_dealGlobalTouchBegin(e) {
		let interrupt = super._dealGlobalTouchBegin(e);

		const hitOn = this.hitTest(e);
		if (hitOn) {
			this._touchBeginFlag = true;
			this.onTouchBegin(e);
			this._dealTouchOver(e);
		}

		return hitOn && interrupt;
	}

	_dealGlobalTouchMove(e) {
		let interrupt = super._dealGlobalTouchMove(e);

		const hitOn = this.hitTest(e);
		if (hitOn) {
			this._dealTouchOver(e);
			this.onTouchMove(e);
		} else {
			this._dealTouchOut(e);
		}

		return hitOn && interrupt;
	}

	_dealGlobalTouchEnd(e) {
		let interrupt = super._dealGlobalTouchEnd(e);

		const hitOn = this.hitTest(e);
		if (hitOn) {
			this.onTouchEnd(e);
			if(this._touchBeginFlag){
				this.onTouchTap(e);
				this._touchBeginFlag = false;
			}
		}

		this.isOut = true;

		return hitOn && interrupt;
	}

	_dealTouchOver(e) {
		if (this.isOut) {
			this.isOut = false;
			this.onTouchOver(e);
		}
	}

	_dealTouchOut(e) {
		if (!this.isOut) {
			this.isOut = true;
			this.onTouchOut(e);
		}
	}

	onTouchBegin(e) {
		//console.log('onTouchBegin', e);
	}

	onTouchMove(e) {
		//console.log('onTouchMove', e);
	}

	onTouchOver(e) {
		//console.log('onTouchOver', e);
	}

	onTouchOut(e) {
		//console.log('onTouchOut', e);
	}

	onTouchEnd(e) {
		//console.log('onTouchEnd', e);
	}

	onTouchTap(e) {
		//console.log('onTouchTap', e);
	}

	/**
	 * 碰撞检测
	 * @param e
	 */
	hitTest(e) {
		const matrix = this.transform.getMatrix();
		const invertMatrix = this.invertMatrix;
		invertMatrix.copyFrom(matrix);
		invertMatrix.invert();
		invertMatrix.transformPoint(e.x, e.y, this.localPos);

		let result = false;
		const renderers = this.entity.getComponents(Renderer);
		for (let renderer of renderers) {
			if (renderer.hitTest(this.localPos.x, this.localPos.y)) {
				if (renderer.isUsedToMask) {
					continue
				} else {
					result = true;
					break
				}
			} else if (renderer.isUsedToMask) {
				return false
			}
		}

		return result;
	}
}
