import DisplayCollider, { Tag } from "./DisplayCollider";
import { MConst } from "../MConst";
import { Decorator } from "../Decorator/Decorator";
import GameMgr from "../Mgr/GameMgr";
import DebugMgr from "../Mgr/DebugMgr";

export default abstract class GameObject extends DisplayCollider {
    /**@abstract */
    protected abstract onDraw(): void;
    /**每帧速率的增量。x坐标表示水平方向速率的增量，为标量，单位为像素/帧；y轴同上。 */
    protected acceleration: egret.Point = new egret.Point();

    private timerList: MTimer[] = [];

    constructor(tag: Tag, localRect: egret.Rectangle) {
        super(tag, localRect);
        this.onDraw();
    }

    public moveTo(x: number | egret.Point, y?: number) {
        if (typeof x == "number") {
            if (!y) {
                console.error("invalid param");
                return;
            }

            this.moveTo(new egret.Point(x, y));
        } else {
            let target: egret.Point = x;
            let bottomY = this.y + this.height;
            let curBottomcPos = new egret.Point(this.x, bottomY);
            let bottomTarget = new egret.Point(target.x, target.y + this.height);
            if (bottomTarget.y == bottomY) { //防止下面的除零异常
                this.x = target.x;
                return;
            }

            let groundLine = GameMgr.instance.groundLineInWorld;
            let targetBottomToGroundLine = groundLine - bottomTarget.y;
            let displace = bottomTarget.subtract(curBottomcPos);
            if (displace.y >= 0 && targetBottomToGroundLine <= 0) {
                let ratio = (groundLine - bottomY) / (bottomTarget.y - bottomY);
                displace.x *= ratio;
                displace.y *= ratio;
                bottomTarget = curBottomcPos.add(displace);
                this.x = bottomTarget.x;
                this.y = bottomTarget.y - this.height;
            } else {
                this.x = target.x;
                this.y = target.y;
            }
        }
    }

    public land(x: number, y: number = 0) {
        this.x = x;
        this.y = (GameMgr.instance.groundLineInWorld - this.height) + y;
    }

    public get position() {
        return new egret.Point(this.x, this.y);
    }

    /**速度 单位：像素/帧 */
    public get velocity() {
        return this._velocity;
    }
    public set velocity(v: egret.Point) {
        this._velocity = v;
    }
    private _velocity: egret.Point = new egret.Point();

    /**@override */
    onUpdate() {
        super.onUpdate();
        this.velocity.x += this.acceleration.x;
        this.velocity.y += this.acceleration.y;
        if (this.velocity.length > 0) {
            this.moveTo(this.position.add(this.velocity));
        }
    }

    /**@override */
    onDestroy() {
        super.onDestroy();
        egret.Tween.removeTweens(this);
        this.timerList.forEach(e => e.destroy());
        this.timerList = null;
    }

    public setTimer(time: number, onTimeOut: () => void, repeat?: number, onRepeated?: () => void): MTimer {
        let timer = new MTimer(time, onTimeOut, repeat, () => {
            onRepeated && onRepeated();
            //执行完毕，在列表中删除自身
            this.timerList.splice(this.timerList.indexOf(timer), 1);
        });
        this.timerList.push(timer);
        return timer;
    }

    public delay(time: number): Promise<void> {
        return new Promise<void>(resolve => {
            this.setTimer(time, () => {
                resolve();
            });
        });
    }
}

export class MTimer {
    private timer: egret.Timer = null;

    constructor(time: number, onTimeOut: () => void, repeat?: number, onRepeated?: () => void) {
        //创建一个计时器对象
        let timer: egret.Timer = new egret.Timer(time, repeat || 1);
        //注册事件侦听器
        timer.addEventListener(egret.TimerEvent.TIMER, onTimeOut, this);
        timer.addEventListener(egret.TimerEvent.TIMER_COMPLETE, onRepeated || (() => { }), this);
        //开始计时
        timer.start();
        this.timer = timer;
    }

    stop() {
        this.timer.stop();
    }

    destroy() {
        this.stop();
        this.timer = null;
    }
}