import GameComponent from "../Game/GameComponent";
import GameObject from "../Game/GameObject";
import PhycicsSystem from "./PhycicsSystem";
import Physics from "./Physics";
import { DataMgr } from "../Mgr/DataMgr";

export default abstract class Collider extends GameComponent {
    public physics: Physics = null;
    private _group: ColliderGroup = null;
    set group(group: ColliderGroup) {
        if (this._group == null) {
            this._group = group;
            DataMgr.game._phycicsSystem.addCollider(this);
        } else {
            this._group = group;
        }
    }
    get group() {
        return this._group;
    }
    public type: ColliderType = null;
    setData(...ags: any[]): void {
        this.physics && this.physics.onColliderResize(this);
    }

    onEnabled() {
        //自动设置物理组件
        if (this.group)
            DataMgr.game._phycicsSystem.addCollider(this);
        let physics = this.owner.getComponent<Physics>(Physics);
        if (physics) {
            this.physics = physics;
            physics.collider = this;
        }
    }

    protected worldPos: engine.Point = new engine.Point();

    abstract getWorldPosition(out: number[]): void;

    onDisabled() {
        DataMgr.game._phycicsSystem.removeCollider(this);
    }

    /**获取碰撞器的中心的节点坐标 */
    abstract getCenter(): number[];
}

export class CircleCollider extends Collider {
    public radius: number = 0
    public center: number[] = []
    constructor(owner: GameObject) {
        super(owner);
        this.type = ColliderType.Circle;
    }

    setData(x: number, y: number, radius: number) {
        this.radius = radius;
        this.center[0] = x;
        this.center[1] = y;
        super.setData();
    }

    getCenter() {
        return this.center;
    }

    private t = {
        x: 0,
        y: 0
    };
    getWorldPosition(out: number[]) {
        out[0] = this.owner.x + this.center[0];
        out[1] = this.owner.y + this.center[1];
    }
}

export class RectCollider extends Collider {
    public rect: engine.Rectangle = new engine.Rectangle();

    constructor(owner: GameObject) {
        super(owner);
        this.type = ColliderType.Rect;
    }

    setData(x: number, y: number, width: number, height: number) {
        this.rect.x = x;
        this.rect.y = y;
        this.rect.width = width;
        this.rect.height = height;
        super.setData();
    }

    getCenter() {
        return [this.rect.x + this.rect.width / 2, this.rect.y + this.rect.height / 2];
    }
    getWorldPosition(out: number[]) {
        out[0] = this.owner.x + this.rect.left;
        out[1] = this.owner.y + this.rect.top;
    }
}

export class PointCollider extends Collider {
    public center: number[] = [];
    constructor(owner: GameObject) {
        super(owner);
        this.type = ColliderType.Point;
    }

    setData(x: number, y: number) {
        this.center[0] = x;
        this.center[1] = y;
        super.setData();
    }

    getCenter() {
        return this.center;
    }

    getWorldPosition(out: number[]) {
        let owner = this.owner;
        out[0] = this.owner.x + this.center[0];
        out[1] = this.owner.y + this.center[1];
    }
}

export enum ColliderGroup {
    None = 0,
    Ball = 1,
    Bullet = 2,
    Wall = 3,
    Ground = 4,
    Drop = 5,
    Car = 6,
    Top = 7
}

export enum ColliderType {
    Circle = 0,
    Rect = 1,
    Point = 2
}
