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

[System.Serializable]
public class MemoryPage
{
    public bool m_found;
    public Sprite m_sprite;
}

public class MemoryBook : MonoBehaviourSingleton<MemoryBook>
{
    public MemoryPage[] m_pages;

    Image m_image;

    int m_currentPageIdx = -1;
    int m_showPageIdx = -1;
    int m_lastPageIdx = -1;

    float m_alpha = 0;

    float m_alphaFadeSpeed = 1.0f;

    enum Mode
    {
        None,
        Closed,
        Browse,
        Inspect
    }

    Mode m_mode = Mode.Closed;

	public void OnInit()
    {
        m_image = GetComponent<Image>();

        bool found = false; // @DBG
        foreach (var p in m_pages)
            p.m_found = found;
	}

    public int GetNormalPagesCount()
    {
        return m_pages.Length - 3;
    }

    public int GetTotalPagesCount()
    {
        return m_pages.Length;
    }

    public int GetFoundPagesCount()
    {
        int c = 0;
        foreach (var p in m_pages)
            if (p.m_found)
                c++;
        return c;
    }

    public bool IsOpen()
    {
        return m_mode != Mode.Closed || !IsTurningPage();
    }

    public void OpenBookBrowse()
    {
        if (m_lastPageIdx == -1) // none found
        {
            return;
        }
        m_mode = Mode.Browse;
        m_alphaFadeSpeed = 0.5f;

        ShowPage(m_lastPageIdx);
    }

    public void OpenBookInspect(int newPageIdx)
    {
        m_mode = Mode.Inspect;
        m_alphaFadeSpeed = 0.5f;

        Debug.Assert(0 <= newPageIdx && newPageIdx < m_pages.Length);
        m_pages[newPageIdx].m_found = true;
        m_lastPageIdx = newPageIdx;

        ShowPage(m_lastPageIdx);
    }

    public void CloseBook()
    {
        m_mode = Mode.Closed;
        m_alphaFadeSpeed = 1.0f;

        ShowPage(-1);
    }

    bool IsTurningPage()
    {
        return (m_showPageIdx != -1 && m_alpha != 1) || (m_showPageIdx == -1 && m_alpha != 0);
            //(m_showPageIdx != -1 && m_currentPageIdx != m_showPageIdx) || m_alpha != 1;
    }

    int GetNextPage(int idx)
    {
        do
        {
            idx++;
        } while (idx < m_pages.Length && !m_pages[idx].m_found);

        return (idx == m_pages.Length) ? -1 : idx;
    }

    int GetPrevPage(int idx)
    {
        do
        {
            idx--;
        } while (idx > -1 && !m_pages[idx].m_found);

        return (idx == -1 ) ? -1 : idx;
    }

    public void OnUpdate()
    {
        if(m_mode == Mode.Browse)
            UpdateBrowse();
        
        bool applyAlpha = false;

        if (m_currentPageIdx != m_showPageIdx)
        {
            // hide
            if (m_currentPageIdx != -1 && m_alpha > 0)
            {
                m_alpha -= Time.deltaTime * m_alphaFadeSpeed;
                if (m_alpha < 0)
                {
                    m_alpha = 0;
                    m_currentPageIdx = -1;
                }

                applyAlpha = true;
            }
        }

        if(m_currentPageIdx == -1 && m_showPageIdx != -1)
        {
            LoadPage(m_showPageIdx);
        }
        
        if (m_currentPageIdx == m_showPageIdx)
        {
            // show
            if(m_currentPageIdx != -1 && m_alpha < 1)
            {
                m_alpha += Time.deltaTime * m_alphaFadeSpeed;
                if(m_alpha > 1)
                {
                    m_alpha = 1;
                    OnFinishedShowingPage();
                }
            }
            applyAlpha = true;
        }

        if(applyAlpha)
        {
            m_image.color = new Color(1, 1, 1, m_alpha * 0.9f);
        }
    }

    void UpdateBrowse()
    {
        if (IsTurningPage())
            return;

        int idx = -1;
        float h = CrossPlatformInputManager.GetAxis("Horizontal");
        if(h > 0)
        //if (Input.GetKeyDown(KeyCode.RightArrow))
            idx = GetNextPage(m_showPageIdx);
        else
        if (h < 0)
        //if (Input.GetKeyDown(KeyCode.LeftArrow))
             idx = GetPrevPage(m_showPageIdx);

        if (idx != -1)
            ShowPage(idx);
    }

    void ShowPage(int idx)
    {
        if (m_pages.Length == 0)
            return;

        m_showPageIdx = Mathf.Clamp(idx, -1, m_pages.Length-1);
    }

    void LoadPage(int idx)
    {
        RandomPosition();

        m_image.sprite = m_pages[idx].m_sprite;
        Vector2 size = m_image.sprite.bounds.size * m_image.sprite.pixelsPerUnit;
        m_image.rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, size.x);
        m_image.rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, size.y);

        m_alpha = 0;
        m_image.color = new Color(1, 1, 1, m_alpha);

        m_currentPageIdx = idx;
    }

    void RandomPosition()
    {
        if (GFRandom.RangeClose(0, 1) == 0)
        {
            // left
            //m_image.rectTransform.anchorMin = new Vector2(0, 1);
            //m_image.rectTransform.anchorMax = new Vector2(0, 1);
            m_image.rectTransform.anchoredPosition = new Vector2(-380, -100);
            m_image.rectTransform.rotation = Quaternion.Euler(0, 0, GFRandom.RangeClose(24, 36));
        }
        else
        {
            // right
            //m_image.rectTransform.anchorMin = new Vector2(1, 1);
            //m_image.rectTransform.anchorMax = new Vector2(1, 1);
            m_image.rectTransform.anchoredPosition = new Vector2(380, -70);
            m_image.rectTransform.rotation = Quaternion.Euler(0, 0, GFRandom.RangeClose(-36, -24));
        }
    }

    void OnFinishedShowingPage()
    {
        Debug.Log("Page " + m_currentPageIdx + " " + m_image.sprite.name);
        // @TODO play sound, etc.

        m_lastPageIdx = m_currentPageIdx;
        m_alphaFadeSpeed = 1;
    }
}
