using Godot;
using System;

public partial class player : ship // Inherits from base ship class
{   
	public enum ShipColor{RED, GREEN, BLUE}

	[Signal]
	public delegate void  HealthUpdateEventHandler(int health);
	
	[Signal]
	public delegate void PlayerDeathEventHandler();

	[Export]
	public ShipColor Color;
	
	[Export]
	public float FlightAssistValue { get; set; } = 2.5f;

	private float _angularVelocity;
	private float _angularAccel = 0.3f;


	private void GetInput()
	{
		RotationDirection = (int)Input.GetAxis("left", "right");
		_angularVelocity += RotationDirection * _angularAccel;
		_angularVelocity = Mathf.Clamp(_angularVelocity, -RotationSpeed, RotationSpeed);

		if (RotationDirection == 0 && FlightAssistValue > 0f)
		{
			_angularVelocity = Mathf.MoveToward(_angularVelocity, 0f, FlightAssistValue);
		}
		
		Velocity += (Transform.X * Input.GetAxis("strafe_left", "strafe_right") * StrafeSpeed) + (Transform.Y * Input.GetAxis("up", "down") * MainSpeed);
		Velocity = Velocity.LimitLength(MaxSpeed);

		if(Input.GetAxis("strafe_left", "strafe_right") == 0){
			Velocity = Velocity.MoveToward(Vector2.Zero, FlightAssistValue);
		}
		else if(Input.GetAxis("down", "up") == 0){
			Velocity = Velocity.MoveToward(Vector2.Zero, FlightAssistValue);
		}
		//FA toggle
		if (Input.IsActionJustPressed("toggle_fa"))
		{
			ToggleFlightAssist();
		}
	}

    public override void ShipDamage(int damage)
    {
        base.ShipDamage(damage);
		EmitSignal(SignalName.HealthUpdate, Health);

		if (Health <= 0)
		{
			EmitSignal(SignalName.PlayerDeath);
			//etNode<AudioStreamPlayer2D>("ExplodeSFX").Play();
		}
    }

    public void HealShip(int health)
    {
	    Health += health;
	    if (Health > MaxHealth) Health = MaxHealth;
	    EmitSignal(SignalName.HealthUpdate, Health);

    }

    public void HealthUpgrade() // sets health stats (upgrades)
    {
	    MaxHealth = (int)(MaxHealth * 1.1f);
	    Health = MaxHealth;;
	    EmitSignal(SignalName.HealthUpdate, Health);
    }

    public void DamageUpgrade() // sets new damage stat (upgrades)
    {
	    Damage = (int)(Damage * 1.1f);;
    }

    public void SpeedUpgrade() // sets new speed stats (upgrades)
    {
		MaxSpeed = (int)(MaxSpeed * 1.1f);
		MainSpeed = (int)(MainSpeed * 1.1f);
		StrafeSpeed = (int)(StrafeSpeed * 1.1f);
		RotationSpeed = RotationSpeed * 1.1f;
    }

    private void ToggleFlightAssist()
	{
		if (FlightAssistValue == 0f){FlightAssistValue = 2.5f;}
		else {FlightAssistValue = 0;}
	}

    public override void _Ready()
    {
	    Type = player_config.SelectedType;
	    Color = player_config.SelectedColor;
		
		SetupVisual();
		//GD.Print(Faction);

		this.SpritePath = Color switch
		{
			ShipColor.RED => this.SpritePath + "ShipRed.png",
			ShipColor.GREEN => this.SpritePath + "ShipGreen.png",
			ShipColor.BLUE => this.SpritePath + "ShipBlue.png",
			_ => this.SpritePath
		};
		//GD.Print(SpritePath);
		Sprite.Texture = GD.Load<Texture2D>(SpritePath);


		LaserSpawn = GetNode<Node2D>("LaserSpawn");
		//Connect("body_entered" +=)
		StatModifier = 1.3f;
		SetShipStats();
		MaxHealth *= 4; // quadruple player health (balancing)
		Health = MaxHealth;
		Damage *= 2; // double player damage (balancing)
		EmitSignal(SignalName.HealthUpdate, Health);
	}

	public override void _Process(double delta)
	{
		FireTimer -= (float)delta;

		if(Input.IsActionPressed("shoot"))
		{
			//GD.Print("DEBUG: FIRING PLAYER LASER");
			if (FireTimer > 0f) return;
			ShootLaser();
			FireTimer = FireCooldown;
		}

	}
	public override void _PhysicsProcess(double delta)
	{ // every frame
		GetInput();
		Rotation += _angularVelocity * (float)delta;
		Velocity.LimitLength(MaxSpeed);

		//GD.Print(MainSpeed);
        //GD.Print("v ",Velocity, "v");
		//GD.Print(Name, ": MainSpeed = ", MainSpeed, "  Velocity = ", Velocity.Length());
		
		MoveAndSlide();

		/*
		if (Position.Y < 0) {Position = new Vector2(Position.X, ScreenSize.Y);}
		if (Position.Y > ScreenSize.Y) {Position = new Vector2(Position.X, 0);}
		if (Position.X < 0) { Position = new Vector2(ScreenSize.X, Position.Y);}
		if (Position.X > ScreenSize.X) { Position = new Vector2(0, Position.Y);}
		*/
	}
}
