const { ccclass, property } = cc._decorator;

@ccclass
export default class LongTouchComponent extends cc.Component {
    @property({
        tooltip: "触摸回调间隔(秒)。假如为0.1,那么1秒内会回调10次 ${longTouchEvents} 事件数组"
    })
    touchInterval: number = 0.1;

    @property({
        type: [cc.Component.EventHandler],
        tooltip: "回调事件数组,每间隔 ${toucheInterval}s 回调一次"
    })
    longTouchEvents: cc.Component.EventHandler[] = [];

    /**
     * 触摸计数器,用于统计本次长按的回调次数
     */
    private _touchCounter: number = 0;

    /**
     * 标记当前是否在触摸这个节点
     */
    private _isTouching: boolean = false;

    onEnable() {
        this.node.on(cc.Node.EventType.TOUCH_START, this._onTouchStart, this);
        this.node.on(cc.Node.EventType.TOUCH_END, this._onTouchEnd, this);
        this.node.on(cc.Node.EventType.TOUCH_CANCEL, this._onTouchCancel, this);
    }

    onDisable() {
        this.node.off(cc.Node.EventType.TOUCH_START, this._onTouchStart, this);
        this.node.off(cc.Node.EventType.TOUCH_END, this._onTouchEnd, this);
        this.node.off(cc.Node.EventType.TOUCH_CANCEL, this._onTouchCancel, this);
    }

    private _onTouchStart(event: cc.Event.EventTouch) {
            if (this._isTouching) {
                return;
            }

            if (this.node.getBoundingBoxToWorld().contains(event.getLocation())) {
                this._isTouching = true;
            } else {
                this._isTouching = false;
            }

            if (this._isTouching) {
                // 第一次触摸立即回调一次
                this.publishOneTouch();

                // 然后开启计时器,计算后续的长按相当于触摸了多少次
                this.schedule(this._touchCounterCallback, this.touchInterval);
            }
    }

    private _onTouchEnd(event: cc.Event.EventTouch) {
        this._isTouching = false;
        this._touchCounter = 0;
        this.unschedule(this._touchCounterCallback);
    }

    private _onTouchCancel(event: cc.Event.EventTouch) {
        this._isTouching = false;
        this._touchCounter = 0;
        this.unschedule(this._touchCounterCallback);
    }

    private _touchCounterCallback() {
        if (this._isTouching) {
            this.publishOneTouch();
        } else {
            this.unschedule(this._touchCounterCallback);
        }
    }

    /**
     * 通知出去:被点击/触摸了一次,长按时,会连续多次回调这个方法
     */
    private publishOneTouch() {
        if (!this._isTouching) {
            return;
        }
        this._touchCounter++;
        this.longTouchEvents.forEach((eventHandler: cc.Component.EventHandler) => {
            eventHandler.emit([this._touchCounter]);
        });
    }
}