using System.Collections.Generic;

using UnityEngine;
using UnityEngine.UI;

using Sfs2X;
using Sfs2X.Core;
using Sfs2X.Entities;
using Sfs2X.Entities.Variables;
using Sfs2X.Requests;

/**
 * Script attached to the Controller object in the Game scene.
 */
public class GameSceneController : BaseSceneController
{
	//----------------------------------------------------------
	// UI elements
	//----------------------------------------------------------

	public Text loggedInAsLabel;
	public Text interactionTextArea;
	public ScrollRect interactionScrollView;

	//----------------------------------------------------------
	// Private properties
	//----------------------------------------------------------

	private SmartFox sfsLobby;
	private SmartFox sfsGame;

	//----------------------------------------------------------
	// Unity callback methods
	//----------------------------------------------------------
	#region
	private void Start()
	{
		Debug.Log("GAME SCENE - Scene loaded");

		// Get reference to static SmartFox client instances for the lobby and game nodes
		sfsLobby = gm.GetLobbyClient();
		sfsGame = gm.GetGameClient();

		// Add game-related SmartFox event listeners
		AddSmartFoxGameListeners();

		// NOTE
		// If this scene needed its own lobby-related SmartFox event listeners, they should be added now
		// In such case, listeners must be removed in the RemoveSmartFoxListeners method below

		// Display username in footer
		loggedInAsLabel.text = "Logged in as <b>" + sfsGame.MySelf.Name + "</b>";
	}
	#endregion

	//----------------------------------------------------------
	// Abstract methods from BaseSceneController implementation
	//----------------------------------------------------------
	#region
	/**
	 * Remove all SmartFoxServer-related event listeners added by the scene.
	 * This method is called by the parent BaseSceneController.OnDestroy method when the scene is destroyed.
	 */
	override protected void RemoveSmartFoxListeners()
	{
		// Remove game-related SmartFox event listeners
		RemoveSmartFoxGameListeners();

		// Remove lobby-related SmartFox event listeners
		// NONE

		Debug.Log("GAME SCENE - No lobby node event listeners to remove");
	}

	override public void ShowError(string errorMsg)
	{
		// Nothing to do
	}

	override protected void HideModals()
	{
		// Nothing to do
	}
	#endregion

	//----------------------------------------------------------
	// UI event listeners
	//----------------------------------------------------------
	#region
	/**
	 * On interact button click, update user variable.
	 */
	public void OnInteractButtonClick()
	{
		UserVariable clickVar = sfsGame.MySelf.GetVariable("click");

		if (clickVar == null)
			clickVar = new SFSUserVariable("click", 1);
		else
			clickVar = new SFSUserVariable("click", clickVar.GetIntValue() + 1);

		sfsGame.Send(new SetUserVariablesRequest(new List<UserVariable>() { clickVar }));
	}

	/**
	 * On leave button click, disconnect from SmartFoxServer.
	 * This causes the SmartFox listeners added by this scene to be removed (see BaseSceneController.OnDestroy method)
	 * and the Lobby scene to be loaded (see SFClusterClientManager.OnGameConnectionLost method).
	 */
	public void OnLeaveButtonClick()
	{
		// Disconnect from game node
		sfsGame.Disconnect();
	}

	/**
	 * On Kill button click, kill the connection to game node.
	 */
	public void OnKillGameButtonClick()
	{
		sfsGame.KillConnection();
	}

	/**
	 * On Kill button click, kill the connection to lobby node.
	 */
	public void OnKillLobbyButtonClick()
	{
		sfsLobby.KillConnection();
	}
	#endregion

	//----------------------------------------------------------
	// Helper methods
	//----------------------------------------------------------
	#region
	/**
	 * Add all SmartFoxServer game-related event listeners required by the scene.
	 */
	private void AddSmartFoxGameListeners()
	{
		Debug.Log("GAME SCENE - Adding game node event listeners");

		sfsGame.AddEventListener(SFSEvent.USER_ENTER_ROOM, OnUserEnterRoom);
		sfsGame.AddEventListener(SFSEvent.USER_EXIT_ROOM, OnUserExitRoom);
		sfsGame.AddEventListener(SFSEvent.USER_VARIABLES_UPDATE, OnUserVariablesUpdate);
	}

	/**
	 * Remove all SmartFoxServer game-related event listeners added by the scene.
	 */
	private void RemoveSmartFoxGameListeners()
	{
		Debug.Log("GAME SCENE - Removing game node event listeners");

		sfsGame.RemoveEventListener(SFSEvent.USER_ENTER_ROOM, OnUserEnterRoom);
		sfsGame.RemoveEventListener(SFSEvent.USER_EXIT_ROOM, OnUserExitRoom);
		sfsGame.RemoveEventListener(SFSEvent.USER_VARIABLES_UPDATE, OnUserVariablesUpdate);
	}

	/**
	 * Display interaction.
	 */
	private void PrintInteraction(string message)
	{
		// Print message
		interactionTextArea.text += message + "\n";

		// Scroll view to bottom
		Canvas.ForceUpdateCanvases();
		interactionScrollView.verticalNormalizedPosition = 0;
	}
	#endregion

	//----------------------------------------------------------
	// SmartFoxServer event listeners
	//----------------------------------------------------------
	#region
	private void OnUserEnterRoom(BaseEvent evt)
	{
		Debug.Log("GAME SCENE - User entered Game Room");

		User user = (User)evt.Params["user"];
		Room room = (Room)evt.Params["room"];

		PrintInteraction("User " + user.Name + " joined this game");
	}

	private void OnUserExitRoom(BaseEvent evt)
	{
		Debug.Log("GAME SCENE - User left Game Room");

		User user = (User)evt.Params["user"];

		if (user != sfsGame.MySelf)
			PrintInteraction("User " + user.Name + " left the game");
	}

	private void OnUserVariablesUpdate(BaseEvent evt)
	{
		Debug.Log("GAME SCENE - User Variables updated");

		User user = (User)evt.Params["user"];

		int clickNum = user.GetVariable("click").GetIntValue();

		PrintInteraction("User " + user.Name + " clicked the button " + clickNum + " time" + (clickNum != 1 ? "s" : ""));
	}
	#endregion
}
