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

public delegate void PersonHandler(Person person);

public class Population : MonoBehaviour
{

    public event PersonHandler PersonDied;

    public Transform topRight;
    public Transform bottomLeft;

    [HideInInspector]
    public float Left;
    [HideInInspector]
    public float Right;
    [HideInInspector]
    public float Down;
    [HideInInspector]
    public float Up;

    public float MovementChangeRate;

    public float RespawnRate;
    public float ContaminationRate;
    public float HealthLossRate;

    public int numberOfPeople;
    public GameObject personPrefab;

    private List<Person> persons = new List<Person>();
    public int noOfDead = 0;
    public int noOfHealthy = 0;
    public int noOfContaminated = 0;
    public PopulationUI UI;


    // Use this for initialization
    void Start()
    {
        Reset();

    }

    private void OnEnable()
    {
        ControlsUI.StartGame += StartGame;
    }

    private void OnDisable()
    {
        ControlsUI.StartGame -= StartGame;
    }


    private void StartGame()
    {
        CreateContaminated();
        CreateContaminated();
        CreateContaminated();
        CreateContaminated();
    }

    private void Reset()
    {
        Left = bottomLeft.transform.position.x;
        Right = topRight.transform.position.x;
        Down = bottomLeft.transform.position.y;
        Up = topRight.transform.position.y;

        persons.ForEach(person => { Destroy(person.gameObject); });
        persons.Clear();

        for (int i = 0; i < numberOfPeople; i++)
        {
            CreatePerson("Person " + i);
        }



        // Invoke("Spawn", RespawnRate * persons.Count / 100);
    }

    void Spawn()
    {
        CreatePerson("Spawned " + persons.Count);
        Invoke("Spawn", RespawnRate * persons.Count / 100 * UnityEngine.Random.value);
    }

    void CreateContaminated()
    {
        Person contaminatedPerson = CreatePerson("Contaminated person " + persons.Count);
        contaminatedPerson.IsContaminated = true;
        contaminatedPerson.Health = 0.2f + 0.2f * UnityEngine.Random.value;
    }

    internal void Kill(Person person)
    {
        Destroy(person.gameObject);
        noOfDead++;
        persons.Remove(person);
        if (PersonDied != null)
            PersonDied.Invoke(person);
    }

    Person CreatePerson(string name)
    {
        GameObject personGO = Instantiate(personPrefab, Utils.GetRandomFreePositionInSquare(Left, Right, Down, Up), Quaternion.identity);
        personGO.name = name;
        personGO.transform.SetParent(transform, true);
        personGO.GetComponent<Move>().parent = this;
        Person person = personGO.GetComponent<Person>();
        person.population = this;
        persons.Add(person);
        return person;
    }

    public bool UseDeadBody()
    {
        if (noOfDead > 0)
        {
            noOfDead--;
            return true;
        }
        return false;
    }

    private void Update()
    {

        if (Input.GetKey("left ctrl") && Input.GetKeyDown("r"))
        {
            Reset();
        }
        if (Input.GetKey("left ctrl") && Input.GetKey("k"))
        {
            if (persons.Count > 0)
                Kill(persons[0]);
        }
        noOfHealthy = 0;
        noOfContaminated = 0;

        foreach (Person person in persons)
        {
            if (person.IsContaminated)
            {
                noOfContaminated++;
            }
            else
            {
                noOfHealthy++;
            }
        }
        UI.NoOfHealthy = noOfHealthy;
        UI.NoOfSick = noOfContaminated;
        UI.NoOfDead = noOfDead;
    }

}
