
import { _decorator, Component, Node, CCFloat, CCInteger, CCBoolean, Prefab, v3, RigidBody2D, v2, Vec2, toDegree, Collider2D, Contact2DType, IPhysics2DContact, TiledObjectGroup, ParticleSystem2D, instantiate, math, SpriteComponent, AudioSourceComponent, AudioClip, PlaneCollider } from 'cc';
import { PhysicsGroup } from './Constants';
import { GameMgr } from './GameMgr';
import { ObjPool } from './ObjPool';
import { Planet } from './Planet';
const { ccclass, property } = _decorator;

let outPos = v3();
 
@ccclass('Enemy')
export class Enemy extends Component {
    @property({
        type: CCFloat
    })
    health: number = 100;

    @property({
        type: CCFloat
    })
    speed: number = 10;

    @property({
        type: CCInteger
    })
    damage: number = 1;

    @property
    stunned: boolean = false;

    @property({
        type: Prefab
    })
    deathParticleEffect: Prefab;

    rb2d: RigidBody2D;
    velocity: Vec2 = v2();

    isDeath: boolean = false;

    @property({
        type: AudioClip
    })
    audioHited: AudioClip;

    @property({
        type: AudioClip
    })
    audioDeath: AudioClip;

    audioSource: AudioSourceComponent;

    onLoad() {
        this.audioSource = this.getComponent(AudioSourceComponent);
        this.rb2d = this.getComponent(RigidBody2D);
        this.speed *= this.randomRanage(0.9, 1.1);

        this.getComponent(Collider2D).on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
    }

    onEnable() {
        this.rb2d.wakeUp();
    }

    onBeginContact(selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact) {
        if(otherCollider.group & PhysicsGroup.Planet) {
            otherCollider.node.getComponent(Planet).shake();
            this.die();
        }
        else if(otherCollider.group & PhysicsGroup.Shield) {
            this.die();
        }
    }

    die() {
        this.isDeath = true;
        let particle = instantiate(this.deathParticleEffect);
        particle.parent = this.node.parent;
        particle.setPosition(this.node.position);
        particle.getComponent(ParticleSystem2D).startColor = this.getComponent(SpriteComponent).color;
        this.rb2d.sleep();
        this.scheduleOnce(() => {
            ObjPool.putNode(this.node);
        });
        this.audioSource.clip = this.audioDeath;
        this.audioSource.play();
    }

    takeDamage(damage: number) {
        if(this.isDeath) {
            return;
        }
        
        this.health -= damage;
        if(this.health <= 0) {
            this.die();
        }
        else {
            this.audioSource.clip = this.audioHited;
            this.audioSource.play();
        }
    }

    randomRanage(min: number, max: number) {
        console.assert(max > min);
        return min + Math.random() * (max - min);
    }

    update(dt: number) {
        if(this.isDeath) {
            return;
        }
        let planetPos = GameMgr.inst.planet.position;
        this.velocity.x = planetPos.x - this.node.position.x;
        this.velocity.y = planetPos.y - this.node.position.y;
        this.velocity.multiplyScalar(this.speed / this.velocity.length());
        this.rb2d.linearVelocity = this.velocity;

        this.node.angle = toDegree(Math.atan2(this.velocity.y, this.velocity.x)) - 90;
    }
}
