using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using ExposeProperty;
using UnityEngine.SceneManagement;

public class Level : ExposableMonobehaviour {

    public WaveSource basePlayerWave;

    public GameObject playerRoom;

    public WaveInstance waveInstancePrefab;

    public GameObject roomContainer;

    public GameObject attackContainer;

    public Griddy grid;

    public Text moneyCounterText;

    public GameObject player;

    public GameObject[] musics;

    
    public int currentMusic = 0;

    public int attackDelay;

    public int baseAttackDelay;

    [HideInInspector] [SerializeField]
    private int money;

    private static Level instance;

    public static Level Instance
    {
        get
        {
            return instance;
        }
    }

    public List<GridElement> GetElementsInZone(AbsoluteZone zone)
    {
        GridElement[] gridElements = GetComponentsInChildren<GridElement>();
        List<GridElement> list = new List<GridElement>();
        foreach(GridElement gridElement in gridElements)
        {
            if (gridElement.IsIn(zone))
            {
                list.Add(gridElement);
            }
        }
        return list;
    }

    /*public void PerformAttack(Wave attack, Vector2I source)
    {
        AbsoluteZone zone = AbsoluteZone.Create(attack.zone, source);

        List<GridElement> elementsInZone = GetElementsInZone(zone);

        //List<GridElement> ret = new List<GridElement>();
        foreach(GridElement gridElement in elementsInZone)
        {
            Attackable[] attackables = gridElement.GetComponents<Attackable>();
            foreach (Attackable attackable in attackables)
            {
                attackable.Attack();
            }
        }
    }*/

    public void AddWave(WaveSource waveSource)
    {
        foreach (Wave wave in waveSource.waves)
        {
            WaveInstance waveInstance = Instantiate(waveInstancePrefab);
            waveInstance.wave = wave;
            waveInstance.zone = AbsoluteZone.Create(wave.zone, waveSource.position);
            waveInstance.name = "Attack from " + waveSource.name;
            waveInstance.transform.SetParent(attackContainer.transform, false);
            AddWave(waveInstance);
        }
    }

    public void AddWave(WaveInstance waveInstance)
    {
        grid.AddWaveOnCells(waveInstance);

        UpdateRooms(waveInstance.zone);
    }

    private void UpdateRooms(AbsoluteZone zone)
    {
        Room[] rooms = roomContainer.GetComponentsInChildren<Room>();
        foreach(Room room in rooms)
        {
            if(room.zone.Collides(zone))
            {
                room.UpdateWaveLevels();
            }
        }
    }

    public Level()
    {
        instance = this;
    }

    [ExposeProperty]
    public int Money
    {
        get
        {
            return money;
        }
        set
        {
            money = value;
            if (moneyCounterText != null)
            {
                moneyCounterText.text = money.ToString();
            }
            else
            {
                Debug.Log("Error : moneyCounterText == null");
            }
        }
    }

    public void Restart()
    {
        SceneManager.LoadScene(0);// SceneManager.GetActiveScene().buildIndex);
    }

    public void Exit()
    {
        Application.Quit();
    }

    void Start()
    {
        Invoke("AddBaseAttack", baseAttackDelay);
    }

    private void AddBaseAttack()
    {
        Debug.Log("Addbaseattack");
        AddWave(basePlayerWave);
    }

    public void UpgradePlaced()
    {
        if (player != null)
        {
            Animator animator = player.GetComponent<Animator>();
            if (animator != null)
                animator.SetTrigger("woohoo");
        }
    }

    public void SetMusic(int index)
    {
        musics[currentMusic].SetActive(false);
        currentMusic = index;
        musics[index].SetActive(true);
    }

    public void ChangeMusicVolume(float volume)
    {
        musics[currentMusic].GetComponent<AudioSource>().volume = volume;
    }

}
