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

public class TimeElement {
    public int time { get; set; }
    public int id { get; set; }
}

public class ApplicationModel  
 {
    static public bool success = false;    // this is reachable from everywhere
    static public float successRate = 0.0f;    // this is reachable from everywhere
    static public float maxFailRate = 0.7f;    // this is reachable from everywhere
 }

public class GameScript : MonoBehaviour {
    private MusicStartUp music;
    public GameObject[] MusicButtons;
    public string FileMapName;
    public int Delay = 1500;
    private List<TimeElement> TimeElements { get; set; }
    
    public int SuccCount = 0;
    public int FailCount = 0;
    public GameObject ProgressSlider;
    public Image ProgressSliderFill;
    public float MaxFailRate = 0.8f;
    public AudioClip QSound;
    public AudioClip WSound;
    public AudioClip ESound;
    public AudioClip RSound;
    public AudioClip FailSound;
    public AudioClip BoltSound;
    public AudioClip ExplosionSound;
    public GameObject DarkBG;
    private AudioSource audioSource;
    private float startTime;
    private int totalElementCount;
    private Color goodColor = new Color(10/255.0f, 130/255.0f, 150/255.0f, 255/255.0f);
    private Color badColor = new Color(220/255.0f, 60/255.0f, 30/255.0f, 255/255.0f);
    public SparkContainerScript Spark;
    void Awake () {
        ReadFile(FileMapName);
    }

    void Start()
    {
        audioSource = GetComponent<AudioSource>();
        music = Camera.main.GetComponent<MusicStartUp>();
    }

    void Update () {
        if(TimeElements.Any()) {
            var first = TimeElements.First();
            if(first.time <= music.music.time * 1000 + Delay) {
                MusicButtons[first.id].GetComponentInChildren<SpawnMachineScript>().Spawn();
                TimeElements.Remove(first);
            }
        }

        // init game end
        else
        {
            Invoke("GameEnd", 4f);
        }
        
        if(Input.GetKeyDown(KeyCode.Escape))
        {
            SceneManager.LoadScene("main_menu");
        }
        var slider = ProgressSlider.GetComponent<Slider>();
        slider.value = GetTotalProgress();
        ProgressSliderFill.color = Color.Lerp(badColor, goodColor, GetSuccessRate());

        // dark bg update
        var bgrenderer = DarkBG.GetComponent<SpriteRenderer>();
        var bgcolor = bgrenderer.color;
        bgcolor.a = Mathf.Lerp (bgcolor.a, GetSuccessRate(), 0.1f);
        bgrenderer.color = bgcolor;
    }

    public void GameEnd()
    {
        ApplicationModel.success = GetSuccessRate() >= MaxFailRate;
        ApplicationModel.successRate = GetSuccessRate();
        ApplicationModel.maxFailRate = MaxFailRate;
        SceneManager.LoadScene("end_scene");
    }

    public float GetTotalProgress()
    {
        return  1.0f - ((TimeElements.Count() + 0.000001f) / (totalElementCount + 0.000001f));
    }

    public float GetSuccessRate()
    {
        return (SuccCount + FailCount) <= 0 ? 0.5f : SuccCount / (float)(SuccCount + FailCount);
    }

    private void ReadFile(string fileMapName)
    {
        TimeElements = new List<TimeElement>();
        TextAsset levelMap = Resources.Load(fileMapName) as TextAsset;
        string[] linesFromfile = levelMap.text.Split("\n"[0]);
        foreach (string line in linesFromfile)
        {
            string[] entries = line.Split(',');
            if (entries.Length > 0)
            {
                var element = new TimeElement
                {
                    time = int.Parse(entries[0]),
                    id = int.Parse(entries[1]) - 1
                };
                TimeElements.Add(element);
            }
        }
        totalElementCount = TimeElements.Count();
    }
    public void PlaySound(string id)
    {
        audioSource.volume = 1.0f;
        if(id == "Q")
        {
            audioSource.PlayOneShot(QSound);
        }
        else if(id == "W")
        {
            audioSource.PlayOneShot(WSound);
        }
        else if(id == "E")
        {
            audioSource.PlayOneShot(ESound);
        }
        else if(id == "R")
        {
            audioSource.PlayOneShot(RSound);
        }
        else if(id == "FAIL")
        {
            audioSource.PlayOneShot(FailSound);
        }
        else if(id == "XPL")
        {
            audioSource.PlayOneShot(ExplosionSound);
        }
        else if(id == "BOLT")
        {
            audioSource.PlayOneShot(BoltSound);
        }
        else
        {
            audioSource.PlayOneShot(FailSound);
        }
    }
}
