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, 121);
        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() {
        this.playFireEffect();
        SoundMgr.instance.playEffect("shoot_mp3");
        let column = this.context.fireBulletNumConfig[this.fireBulletNumConfigIndex];
        this.fireBulletNumConfigIndex = this.fireBulletNumConfigIndex == 0 ? 1 : 0; //0/1交替

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

    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 playFireEffect() {
        this.imgParticel.alpha = 1;
        this.imgGun.scaleY = 0.8;
        egret.Tween.removeTweens(this.imgParticel);
        egret.Tween.removeTweens(this.imgGun);
        egret.Tween.get(this.imgParticel).to({ alpha: 0 }, 100);
        egret.Tween.get(this.imgGun).to({ scaleY: 1 }, 100);
    }

    /**帧时间回调 */
    private onEnterFrame() {
        if (GameMgr.instance.pause) return;

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

        this.fireTimer += 1;

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

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