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

public class NetworkGameManager : MonoBehaviour {

	public const string SERVICE_TYPE = "_ballsup._tcp."; 
	public const string SERVICE_NAME = "ballsup";

	const float TIME_TO_WAIT = 5f;

	[SerializeField]
	Text textMesh;

	IEnumerator oneTouchConnectInitializationEnumerator;

	static bool settingUpMultiplayerPlayMode;
	static bool multiplayerModeSetUp;

	[SerializeField]
	Image buttonGraphic;

	[SerializeField]
	Sprite singlePlayerButtonSprite;

	[SerializeField]
	Sprite multiPlayerButtonSprite;

	[SerializeField]
	GameObject multiPlayerSearchingAnimation;

	[SerializeField]
	int NumberOfTurnsPerPlayer;

	int numberOfTurnsRemaining;

	// Use this for initialization
	void Start () {

		ChangeButtonGraphic();

		if((Network.isClient || Network.isServer) && Application.loadedLevelName == "Main Game")
		{
			numberOfTurnsRemaining = NumberOfTurnsPerPlayer;
			BallManager.onEndOfGame += OnEndOfGame;
			BallManager.onTap += OnTap;
		}
	}

	public void OnPlayModeButtonPressed()
	{
		settingUpMultiplayerPlayMode = !settingUpMultiplayerPlayMode;

		if(settingUpMultiplayerPlayMode)
		{
			OneTouchConnectEventHandler.ServiceFound += OnServiceFound;
			oneTouchConnectInitializationEnumerator = StartOneTouchConnect();
			StartCoroutine(oneTouchConnectInitializationEnumerator );
		}
		else
		{
			if(oneTouchConnectInitializationEnumerator != null)
			{
				StopCoroutine(oneTouchConnectInitializationEnumerator);
				OneTouchConnectInterface.StopSearching();
				OneTouchConnectInterface.UnregisterAService();
				Network.Disconnect();
			}
		}

		ChangeButtonGraphic();
	}

	void ChangeButtonGraphic()
	{
		if(multiplayerModeSetUp)
		{
			// change graphic to multiplayer graphic
			buttonGraphic.sprite = multiPlayerButtonSprite;
			multiPlayerSearchingAnimation.SetActive(false);
		}
		else if(!multiplayerModeSetUp && settingUpMultiplayerPlayMode)
		{
			// Change graphic to searching multiplayer graphic
			multiPlayerSearchingAnimation.SetActive(true);
		}

		else
		{
			// Change graphic to usual one
			buttonGraphic.sprite = singlePlayerButtonSprite;
			multiPlayerSearchingAnimation.SetActive(false);
		}
	}
	
	public IEnumerator StartOneTouchConnect()
	{
		OneTouchConnectInterface.BrowseForServices(SERVICE_TYPE);

		float timer = 0;

		// Five seconds should be enough time, in fact we can rinse and repeat until needed if required.

		while(timer <= TIME_TO_WAIT)
		{
			timer += Time.deltaTime;
			yield return 0;
		}

		Network.InitializeServer(1, 25000, false);

		OneTouchConnectInterface.PublishAService(SERVICE_NAME + SystemInfo.deviceUniqueIdentifier, SERVICE_TYPE, 25000); 
	}

	public void OnServiceFound(ServiceInfo serviceInfo)
	{
		Network.Disconnect();
		textMesh.text = "Service Found, Attempting Connection";
		if(oneTouchConnectInitializationEnumerator != null)
		{
			StopCoroutine(oneTouchConnectInitializationEnumerator);
		}
		Network.Connect(serviceInfo.ipAddress, 25000);
	}

	public void OnPlayerConnected(NetworkPlayer networkPlayer)
	{
		OneTouchConnectInterface.StopSearching();
		OneTouchConnectInterface.UnregisterAService();
		textMesh.text = "Connected to client";
		multiplayerModeSetUp = true;

		Application.LoadLevel("Main Game");
	}

	public void OnPlayerDisconnected(NetworkPlayer networkPlayer)
	{
		OnDisconnect();
	}

	public void OnConnectedToServer()
	{
		OneTouchConnectInterface.StopSearching();
		OneTouchConnectInterface.UnregisterAService();
		textMesh.text = "Connected to server";
		multiplayerModeSetUp = true;

		Application.LoadLevel("NetworkPlayerScreen");
	}

	void OnDisconnect()
	{
		//Network.Disconnect();
		settingUpMultiplayerPlayMode = false;
		multiplayerModeSetUp = false;
		
		if(Application.loadedLevelName != "Main Game")
		{
			Application.LoadLevel("Main Game");
		}
	}

	void OnEndOfGame()
	{
		numberOfTurnsRemaining--;


		networkView.RPC("OnPlayerLose", RPCMode.All);
	}

	[RPC]
	void OnPlayerLose()
	{
		if(numberOfTurnsRemaining <= 0)
		{
			// We're probably going to need something saying game over here.
			// For now we'll just invoke with a small delay.

			Invoke("OnPlayerTurnFinishedDelay", 2.0f);
		}

		// Otherwise just carry on.
	}

	void OnPlayerTurnFinishedDelay()
	{
		networkView.RPC("OnPlayerTurnFinished", RPCMode.All);
	}

	[RPC]
	void OnPlayerTurnFinished()
	{
		Application.LoadLevel("NetworkPlayerScreen");
	}

	public void OnDisconnectedFromServer()
	{
		OnDisconnect();
	}

	void OnDestroy()
	{
		BallManager.onEndOfGame -= OnEndOfGame;
		BallManager.onTap -= OnTap;
	}

	void OnTap()
	{
		networkView.RPC("SendTap", RPCMode.All);
	}

	[RPC]
	void SendTap()
	{

	}

}
