﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun;
using TMPro;

public class SpectatorController : MonoBehaviour {

	//BasicCameraBehaviour basicCameraBehaviour;
    GameObject player;
    bool localPlayerFound = false;
    GameObject[] playerObjs;
    int currentSpectatingPlayerViewID;
    CamController cameraController;
    string spectatingPlayerName;

    public TextMeshProUGUI usernameText;
    public FreeCameraFly freeCameraFlyScript;
    public CamController camControllerScript;
    public Rotate rotateScript;
    public bool freeFlying;
    bool m_mouseCaptured = false;


    // Use this for initialization
    void Start ()
    {
        InitializeSpectatorController();
    }

    private void InitializeSpectatorController()
    {
        // Default spectating behavior is to follow, not freefly
        freeFlying = false;

        m_mouseCaptured = false;

        Cursor.visible = true;
        Cursor.lockState = CursorLockMode.None;

        // Get the "Camera Pivot" component of the spectator controller
        Transform camPivot = GameObject.FindGameObjectWithTag("Camera Pivot").transform;

        // Get the BasicCameraBehavior script reference from the first child of the pivot
	    //basicCameraBehaviour = camPivot.GetChild(0).GetComponent<BasicCameraBehaviour>();

        // Get the main camera's camera controller reference
        cameraController = GameObject.FindGameObjectWithTag("MainCamera").GetComponent<CamController>();
    }

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

        if (IsCurrentlySpectatingPlayer())
        {
            if (Input.GetMouseButtonDown(0) && !m_mouseCaptured && player)
                m_mouseCaptured = true;

            if (Input.GetKeyDown(KeyCode.Escape) || Input.GetKeyDown(KeyCode.LeftAlt))
                m_mouseCaptured = !m_mouseCaptured;

            Cursor.visible = !m_mouseCaptured;
            Cursor.lockState = m_mouseCaptured ? CursorLockMode.Locked : CursorLockMode.None;

            if (Input.GetKeyDown(KeyCode.Alpha1)) 
            {
                camControllerScript.enabled = true;
                freeCameraFlyScript.enabled = false;
                freeFlying = false;
            }
            if (Input.GetKeyDown(KeyCode.Alpha2)) 
            {
                camControllerScript.enabled = false;
                freeCameraFlyScript.enabled = true;
                rotateScript.enabled = false;
                freeFlying = true;
            }

            playerObjs = GameObject.FindGameObjectsWithTag("Player");

			if (!freeFlying) 
            {
				if (Input.GetKeyDown (KeyCode.A)) {
					SwitchSpectate (true);
				}
				if (Input.GetKeyDown (KeyCode.D)) {
					SwitchSpectate (false);
				}
				if (Input.GetKeyDown (KeyCode.W)) {

				}
				if (Input.GetKeyDown (KeyCode.S)) {

				}

                camControllerScript.transform.parent.position = player.transform.position;
                camControllerScript.transform.parent.rotation = Quaternion.Euler(camControllerScript.orbit.xRotation, camControllerScript.orbit.yRotation, 0);
            }
        }

        // Update the spectator text display if we have a spectated player
		if (spectatingPlayerName != "") 
        {
			usernameText.text = spectatingPlayerName;
			usernameText.fontSize = 20f;
		} 
        else 
        {
			usernameText.text = "";
			usernameText.fontSize = 20f;
		}
    }

    public void SwitchSpectate(bool left) 
    {
        PlayerBase lastPlayer = null;

        if (playerObjs == null)
            return;

        for(int i = 0; i < playerObjs.Length; i++) {
            PlayerBase player;
            if (player = playerObjs[i].GetComponent<PlayerBase>()){
                if (player.photonView && player.photonView.ViewID == currentSpectatingPlayerViewID) {
                    if (left) {
                        if(lastPlayer)
                            SpectatePlayer(lastPlayer.transform);
                        else {
                            SpectatePlayer(playerObjs[playerObjs.Length - 1].transform);
                        }
                    }
                    else {
                        if (playerObjs.Length - 1 != i)
                            SpectatePlayer(playerObjs[i + 1].transform);
                        else
                            SpectatePlayer(playerObjs[0].transform);
                    }
                    return;
                }
                lastPlayer = player;
            }
        }
    }

    public void SpectateAnyPlayer() {
        Transform t = PlayerBase.GetNetworkPlayer();
        if(t == null) {
            return;
        }
        cameraController.MoveToSpecificTarget(t.GetComponent<PlayerBase>());
        SpectatePlayer(t);
    }

    public void SpectatePlayer(Transform t) {
        if (t) {
            if(player) {
                PlayerBase oldPlayerBase = player.GetComponent<PlayerBase>();
                oldPlayerBase.Spectating = false;
            }
            player = t.gameObject;
            PlayerBase playerBase = t.GetComponent<PlayerBase>();
            playerBase.Spectating = true;
            currentSpectatingPlayerViewID = playerBase.photonView.ViewID;

            object prop;
            if(playerBase.photonView.Owner.CustomProperties.TryGetValue("DisplayName", out prop)) {
                spectatingPlayerName = (string)prop;
            }

            Debug.Log(spectatingPlayerName);

	        //basicCameraBehaviour.ChangeCameraTarget(t);
        }
    }

    public bool IsCurrentlyPlaying() {
        if (localPlayerFound && player)
            return true;
        if (!PhotonNetwork.IsConnected) {
            player = GameObject.FindGameObjectWithTag("Player");
            return player != null;
        }

        GameObject[] players = GameObject.FindGameObjectsWithTag("Player");
        for (int i = 0; i < players.Length; i++) {
            PhotonView view = players[i].GetPhotonView();
            if (view && view.IsMine) {
                player = players[i];
                localPlayerFound = true;
                return true;
            }
        }
        return false;
    }

    public bool IsCurrentlySpectatingPlayer() {
        if (!PhotonNetwork.IsConnected) {
            return false;
        }

        GameObject[] players = GameObject.FindGameObjectsWithTag("Player");
        for (int i = 0; i < players.Length; i++) {
            PhotonView view = players[i].GetPhotonView();
            if (view && !view.IsMine && players[i].GetComponent<PlayerBase>().Spectating)
                return true;
        }
        return false;
    }
}
