import GameObject from "./GameObject";
import { Decorator } from "../Decorator/Decorator";
import ParticleMgr from "../Mgr/ParticleMgr";
import MainScene from "../Scene/MainScene";
import { MUtils } from "../Global/MUtils";
import { getBallScore } from "../Global/GUtils";
import DebugMgr from "../Mgr/DebugMgr";
import Collider, { RectCollider, ColliderGroup } from "./Collider";
import { MConst } from "../Global/MConst";
import Bullet from "./Bullet";
import MTweenMgr from "../MComponents/MTween";
import GameMgr from "../Mgr/GameMgr";
import SoundMgr from "../Mgr/SoundMgr";
import MTimer from "../MComponents/MTimer";

@Decorator.OnDestroy
export default class Car extends GameObject implements Decorator.IDefaultCallback {
    private imgGun: egret.Bitmap = null;
    private imgParticel: egret.Bitmap = null;
    private fireTimer: number = null;
    private fireBulletNumConfigIndex: 0 | 1 = 0;
    public touchWall: 1 | -1 | 0 = 0;

    private invincibleDuration = 0;

    constructor(context: MainScene) {
        super(context);
        this.x = 124;
        this.y = 145;
        this.createPart("car_shadow_png", 4.96, 138.69);
        this.createPart("car_part_0_png", 12.5, 102.5);
        this.imgGun = this.createPart("car_gun_png", 33.5, 120);
        this.createPart("car_wheel_png", 0, 97.5);
        this.imgParticel = this.createPart("car_particle_png", 15.98, 1.33);
        // this.imgParticel.alpha = 0;
        this.imgGun.anchorOffsetY = 100;

        this.addEventListener(egret.Event.ENTER_FRAME, this.onEnterFrame, this);

        let collider = this.addComponent<RectCollider>(RectCollider);
        collider.setData(29, 20, 63, 150);
        collider.group = ColliderGroup.Car;
    }

    private createPart(source: string, x: number, y: number) {
        let bitmap = new egret.Bitmap(RES.getRes(source) as egret.Texture);
        bitmap.x = x;
        bitmap.y = y;
        this.addChild(bitmap);
        return bitmap;
    }

    private fire() {
        SoundMgr.instance.playEffect("shoot_mp3");
        // let column = this.context.fireBulletNumConfig[this.fireBulletNumConfigIndex];
        // this.fireBulletNumConfigIndex = this.fireBulletNumConfigIndex == 0 ? 1 : 0; //0/1交替
        const column = this.context.fireBulletNumConfig;
        const numb = MConst.BulletDisperseFrameNum;

        let bullets: Bullet[] = [];
        for (let i = 0; i < column; i++) {
            const bullet = this.context.bulletPool.create(this.context).init(Math.floor(this.context.powerScore / 100));
            bullet.posY = this.posY - this.height + 26;
            bullet.posX = this.posX;
            let offsetX = (i - (column - 1) / 2) * MConst.BulletWidth;
            bullet.physics.velocity.x = offsetX / numb;
            /* MTweenMgr.instance.get(bullet).wait(MConst.BulletDisperseFrameNum, true).call(() => {
                bullet.physics.velocity.x = 0;
            }); */
            bullets.push(bullet);
        }

        MTimer.set(numb, () => {
            for (let i of bullets) {
                i.physics.velocity.x = 0;
            }
        });
    }

    onCollisionEnter(other: Collider) {
        if (other.group == ColliderGroup.Ball) {
            if (this.invincibleDuration <= 0) {
                this.die();
            }
        }

        if (other.group == ColliderGroup.Wall) {
            this.touchWall = other.owner.x < 0 ? 1 : -1;

        }
    }

    onCollisionStay(other: Collider) {
        if (other.group == ColliderGroup.Ball) {
            if (this.invincibleDuration <= 0) {
                this.die();
            }
        }

        if (other.group == ColliderGroup.Wall) {
            this.touchWall = other.owner.x < 0 ? 1 : -1;

        }
    }

    private onceBlink() {
        MTweenMgr.instance.get(this)
            .to({ alpha: 0 }, 1, true)
            .wait(2)
            .to({ alpha: 1 }, 1, true)
            .wait(2)
            .call(() => { this.onceBlink(); });
    }

    revive() {
        this.invincibleDuration = MConst.ReviveInvincibleDuration * 1000;
        MTweenMgr.instance.removeTweens(this);
        this.onceBlink();
        MTimer.set(MConst.ReviveInvincibleDuration * 60, () => {
            //无敌结束
            this.alpha = 1;
            MTweenMgr.instance.removeTweens(this);
        });
    }

    move(deltaX: number) {
        if (this.touchWall == 1 && deltaX <= 0) {
            return;
        } else if (this.touchWall == -1 && deltaX >= 0) {
            return;
        }

        this.x += deltaX;
    }

    onCollisionExit(other: Collider) {
        if (other.group == ColliderGroup.Wall) {
            this.touchWall = 0;
        }
    }

    private die() {
        this.context.gameOver();
    }

    private frameTimer = 0;

    private onEnterFrame() {
        if (GameMgr.instance.pause) return;

        if (this.invincibleDuration > 0) {
            this.invincibleDuration -= MTimer.deltaTime;
        }

        this.fireTimer += 1;

        if (this.fireTimer >= 60 / this.context.fireSpeed) {
            this.fire();
            this.fireTimer = 0;
        }

        if (this.frameTimer % 3 == 0) {
            this.imgParticel.visible = !this.imgParticel.visible;
        }
        this.frameTimer++;
    }

    onDestroy() {
        this.removeEventListener(egret.Event.ENTER_FRAME, this.onEnterFrame, this);
        MTweenMgr.instance.removeTweens(this);
    }
}