package;

import flixel.math.FlxPoint;
import flixel.FlxG;
import flixel.FlxSprite;

class Enemy extends FlxSprite {
    // Add your player-specific properties and methods here
    public var enemyType:Int = 1;
    var speed:Float = 47;
    var separationSpeed:Float = 0;  // speed that was used to avoid overlapping with other enemies
    public var target:FlxPoint;

    public var hurting:Float = 0;  // if above 0 just took damage, will not move toward target
    public var hurtTime:Float = 0.4;

    var iHealth:Float = 3;

    public var randomOffTarget:FlxPoint = new FlxPoint(FlxG.random.float(-15, 15), FlxG.random.float(-15, 15));

    public var undead:Bool = false;
    public var dead:Bool = false;

    public var damage:Float = 1;
    public var attackCooldown:Float = 0.0;
    public var attackCooldownMax:Float = 1.0;

    public var timeToResurrect:Float = 0.4;

    public var timeToDecompose:Float = 0.0;
    public var decomposeTime:Float = 12.0;

    var shootTime:Float = 1.0;
    var shootTimeMax:Float = 3.0;

    public var xpGiven:Float = 100;


    public function new(x:Float, y:Float, enemyType:Int = 1) {
        super(x, y);
        
        antialiasing = false;
        this.enemyType = enemyType;


        switch (enemyType) {
            case 1:
                loadGraphic("assets/images/enemy1.png", true, 42, 42);
                animation.add("walk", [0, 1, 2, 3], 16, true);
                animation.add("hurt", [4], 2, false);
                animation.add("stunned", [0], 2, false);
                animation.add("dead", [10], 1, true);
                animation.add("undead_walk", [6, 7, 8, 9], 10, true);
                animation.add("undead_hurt", [11], 2, false);
                animation.add("undead_stunned", [6], 2, false);
                width -= 6;
                height -= 9;
                offset.x = 3;
                offset.y = 3;
            case 2:
                loadGraphic("assets/images/enemy2.png", true, 57, 69);
                animation.add("walk", [4], 1, true);
                animation.add("hurt", [3], 2, false);
                animation.add("stunned", [4], 2, false);
                animation.add("dead", [0], 1, true);
                animation.add("undead_walk", [2], 1, true);
                animation.add("undead_hurt", [1], 2, false);
                animation.add("undead_stunned", [2], 2, false);
                width -= 9;
                height -= 36;
                offset.x += 3;
                offset.y += 33;
                iHealth = 5;
                speed = 35;
                timeToResurrect = 0.65;
                xpGiven = 250;
            case 3:
                loadGraphic("assets/images/enemy3.png", true, 126, 126);
                animation.add("walk", [0, 1, 2, 3], 16, true);
                animation.add("hurt", [4], 2, false);
                animation.add("stunned", [0], 2, false);
                animation.add("dead", [10], 1, true);
                animation.add("undead_walk", [6, 7, 8, 9], 10, true);
                animation.add("undead_hurt", [11], 2, false);
                animation.add("undead_stunned", [6], 2, false);
                width -= 18;
                height -= 27;
                offset.x = 9;
                offset.y = 9;
                iHealth = 18;
                speed = 90;
                damage = 2;
                timeToResurrect = 1.0;
                xpGiven = 600;
        }

        

        
        animation.play("walk");

        target = new FlxPoint(x, y);

        health = iHealth;

        

        drag.x = drag.y = 1000;
    }

    override public function update(elapsed:Float):Void {
        super.update(elapsed);

        if (health <= 0) {
            if (timeToDecompose > 0.0) {
            
                if (timeToDecompose <= 4.0) {
                    alpha = timeToDecompose * 0.25;
                }
                
                timeToDecompose -= FlxG.elapsed;
    
                if (timeToDecompose <= 0.0) {
                    kill();
                    
                }
            }

            return;
        }

        if (undead) {
            if (health > 0) {
                //if (animation.curAnim.name != "undead_walk")
                //trace("play undead_walk 1");
                //animation.play("undead_walk");
                //animation.play("undead_walk");
            }
        }

        

        if (attackCooldown > 0.0) {
            attackCooldown -= FlxG.elapsed;
            
        }

        if (target != null && hurting <= 0.0) {
            moveTowardsTarget();
        }

        if (hurting > 0.0) {
            hurting -= elapsed;
            if (hurting <= 0.0) {
                hurting = 0.0;
                //setColorTransform();
                //drag.x = drag.y = 0.0;
                //blend = "normal";
                if (!undead) {
                    animation.play("walk");
                }
                else {
                    animation.play("undead_walk");
                }
            }
            else {
                //setColorTransform(1.0 + hurting * 3, 1.0 + hurting * 3, 1.0 + hurting * 3);
                //blend = "screen";

                if (hurting >= hurtTime - 0.15) {
                    if (!undead) {
                        animation.play("hurt");
                    }
                    else {
                        animation.play("undead_hurt");
                    }
                }
                else {
                    if (!undead) {
                        animation.play("stunned");
                    }
                    else {
                        animation.play("undead_stunned");
                    }
                }
            }
        }
        
        //if (velocity.x == 0.0 && velocity.y == 0.0) {
        //    x = Math.round(x);
        //    y = Math.round(y);
        //}

        if (enemyType == 2) {
            shootTime -= elapsed;

            if (shootTime <= 0.0) {
                shootTime += shootTimeMax;

                shootBullet();
            }

        }

        separationSpeed = 0;
    }

