using UnityEngine.UI;
using UnityEngine;

public class Catapult : MonoBehaviour
{
        [SerializeField]
    private Population population;

    [SerializeField]
    private float turnSpeed = 1.5f;

    [SerializeField]
    private float maxAngle;

    [SerializeField]
    private float maxProjectileSpeed;
    private float rangeMultiplier;  //The velocity obtained from input (0 to 1)

    [SerializeField]
    private float valueSpeed;   //The speed the UI element moves
    [SerializeField]
    private bool leftSide = true;   //Is this catapult located on the right side?

    [SerializeField]
    private Text noOfBodiesLabel;
    private int _noOfLoadedBodies = 1; 
    private int NoOfLoadedBodies
    {
        get
        {
            return _noOfLoadedBodies;
        }
        set
        {
            _noOfLoadedBodies = value;
            noOfBodiesLabel.text = value+"";
        }
    }
    private bool loaded
    {
        get
        {
            return NoOfLoadedBodies > 0;
        }
    }

    [SerializeField]
    private GameObject bodyPrefab;  //A reference to the body we want to instantiate!

    [SerializeField]
    private Transform catapultTransform;    //The transform for the catapult sprite

    [SerializeField]
    private GameObject displayBody; //The body to be displayed on the catapult (get enabled and disabled, visual representation only!)

    [SerializeField]
    private Slider valueSlider; //Reference for the value slider connected to this catapult


    void Update()
    {
        if (leftSide)
        {
            Controls("w", "s", "Left Horizontal", 1);

        }
        else
        {
            Controls("up", "down", "Right Horizontal", 2);
        }
    }

    private void Controls(string shootKey, string loadKey, string turnAxis, int catapultId)
    {
        if (Input.GetKeyDown(shootKey) && loaded)
        {
            //play sfx
            AudioManager.instance.PlayChargeSound(catapultId);
        }

        if (Input.GetKey(shootKey) && loaded)
        {
            valueSlider.value += valueSpeed * Time.deltaTime;
            rangeMultiplier = valueSlider.value;
            if (valueSlider.value >= valueSlider.maxValue)
            {
                rangeMultiplier = valueSlider.maxValue;
                CalculateAndFire(catapultId);
                NoOfLoadedBodies = 0;
            }
        }

        if (Input.GetKeyUp(shootKey) && loaded)
        {
            rangeMultiplier = valueSlider.value;
            CalculateAndFire(catapultId);
            NoOfLoadedBodies = 0;
        }

        if (Input.GetKeyDown(loadKey))
        {
            LoadCatapult(catapultId);
        }

        //Rotation
        float h = Input.GetAxis(turnAxis);

        if (h != 0)
        {
            catapultTransform.Rotate(0, 0, -turnSpeed * h * Time.deltaTime);

            if (catapultTransform.rotation.z > maxAngle)
                catapultTransform.rotation = Quaternion.Euler(0, 0, maxAngle);

            if (catapultTransform.rotation.z < -maxAngle)
                catapultTransform.rotation = Quaternion.Euler(0, 0, -maxAngle);
        }
    }

    void LoadCatapult(int id)
    {
        if (population.UseDeadBody())
        {
            AudioManager.instance.PlayReloadSound(id);
            NoOfLoadedBodies++;
            if (!displayBody.activeSelf)
                displayBody.SetActive(true);

            //Enable slider ui     
            valueSlider.gameObject.SetActive(true);
        }
    }

    void CalculateAndFire(int id)
    {
        AudioManager.instance.StopChargeSound(id);

        //Reset slider
        valueSlider.value = valueSlider.minValue;

        Vector2 impactPosition = Vector2.zero;

        if (leftSide)
        {
            //Calculate the impact position
            impactPosition = catapultTransform.position + catapultTransform.right * rangeMultiplier;
        }
        else
        {
            //Calculate the impact position
            impactPosition = catapultTransform.position - catapultTransform.right * rangeMultiplier;
        }

        //Disable slider ui     
        valueSlider.gameObject.SetActive(false);

        //Play Animation

        //Disable the visual representation on the catapult
        if (displayBody.activeSelf)
            displayBody.SetActive(false);

        AudioManager.instance.PlayShootSound(id);
        for (int i = 0; i < NoOfLoadedBodies; i++) {
            float spread = Mathf.Min(0.5f + 0.5f * NoOfLoadedBodies / 5, 3.5f);
            SendDeadBody(id, impactPosition + Random.insideUnitCircle * spread);
        }

        //Reset variables
        rangeMultiplier = 0;
        NoOfLoadedBodies = 0;
    }

    private void SendDeadBody(int id, Vector2 impactPosition)
    {
        GameObject body = Instantiate(bodyPrefab, catapultTransform.position, catapultTransform.rotation);     //change spawn position? To the "basket" position in animation?

        //Send impactPosition to body.
        rangeMultiplier = Mathf.Clamp(rangeMultiplier, 0, maxProjectileSpeed);
        body.GetComponent<deadBody>().setGoal(impactPosition, rangeMultiplier);
    }

    void OnDrawGizmos()
    {
        Gizmos.color = Color.red;
        Vector3 pos = Vector3.zero;
        if (leftSide)
            pos = catapultTransform.position + catapultTransform.right * rangeMultiplier;
        else     
            pos = catapultTransform.position + -catapultTransform.right * rangeMultiplier;

        Gizmos.DrawSphere(pos, 0.1f);
    }
}
