using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerGameplay : MonoBehaviour
{
	public GameObject DeathBodyPrefab;
    public float DefaultPlayerSpeed = 1.0f;
    public float PlayerSpeed;             //Floating point variable to store the player's target movement speed.

    public bool IsDiseased;
    public bool m_IsDead;
    public float DiseasedSpeedModifier = 0.5f;
    public float DiseaseTransmissionCooldown = 0.5f;
    public float DiseaseExplosionTime; //time before disease explodes
    private float m_DiseaseOriginalTime;
    public float RespawnTime;
    public float m_RespawnTimer;
    public float RatioCoinsDropOnDeath;
    private PlayerHead m_PlayerHead;
	private GameObject deadbody;

    public int m_CurrentScore { get; set; }
    Renderer cachedRenderer;

    private bool RefreshGameplayValues = false;

    private Vector3 m_PreviousPosition = Vector3.zero;

    private Rigidbody2D rb2d;       //Store a reference to the Rigidbody2D component required to use 2D Physics.
    // Use this for initialization
    void Start()
    {
        IsDiseased = false;
        PlayerSpeed = DefaultPlayerSpeed;
        cachedRenderer = GetComponent<Renderer>();
        cachedRenderer.material.color = GetComponent<Player>().DefaultColor;
        
    	m_PreviousPosition = transform.position;
        m_IsDead = false;
        transform.Find("DiseasedGraphic").GetComponent<Renderer>().enabled = false;
        rb2d = GetComponent<Rigidbody2D>();

		m_PlayerHead = transform.Find("PlayerHead").GetComponent<PlayerHead>();
    }

    public bool GetIsDiseased()
    {
        return IsDiseased;
    }

    public void SetPlayerSpeed(float newSpeed)
    {
        PlayerSpeed = newSpeed;
    }

    public float GetPlayerSpeed()
    {
        return PlayerSpeed;
    }

    public void SetCurrentScore(int value)
    {
        m_CurrentScore += value;
        GameManager.GetPersistantGameInfo().ActivePlayers[GetComponent<Player>().m_PlayerIndex].Score = m_CurrentScore;
    }

    public void SetIsDiseased(bool setting)
    {
        if(m_IsDead)
        { return; }
        if(!GetIsDiseased() && setting)
        { 
            if(setting)
            {
                DiseaseExplosionTime = Random.Range(4.0f, 8.0f);
                m_DiseaseOriginalTime = DiseaseExplosionTime;
            }

            RefreshGameplayValues = true;
            IsDiseased = setting;
        }
        else if(GetIsDiseased() && !setting)
        {
            RefreshGameplayValues = true;
            IsDiseased = setting;
        }
        DiseaseTransmissionCooldown = 0.5f;
    }

    void OnCollisionEnter2D(Collision2D col)
    {
        if (col.gameObject.CompareTag("Player") && DiseaseTransmissionCooldown == 0)
        {
            bool isOpponentDiseased = col.gameObject.GetComponent<PlayerGameplay>().GetIsDiseased();
            bool isMyselfDiseased = GetIsDiseased();

            //infected players don't transmit to others
            if (isOpponentDiseased && isMyselfDiseased)
            { return; }

            //Transmit infection to another player
            if (isMyselfDiseased && !isOpponentDiseased)
            {
                Debug.Log("Spread disease to " + col.gameObject.GetComponent<Player>().m_PlayerName);
                SetIsDiseased(false);
                col.gameObject.GetComponent<PlayerGameplay>().SetIsDiseased(true);
            }

            //received a transmission from another player
            if(isOpponentDiseased && !isMyselfDiseased)
            {
                Debug.Log("Got a disease from " + col.gameObject.GetComponent<Player>().m_PlayerName);
                SetIsDiseased(true);
                col.gameObject.GetComponent<PlayerGameplay>().SetIsDiseased(false);
                ApplyDiseaseTransmissonForce(rb2d);
            }
            
        }
    }

    void ApplyDiseaseTransmissonForce(Rigidbody2D body)
    {
        Vector3 direction = body.transform.position - transform.position;
        body.AddForceAtPosition(direction.normalized, transform.position);
    }
    // Update is called once per frame
    void Update()
    {
        if (DiseaseTransmissionCooldown > 0)
        {
            DiseaseTransmissionCooldown -= Time.deltaTime;
        }
        else
        {
            DiseaseTransmissionCooldown = 0;
        }

        if (RefreshGameplayValues)
        {
            if (IsDiseased)
            {
                PlayerSpeed = PlayerSpeed * DiseasedSpeedModifier;
                transform.Find("DiseasedGraphic").GetComponent<Renderer>().enabled = true;
            }
            else
            {
                PlayerSpeed = DefaultPlayerSpeed;
				transform.Find("DiseasedGraphic").GetComponent<Renderer>().enabled = false;
            }
            RefreshGameplayValues = false;
        }

        UpdateDiseaseTimer();
        UpdateRespawnTimer();
    }

    void UpdateDiseaseTimer()
    {
        if (IsDiseased)
        {
            if (DiseaseExplosionTime > 0)
            {
                DiseaseExplosionTime -= Time.deltaTime;
				float headScaleRatio = (1.0f-DiseaseExplosionTime/m_DiseaseOriginalTime);
				m_PlayerHead.HeadScaleRatio = headScaleRatio;
            }
            else //you exploded
            {
                ApplyDiseaseTransmissonForce(rb2d);
				m_IsDead = true;
				transform.Find("DiseasedGraphic").GetComponent<Renderer>().enabled = false;
                IsDiseased = false;
                DiseaseExplosionTime = 0.0f;
                DiseaseTransmissionCooldown = 0.0f;
                SetPlayerSpeed(0.0f);
                RefreshGameplayValues = true;
                //TODO:disable input during death animation

                //Generate dead body.
				deadbody = Instantiate(DeathBodyPrefab);
				deadbody.GetComponent<Renderer>().material.color = cachedRenderer.material.color;
				deadbody.GetComponent<Renderer>().enabled = false;

				//Set Camera Focus
				GameObject.Find("Main Camera").GetComponent<FocusCam>().SetFocusGameObject(this.gameObject);

                //spill out your coins
                float currentCoins = (float)m_CurrentScore;
                int coinsToDrop;
                coinsToDrop = Mathf.FloorToInt(RatioCoinsDropOnDeath * currentCoins);
                GameObject.FindWithTag("CoinSpawner").GetComponent<CoinSpawner>().SpillCoins(gameObject.transform.localPosition, coinsToDrop);
                SetCurrentScore(-coinsToDrop);
                SetIsDiseased(false);
            }
        }
    }

    void UpdateRespawnTimer()
    {
        if(m_IsDead)
        {
            if (m_RespawnTimer > 0)
            {
                m_RespawnTimer -= Time.deltaTime;
            }
            else //You are respawned
            {
				if(deadbody)
				{
					deadbody.transform.position =  transform.position;
					deadbody.GetComponent<Renderer>().enabled = true;
				}
                //enable input after death animation
				gameObject.transform.localPosition = GameObject.FindWithTag("PlayerManager").GetComponent<PlayerManager>().GetPlayerStartPosition(GetComponent<Player>().m_PlayerIndex);

				m_PlayerHead.HeadScaleRatio = 0.0f; //Reset Headscale.
                m_IsDead = false;
                m_RespawnTimer = RespawnTime;
            }
        }
    }
}
