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

public class MenuManager : MonoBehaviour {

    enum CursorDirection { UP, DOWN, LEFT, RIGHT };

    public static bool cursorLocked = false;

    private static GameObject options = null;

    private static List<Text> choices = null;

    private static int cursorIdx = 0;

    private static List<GameObject> soundVolume = null;

    private static List<GameObject> musicVolume = null;

    private static GameObject back = null;

    private static Transform[] optionsChildren = null;

    private static Text[] levelSelection = null;

    private static bool inOptions = false;

    private static bool inLevelSelection = false;

    private const int maxCursorPos = 10;

    private static int soundVolumePos = 0;

    private static int musicVolumePos = 0;

    private static float pasCursor = 0f;

    private static float leftPosCursor = 0f;

	void Start() {
        soundVolumePos = maxCursorPos;
        musicVolumePos = maxCursorPos;
        choices = new List<Text>();
        Transform[] children = GetComponentsInChildren<Transform>();
        for(int i = 1; i < children.Length; i++) {
            // On ne veut que le premier niveau d'enfants
            if (children[i].transform.parent == transform) {
                choices.Add(children[i].GetComponent<Text>());
                if (children[i].name == "Continue") {
                    levelSelection = children[i].GetComponentsInChildren<Text>();
                } else if (children[i].name == "Options") {
                    options = children[i].gameObject;
                    optionsChildren = options.GetComponentsInChildren<Transform>();
                    soundVolume = new List<GameObject>();
                    soundVolume.Add(optionsChildren[1].gameObject);
                    soundVolume.Add(optionsChildren[2].gameObject);
                    pasCursor = soundVolume[1].GetComponent<RectTransform>().rect.width / maxCursorPos;
                    leftPosCursor = soundVolume[1].GetComponent<RectTransform>().anchoredPosition.x - pasCursor * (maxCursorPos / 2);
                    soundVolume.Add(optionsChildren[3].gameObject);
                    musicVolume = new List<GameObject>();
                    musicVolume.Add(optionsChildren[4].gameObject);
                    musicVolume.Add(optionsChildren[5].gameObject);
                    musicVolume.Add(optionsChildren[6].gameObject);
                    back = optionsChildren[7].gameObject;
                }
            }
        }
        // Au démarrage, on cache les options
        ShowOptions(false);
        // Idem pour la sélection des levels
        ShowLevelSelection(false);
	}

    void Update() {
        if (Input.GetKeyDown(KeyCode.UpArrow) || Input.GetKeyDown(KeyCode.Z)) {
            if (!cursorLocked) {
                if (!inLevelSelection) {
                    ChangeCursorPosition(CursorDirection.UP);
                } else {
                    ChangeLevelSelection(CursorDirection.UP);
                }
            }
        } else if (Input.GetKeyDown(KeyCode.DownArrow) || Input.GetKeyDown(KeyCode.S)) {
            if (!cursorLocked) {
                if (!inLevelSelection) {
                    ChangeCursorPosition(CursorDirection.DOWN);
                } else {
                    ChangeLevelSelection(CursorDirection.DOWN);
                }
            }
        }
        if (Input.GetKeyDown(KeyCode.LeftArrow) || Input.GetKeyDown(KeyCode.Q)) {
            if (inOptions) {
                ChangeVolumePosition(CursorDirection.LEFT);
            } else if (inLevelSelection) {
                ChangeLevelSelection(CursorDirection.LEFT);
            }
        } else if (Input.GetKeyDown(KeyCode.RightArrow) || Input.GetKeyDown(KeyCode.D)) {
            if (inOptions) {
                ChangeVolumePosition(CursorDirection.RIGHT);
            } else if (inLevelSelection) {
                ChangeLevelSelection(CursorDirection.RIGHT);
            }
        }
        
        if (!cursorLocked && (Input.GetKeyDown(KeyCode.Return) || Input.GetKeyDown(KeyCode.KeypadEnter))) {
            ValidateChoice();
        }
        if (Input.GetKeyDown(KeyCode.Escape)) {
            if (inOptions) {
                cursorIdx = 2;
                ShowOptions(false);
            } else if (inLevelSelection) {
                cursorIdx = 1;
                ShowLevelSelection(false);
            } else {
                Application.Quit();
            }
        }
    }

    void UpdateCursorColor() {
        if (!inOptions && !inLevelSelection) {
            for (int i = 0; i < choices.Count; i++) {
                SetColor(choices[i], (i == cursorIdx ? Color.white : Color.black), true);
            }
        } else if (!inLevelSelection) {
            if (cursorIdx == 0) {
                for(int i = 0; i < soundVolume.Count; i++) {
                    SetColor(soundVolume[i], Color.white);
                }
                for (int i = 0; i < musicVolume.Count; i++) {
                    SetColor(musicVolume[i], Color.black);
                }
                SetColor(back, Color.black);
            } else if (cursorIdx == 1) {
                for (int i = 0; i < soundVolume.Count; i++) {
                    SetColor(soundVolume[i], Color.black);
                }
                for (int i = 0; i < musicVolume.Count; i++) {
                    SetColor(musicVolume[i], Color.white);
                }
                SetColor(back, Color.black);
            } else if (cursorIdx == 2) {
                for (int i = 0; i < soundVolume.Count; i++) {
                    SetColor(soundVolume[i], Color.black);
                }
                for (int i = 0; i < musicVolume.Count; i++) {
                    SetColor(musicVolume[i], Color.black);
                }
                SetColor(back, Color.white);
            }
        } else {
            for(int i = 1; i < levelSelection.Length; i++) {
                levelSelection[i].color = (i == cursorIdx + 1 ? Color.white : Color.black);
            }
        }
    }

