using System.Collections.Generic;
using System.IO;
using System.Linq;
using TrackAnalysis;
using UnityEngine;
using UnityEngine.UI;

public class TrackManager : MonoBehaviour
{
    [SerializeField]
    GameObject trackList;

    [SerializeField]
    GameObject trackItemPrefab;

    [SerializeField]
    GameObject trackInfo;

    [SerializeField]
    GameObject trackInfoItemPrefab;

    [SerializeField]
    Texture2D[] backgrounds;
    private int textureID = 0;

    Texture     buffer;

    public Text Artist;
    public Text BPM;

    private GameObject selected = null;

    private KeyDown Pressed
    {
        get
        {
            if (Input.GetKeyDown(KeyCode.DownArrow))
                return KeyDown.Down;
            if (Input.GetKeyDown(KeyCode.UpArrow))
                return KeyDown.Up;
            return KeyDown.None;
        }
    }

    bool IsPressedStart
    { get { return Input.GetKey(KeyCode.Space); } }

    // Use this for initialization
    void Start()
    {
        StretchTrackInfoList(GenerateTrackInfos())
        .ToList()
        .ForEach(x => MakeTrackObject(x));

        TrackBrowse();
    }
	
    // Update is called once per frame
    void Update()
    {
        ScrollTrackList();

        if (IsPressedStart)
            StartTrack();
    }

    void ScrollTrackList()
    {
        if (Pressed == KeyDown.Down)
            DownScroll();
        else if (Pressed == KeyDown.Up)
            UpScroll();
    }

    void UpScroll()
    {
        trackList.transform.GetChild(trackList.transform.childCount - 1).SetAsFirstSibling();
        TrackBrowse();
    }

    void DownScroll()
    {
        trackList.transform.GetChild(0).SetAsLastSibling();
        TrackBrowse();
    }

    IEnumerable<TrackInfo> GenerateTrackInfos()
    {
        return new DirectoryInfo("Assets/Tracks")
                   .GetFiles("*.bpe", SearchOption.AllDirectories)
                   .Select(s => new TrackInfo(s));
    }

    IEnumerable<TrackInfo> StretchTrackInfoList(IEnumerable<TrackInfo> tracks)
    {
        var stretched = Enumerable.Empty<TrackInfo>();
        Enumerable.Range(0, 1 + (4 / tracks.Count()))
                  .ToList()
                  .ForEach(x => stretched = stretched.Concat(tracks));

        return stretched;
    }

    void MakeTrackObject(TrackInfo info)
    {
        Instantiate(trackItemPrefab, trackList.transform)
        .AddComponent<TrackInfoHolder>().trackInfo = info;
    }

    private void TrackBrowse()
    {
        trackList.GetComponent<RawImage>().texture = backgrounds[(textureID ^= 1)];

        if (selected != null)
            selected.GetComponentInChildren<Text>().color = Color.white;

        selected = trackList.transform.GetChild(2).gameObject;
        selected.GetComponentInChildren<Text>().color = Color.black;

        var info = selected.GetComponent<TrackInfoHolder>().trackInfo;

        Artist.text = "Artist  :" + info.Artist.ToString();
        BPM.text    = "BPM    :"  + info.BPM   .ToString();
        
        trackInfo.transform.Cast<Transform>()
                           .ToList()
                           .ForEach(x => Destroy(x.gameObject));

        info.TrackList
            .ForEach(x => Instantiate(trackInfoItemPrefab, trackInfo.transform)
                          .GetComponent<Text>()
                          .text = x);
    }

    public void StartTrack()
    {
        // TODO: disable start button if nothing selected
        
        GameManager.Instance.CurrentTrack = selected.GetComponent<TrackInfoHolder>().trackInfo;
        AllSceneManager.InitJudgeResult();
        
        Destroy(this);

        GameManager.Instance.SceneTransition("InGame");
    }

    private enum KeyDown
    {
        Up,
        Down,
        None
    }
}