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

public class GameManager : MonoBehaviour
{
    public int m_NumRoundsToWin = 5;        
    public float m_StartDelay = 3f;         
    public float m_EndDelay = 3f;           
    public UISoundManager m_UISoundManager;

    public GameObject m_menuCamera;

    public GameObject menuMusic;
    public GameObject gameMusic;

    public GameObject canvasMenu;
    public GameObject canvasPauseMenu;
    public GameObject canvasIntro;
    public GameObject messageCanvas;

    public Text m_MessageText;              
    public GameObject m_TankPrefab;
    public GameObject m_TankAIPrefab;
    public List<TankManager> m_Tanks;

    public Transform[] m_spawnPointsTransform;


    private int m_RoundNumber;              
    private WaitForSeconds m_StartWait;     
    private WaitForSeconds m_EndWait;       
    private TankManager m_RoundWinner;
    private TankManager m_GameWinner;

    public bool m_gameIsStarted;

    public bool isInIntro;

    public bool isMultiplayer;
    public bool max_AI;

    public bool gameIsPaused = false;
    public bool isInOptions = false;

    private void Start()
    {
        canvasMenu.SetActive(false);
        m_gameIsStarted = false;
        gameMusic.SetActive(false);
        m_StartWait = new WaitForSeconds(m_StartDelay);
        m_EndWait = new WaitForSeconds(m_EndDelay); 
    }

    public void SetGameTypeToSolo()
    {
        isMultiplayer = false;
    }

    public void SetGameTypeToMulti()
    {
        isMultiplayer = true;
    }

    void Update()
    {
        if (Input.GetButtonDown("Start_1") || Input.GetButtonDown("Start_2") || Input.GetButtonDown("Start_3") || Input.GetButtonDown("Start_4") || Input.GetKeyDown(KeyCode.Escape) || Input.GetKeyDown(KeyCode.Return))
        {
            if(isInIntro)
            {
                isInIntro = false;
                canvasMenu.SetActive(true);
                canvasIntro.SetActive(false);
                canvasPauseMenu.SetActive(false);
            }        
        }

        if (Input.GetButtonDown("Start_1") || Input.GetButtonDown("Start_2") || Input.GetButtonDown("Start_3") || Input.GetButtonDown("Start_4") || Input.GetKeyDown(KeyCode.Escape))
        {
            if (m_gameIsStarted && !isInOptions)
            {
                PauseGame(!gameIsPaused);
            }
        }
    }

    public void StartGame()
    {
        Debug.Log("Starting Game");
        m_gameIsStarted = true;
        canvasMenu.SetActive(false);
        canvasPauseMenu.SetActive(false);

        menuMusic.SetActive(false);
        gameMusic.SetActive(true);

        m_menuCamera.SetActive(false);

        if(isMultiplayer)
        {
            SpawnAllTanks();
        }        
        else if(!isMultiplayer)
        {
            SpawnAllAITanks();
        }
        gameObject.GetComponent<SplitscreenManager>().SetupCameras();
        SetCameraTargets();

        gameObject.GetComponent<PowerUpManager>().StartPowerUpLoop();

        StartCoroutine(GameLoop());
    }


    private void SpawnAllTanks()
    {
        for (int i = 0; i < m_Tanks.Count; i++)
        {

            m_Tanks[i].m_Instance = Instantiate(m_TankPrefab,
                                    m_Tanks[i].m_SpawnPoint.position,
                                    m_Tanks[i].m_SpawnPoint.rotation) as GameObject;

            m_Tanks[i].m_PlayerNumber = i + 1;
            m_Tanks[i].Setup();
        }
    }

    private void SpawnAllAITanks()
    {
        for (int i = 0; i < m_Tanks.Count; i++)
        {

            m_Tanks[i].m_Instance = Instantiate(m_TankAIPrefab,
                                    m_Tanks[i].m_SpawnPoint.position,
                                    m_Tanks[i].m_SpawnPoint.rotation) as GameObject;

            m_Tanks[i].m_PlayerNumber = i + 1;
            m_Tanks[i].Setup();
        }
    }


    private void SetCameraTargets()
    {
        Transform[] targets = new Transform[m_Tanks.Count];

        for (int i = 0; i < targets.Length; i++)
        {
            targets[i] = m_Tanks[i].m_Instance.transform;
        }

    }