    void SetColor(Text t, Color c, bool keepAlpha = false) {
        if (keepAlpha) {
            t.color = new Color(c.r, c.g, c.b, t.color.a);
        } else {
            t.color = c;
        }
    }

    void SetColor(GameObject go, Color c) {
        if (go.GetComponent<Text>() != null) {
            SetColor(go.GetComponent<Text>(), c);
        } else {
            SetColor(go.GetComponent<Image>(), c);
        }
    }

    void SetColor(Image i, Color c) {
        i.color = c;
    }

    void ChangeLevelSelection(CursorDirection d) {
        if (d == CursorDirection.LEFT) {
            cursorIdx--;
            if (cursorIdx == -1) {
                cursorIdx = levelSelection.Length - 2; // -1 pour éviter segfault, -1 pour éviter parent
            }
        } else if (d == CursorDirection.RIGHT) {
            cursorIdx = (cursorIdx + 1) % (levelSelection.Length - 1); // -1 pour éviter parent
        } else if (d == CursorDirection.UP) {
            if (cursorIdx <= 2) {
                cursorIdx = 6;
            } else if (cursorIdx <= 5) {
                cursorIdx -= 3;
            } else if (cursorIdx == 6) {
                cursorIdx = 4;
            }
        } else if (d == CursorDirection.DOWN) {
            if (cursorIdx <= 2) {
                cursorIdx += 3;
            } else if (cursorIdx <= 5) {
                cursorIdx = 6;
            } else if (cursorIdx == 6) {
                cursorIdx = 1;
            }
        }
        UpdateCursorColor();
        SoundManager.PlaySound("switch_cursor");
    }

    void ChangeCursorPosition(CursorDirection d) {
        if (d == CursorDirection.UP) {
            cursorIdx--;
            if (cursorIdx == -1) {
                if (!inOptions) {
                    cursorIdx = choices.Count - 1;
                } else {
                    // L'index max. dans les options est de 2
                    cursorIdx = 2;
                }
            }
        } else if (d == CursorDirection.DOWN) {
            if (!inOptions) {
                cursorIdx = (cursorIdx + 1) % choices.Count;
            } else {
                cursorIdx = (cursorIdx + 1) % 3;
            }
        }
        UpdateCursorColor();
        SoundManager.PlaySound("switch_cursor");
    }

    void ChangeVolumePosition(CursorDirection d) {
        if (cursorIdx == 0) {
            // Sound Volume
            if (d == CursorDirection.LEFT) {
                soundVolumePos = Mathf.Clamp(soundVolumePos - 1, 0, 10);
            } else if (d == CursorDirection.RIGHT) {
                soundVolumePos = Mathf.Clamp(soundVolumePos + 1, 0, 10);
            }
            soundVolume[2].GetComponent<RectTransform>().anchoredPosition = new Vector2(leftPosCursor + pasCursor * soundVolumePos, soundVolume[2].GetComponent<RectTransform>().anchoredPosition.y);
            SoundManager.ChangeSoundVolume(soundVolumePos / 10f);
        } else if (cursorIdx == 1) {
            // Music Volume
            if (d == CursorDirection.LEFT) {
                musicVolumePos = Mathf.Clamp(musicVolumePos - 1, 0, 10);
            } else if (d == CursorDirection.RIGHT) {
                musicVolumePos = Mathf.Clamp(musicVolumePos + 1, 0, 10);
            }
            musicVolume[2].GetComponent<RectTransform>().anchoredPosition = new Vector2(leftPosCursor + pasCursor * musicVolumePos, musicVolume[2].GetComponent<RectTransform>().anchoredPosition.y);
            SoundManager.ChangeMusicVolume(musicVolumePos / 10f);
        }
        SoundManager.PlaySound("switch_cursor");
    }

    void ValidateChoice() {
        if (!inOptions && !inLevelSelection) {
            if (cursorIdx == 0) {
                FadeManager.DoFadeOut("MainScene_0");
                cursorLocked = true;
            } else if (cursorIdx == 1) {
                ShowLevelSelection();
            } else if (cursorIdx == 2) {
                ShowOptions();
            } else if (cursorIdx == 3) {
                Application.Quit();
            }
        } else if (!inLevelSelection) {
            if (cursorIdx == 2) {
                ShowOptions(false);
            }
        } else {
            if (cursorIdx == 6) {
                cursorIdx = 1;
                ShowLevelSelection(false);
            } else {
                FadeManager.currentDay = cursorIdx;
                FadeManager.DoFadeOut("MainScene_"+cursorIdx.ToString());
                cursorLocked = true;
            }
        }
        SoundManager.PlaySound("validation");
    }

    void ShowOptions(bool b = true) {
        for(int i = 1; i < optionsChildren.Length; i++) {
            optionsChildren[i].gameObject.SetActive(b);
        }
        inOptions = b;
        if (b) {
            cursorIdx = 0;
        }
        UpdateCursorColor();
    }

    void ShowLevelSelection(bool b = true) {
        for (int i = 1; i < levelSelection.Length; i++) {
            levelSelection[i].gameObject.SetActive(b);
        }
        inLevelSelection = b;
        if (b) {
            cursorIdx = 0;
        }
        UpdateCursorColor();
    }
}