    public function setTarget(X:Float, Y:Float) {
        target = new FlxPoint(X, Y);
    }
    
    function moveTowardsTarget() {
        velocity.x = target.x - x;
        velocity.y = target.y - y;
    
        //animation.play("run");
        //animation.curAnim.frameRate = 9;
    
    
        if (velocity.lengthSquared > (speed - separationSpeed) * (speed - separationSpeed))
            velocity.length = (speed - separationSpeed);
        else {
            if (velocity.lengthSquared < 25) {
                //target = null;
                velocity.set(0.0, 0.0);
                //animation.play("idle");
                return;
            }
            else {
                //animation.curAnim.frameRate = 60 * (velocity.length / speed);
                //if (animation.curAnim.frameRate > 9)
                    //animation.curAnim.frameRate = 9;
            }
        }
    
        velocity.set(velocity.x, velocity.y);
    
        if (velocity.x < 0) {
            setFlipX(true);
        }
        else if (velocity.x > 0) {
            setFlipX(false);
        }
    }

    public function moveAwayFromPoint(enemyX:Float, enemyY:Float, distance:Float) {
        var dx:Float = this.x - enemyX;
        var dy:Float = this.y - enemyY;

        var length:Float = Math.sqrt(dx * dx + dy * dy);

        var normX:Float = dx / length;
        var normY:Float = dy / length;

        this.x += normX * distance;
        this.y += normY * distance;

        separationSpeed = distance / FlxG.elapsed;
        if (separationSpeed > speed) separationSpeed = speed;
    }

    public function setFlipX(flip:Bool) {
        if (flip) {
            flipX = true;
            //offset.x = 28 - 11.5;
        }
        else {
            flipX = false;
            //offset.x = 4 - 11.5;
        }
    }

    public function resurrect() {
        health = iHealth * 1.5;
        hurting = 0;
        alpha = 1.0;
        alive = true;
        active = true;
        moves = true;
        //solid = true;
        undead = true;
        animation.play("undead_walk");
        speed *= 0.6;
        velocity.x = 0.0;
        velocity.y = 0.0;
        Reg.playstate.player.xp += xpGiven * 0.25;
    }

    public function standbyDeath() {
        animation.play("dead");
        alive = false;
        moves = false;
        timeToDecompose = decomposeTime;
    }

    function shootBullet() {
        if (undead) {
            for (i in 0...Reg.playstate.playerBullets.members.length) {
                if (!Reg.playstate.playerBullets.members[i].exists) {
                    Reg.playstate.playerBullets.members[i].reset(x + width * 0.5 - 9, y + height * 0.5 - 9);
                    Reg.playstate.playerBullets.members[i].velocity = getVelocityForTarget(target.x, target.y);
                    break;
                }
            }
        }
        else {
            for (i in 0...Reg.playstate.enemyBullets.members.length) {
                if (!Reg.playstate.enemyBullets.members[i].exists) {
                    Reg.playstate.enemyBullets.members[i].reset(x + width * 0.5 - 9, y + height * 0.5 - 9);
                    Reg.playstate.enemyBullets.members[i].velocity = getVelocityForTarget(target.x, target.y);
                    break;
                }
            }
        }
    }

    function getVelocityForTarget(tx:Float, ty:Float):FlxPoint {
        var bVelocity = new FlxPoint((tx + 0) - (x + width * 0.5), (ty + 0) - (y + height * 0.5));
        bVelocity.normalize();
        bVelocity.length = EnemyBullet.speed;


        return bVelocity;
    }
}