    private IEnumerator GameLoop()
    {
        yield return StartCoroutine(RoundStarting());
        yield return StartCoroutine(RoundPlaying());
        yield return StartCoroutine(RoundEnding());


        //CHANGER AVEC LE MENU DE FIN DE JEU (RESTART OU RETOUR MENU)
        if (m_GameWinner != null)
        {
            BackToMenu(4.0f);
        }
        else
        {
            StartCoroutine(GameLoop());
        }
    }


    private IEnumerator RoundStarting()
    {
        ResetAllTanks();
        DisableTankControl();
        ResetAllCameraEffects();

        m_RoundNumber ++;
        m_MessageText.text = "ROUND " + m_RoundNumber;

        yield return m_StartWait;
    }


    private IEnumerator RoundPlaying()
    {
        EnableTankControl();

        m_MessageText.text = string.Empty;

        while(!OneTankLeft())
        {
            yield return null;
        }        
    }


    private IEnumerator RoundEnding()
    {
        DisableTankControl();

        m_RoundWinner = null;

        m_RoundWinner = GetRoundWinner();

        if(m_RoundWinner != null)
        {
            m_RoundWinner.m_Wins++;
        }

        m_GameWinner = GetGameWinner();

        string message = EndMessage();
        m_MessageText.text = message;

        yield return m_EndWait;
    }


    private bool OneTankLeft()
    {
        int numTanksLeft = 0;

        for (int i = 0; i < m_Tanks.Count; i++)
        {
            if (m_Tanks[i].m_Instance.activeSelf)
                numTanksLeft++;
        }

        return numTanksLeft <= 1;
    }


    private TankManager GetRoundWinner()
    {
        for (int i = 0; i < m_Tanks.Count; i++)
        {
            if (m_Tanks[i].m_Instance.activeSelf)
                return m_Tanks[i];
        }

        return null;
    }


    private TankManager GetGameWinner()
    {
        for (int i = 0; i < m_Tanks.Count; i++)
        {
            if (m_Tanks[i].m_Wins == m_NumRoundsToWin)
                return m_Tanks[i];
        }

        return null;
    }


    private string EndMessage()
    {
        string message = "DRAW!";

        if (m_RoundWinner != null)
        {
            message = m_RoundWinner.m_ColoredPlayerText + " WINS THE ROUND!";
            m_UISoundManager.PlayRoundWinnerSFX();
        }

        message += "\n\n\n\n";

        for (int i = 0; i < m_Tanks.Count; i++)
        {
            message += m_Tanks[i].m_ColoredPlayerText + " : " + m_Tanks[i].m_Wins + " WINS\n";
        }

        if (m_GameWinner != null)
        {
            message = m_GameWinner.m_ColoredPlayerText + " WINS THE GAME!";
            m_UISoundManager.PlayMatchWinnerSFX();
        }
        return message;
    }


    private void ResetAllTanks()
    {
        for (int i = 0; i < m_Tanks.Count; i++)
        {
            m_Tanks[i].Reset();
        }
    }


    private void EnableTankControl()
    {
        for (int i = 0; i < m_Tanks.Count; i++)
        {
            m_Tanks[i].EnableControl();
        }
    }


    private void DisableTankControl()
    {
        for (int i = 0; i < m_Tanks.Count; i++)
        {
            m_Tanks[i].DisableControl();
        }
    }

    private void ResetAllCameraEffects()
    {
        for(int i = 0; i < gameObject.GetComponent<SplitscreenManager>().m_cameraList.Count; i++)
        {
            gameObject.GetComponent<SplitscreenManager>().m_cameraList[i].GetComponent<UnityStandardAssets.ImageEffects.Grayscale>().enabled = false;
            gameObject.GetComponent<SplitscreenManager>().m_cameraList[i].GetComponent<VHSPostProcessEffect>().enabled = false;
        }        
    }

    public void PauseGame(bool isPaused)
    {
        if(isPaused)
        {
            gameIsPaused = true;
            canvasPauseMenu.SetActive(true);
            messageCanvas.SetActive(false);
            Time.timeScale = 0;
        }
        else if (!isPaused)
        {
            gameIsPaused = false;
            canvasPauseMenu.SetActive(false);
            messageCanvas.SetActive(true);
            Time.timeScale = 1;
        }
    }

    public void IsInOptionsSwitchTo(bool state)
    {
        isInOptions = state;
    }

    public void BackToMenu(float delay)
    {
        StartCoroutine("BackToMenuCoroutine", delay);
    }

    public IEnumerator BackToMenuCoroutine(float delay)
    {
        Time.timeScale = 1;
        yield return new WaitForSeconds(delay);
        Application.LoadLevel(0);
    }

    public void QuitApplication()
    {
        Application.Quit();
    }
}