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

public class TutorInput : MonoBehaviour
{

    public enum TutorialState
    {
        Idle,
        MoveFromBehindBox,
        TalkToPlayerGreeting,
        WalkNextToPlayer,
        TalkToPlayerGetGlyphs,
        WaitForPlayerToGetGlyphs,
        TalkToPlayerHowToSummon,
        WaitForPlayerToSummon,
        TalkToPlayerOhCrap,
        RunAway,
        Done
    }

    public float Direction;
    public bool DoWalkAnimation = false;
    public Sprite SpeechBubbleSpriteLeft;
    public Sprite SpeechBubbleSpriteRight;
    public GameObject BrokenWindow;
    public AudioClip WindowBreakSound;
    public AudioClip TutorVoice;
    public GameObject Player;

    private TutorialState _tutorialState;
    private Animator _animator;
    private Animator _spriteAnimator;
    private Canvas _speechBubble;
    private Animator _speechAnimator;
    private Text _text;
    private RectTransform _panelTransform;
    private Image _panelImage;


    // Use this for initialization
    void Start()
    {
        _animator = GetComponent<Animator>();
        _spriteAnimator = transform.FindChild("Tutor Positioner").FindChild("Tutor Sprite").GetComponent<Animator>();
        _speechBubble = transform.FindChild("Tutor Positioner").FindChild("Speech Bubble").GetComponent<Canvas>();
        _speechAnimator = _speechBubble.GetComponent<Animator>();
        _text = _speechBubble.transform.FindChild("Panel").GetComponentInChildren<Text>();
        _panelTransform = _speechBubble.transform.FindChild("Panel").GetComponent<RectTransform>();
        _panelImage = _speechBubble.transform.FindChild("Panel").GetComponent<Image>();

        if(Player != null)
        {
            Player.GetComponent<CharacterData>().GlyphStackChanged += TutorInput_GlyphStackChanged;
        }

        GameStateController.Instance.GameState = EGameState.Tutoring_Welcome;
    }

    void TutorInput_GlyphStackChanged(System.Collections.Generic.Stack<DamageType> stack)
    {
        if(_tutorialState == TutorialState.WaitForPlayerToGetGlyphs && stack.Count > 1)
        {
            NextTutorialStep();
        }
    }

    void Awake()
    {
        GameStateController.Instance.GameStateChanged += Instance_GameStateChanged;
    }

    void Instance_GameStateChanged(EGameState oldState, EGameState newState)
    {
        switch(newState)
        {
            case EGameState.Tutoring_Welcome:
                StartTutorial();
                break;
            case EGameState.Tutoring_SummoningFinished:
                if(_tutorialState == TutorialState.WaitForPlayerToSummon)
                {
                    NextTutorialStep();
                }
                break;
        }
    }

    // The text will be split into multiple lines with the pipe ('|') character.
    // If the text ends with '|' then the speech bubble will switch to the left side of the character,
    // otherwise it will be on the right side.
    public void Speak(string text)
    {
        if (!string.IsNullOrEmpty(text))
        {
            bool left = text.EndsWith("|");
            text = text.Trim('|');

            if (left)
            {
                _speechBubble.transform.localPosition = new Vector3(0.25f, 0.25f);
                _speechBubble.GetComponent<RectTransform>().pivot = new Vector2(1.0f, 0.0f);
                _panelTransform.pivot = new Vector2(1.0f, 0.0f);
                _panelImage.sprite = SpeechBubbleSpriteLeft;
            }
            else
            {
                _speechBubble.transform.localPosition = new Vector3(-0.25f, 0.25f);
                _speechBubble.GetComponent<RectTransform>().pivot = new Vector2(0.0f, 0.0f);
                _panelTransform.pivot = new Vector2(0.0f, 0.0f);
                _panelImage.sprite = SpeechBubbleSpriteRight;
            }

            _text.text = text.Replace("|", System.Environment.NewLine);
            _speechAnimator.SetBool("Show", true);
            audio.PlayOneShot(TutorVoice, 1.0f);
        }
        else
        {
            _speechAnimator.SetBool("Show", false);
        }
    }

    // Tutorial state functions
    public TutorialState CurrentTutorialState { get { return _tutorialState; } }

    public void ResetTutorial()
    {
        _tutorialState = TutorialState.Idle;
        _animator.Play("tutor_reset_tutorial");
    }

    public void StartTutorial()
    {
        _tutorialState = TutorialState.MoveFromBehindBox;
        _animator.Play("tutor_move_from_behind_box");
    }

    public void NextTutorialStep()
    {
        switch (_tutorialState)
        {
            case TutorialState.MoveFromBehindBox:
                _tutorialState = TutorialState.TalkToPlayerGreeting;
                _animator.Play("tutor_talk_to_player");
                break;
            case TutorialState.TalkToPlayerGreeting:
                _tutorialState = TutorialState.WalkNextToPlayer;
                _animator.Play("tutor_walk_next_to_player");
                break;
            case TutorialState.WalkNextToPlayer:
                _tutorialState = TutorialState.TalkToPlayerGetGlyphs;
                _animator.Play("tutor_talk_to_player_2");
                break;
            case TutorialState.TalkToPlayerGetGlyphs:
                _tutorialState = TutorialState.WaitForPlayerToGetGlyphs;
                GameStateController.Instance.SetTutoringGlyphs();
                break;
            case TutorialState.WaitForPlayerToGetGlyphs:
                _tutorialState = TutorialState.TalkToPlayerHowToSummon;
                _animator.Play("tutor_talk_to_player_howto");
                break;
            case TutorialState.TalkToPlayerHowToSummon:
                _tutorialState = TutorialState.WaitForPlayerToSummon;
                GameStateController.Instance.SetTutoringSummon();
                break;
            case TutorialState.WaitForPlayerToSummon:
                _tutorialState = TutorialState.TalkToPlayerOhCrap;
                _animator.Play("tutor_talk_to_player_crap");
                break;
            case TutorialState.TalkToPlayerOhCrap:
                _tutorialState = TutorialState.RunAway;
                _animator.Play("tutor_run_away");
                break;
            case TutorialState.RunAway:
                _tutorialState = TutorialState.Idle;
                GameStateController.Instance.SetTutoringFinished();
                ResetTutorial();
                break;
        }
    }

    public void BreakWindow()
    {
        if (WindowBreakSound != null)
        {
            audio.PlayOneShot(WindowBreakSound, 1.0f);
        }
        if (BrokenWindow != null)
        {
            BrokenWindow.SetActive(true);
        }
    }

    //// Update is called once per frame
    void Update()
    {

        _spriteAnimator.SetInteger("Direction", (int)Direction);

        if (DoWalkAnimation)
        {
            _spriteAnimator.SetFloat("Velocity", 1.0f);
        }
        else
        {
            _spriteAnimator.SetFloat("Velocity", 0.0f);
        }

    }

}
