using System;
using System.Collections.Generic;

using UnityEngine;
using UnityEngine.UI;

using Sfs2X;
using Sfs2X.Entities.Match;
using Sfs2X.Requests.Cluster;
using Sfs2X.Util;
using Sfs2X.Entities;

/**
 * Script attached to the Controller object in the Lobby scene.
 */
public class LobbySceneController : BaseSceneController
{
	public static string GAME_ROOMS_GROUP_NAME = "games";
    public static string GAME_ROOM_NAME_PREFIX = "MockRoom";

    //----------------------------------------------------------
    // UI elements
    //----------------------------------------------------------

    public Text loggedInAsLabel;
    public WaitingPanel waitingPanel;
    public WarningPanel warningPanel;

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

    private SmartFox sfsLobby;

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

		// Get reference to static SmartFox client instance for the lobby
		sfsLobby = gm.GetLobbyClient();

		// 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>" + sfsLobby.MySelf.Name + "</b>";

		// Check if a connection lost message should be displayed
		CheckConnectionLost();
	}
	#endregion

	//----------------------------------------------------------
	// Abstract methods from BaseSceneController implementation
	//----------------------------------------------------------
	#region
	override protected void RemoveSmartFoxListeners()
	{
		// Nothing to do, this scene didn't add dedicated listeners

		Debug.Log("LOBBY SCENE - No event listeners to remove");
	}

	override public void ShowError(string errorMsg)
	{
		// Display connection or login error
		warningPanel.Show(errorMsg);
	}

	override protected void HideModals()
	{
		warningPanel.Hide();
	}

    //----------------------------------------------------------

    override public void OnGameJoinFailed()
    {
        // Schedule another request to join or create a game
        Invoke("JoinOrCreateRoom", 2);
    }

    #endregion

    //----------------------------------------------------------
    // UI event listeners
    //----------------------------------------------------------
    #region
    /**
	 * On Logout button click, disconnect from SmartFoxServer.
	 * This causes the SmartFox listeners added by this scene to be removed (see BaseSceneController.OnDestroy method)
	 * and the Login scene to be loaded (see GlobalManager.OnLobbyNodeConnectionLost method).
	 */
    public void OnLogoutButtonClick()
	{
		// Disconnect from lobby node
		sfsLobby.Disconnect();
	}

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

	/**
	 * On Play button click, send request to lobby to join a random game Room (or create one if none is available).
	 */
	public void OnPlayButtonClick()
    {
        // Show waiting message
		waitingPanel.Show();
        
        // Request to join or create game Room
        JoinOrCreateRoom();
    }

    /**
	 * On Cancel button click, stop requesting to join or create a game Room to lobby.
	 */
    public void OnCancelButtonClick()
	{
        CancelInvoke("JoinOrCreateRoom");

        // Hide waiting message
        waitingPanel.Hide();
    }
    #endregion

    //----------------------------------------------------------
    // Helper methods
    //----------------------------------------------------------
    #region
    /**
	 * Join or create a geme Room.
	 */
    private void JoinOrCreateRoom()
    {
		// Set the match expression to search for an existing game Room
        MatchExpression exp = new MatchExpression(RoomProperties.NAME, StringMatch.STARTS_WITH, GAME_ROOM_NAME_PREFIX);

        // Set the Room settings to create a new game Room if one is not found
        // The Room is assigned a name allowing the above match expression find it when other users will try to join
        ClusterRoomSettings settings = new ClusterRoomSettings("MockRoom__" + new System.Random().Next());
        settings.GroupId = GAME_ROOMS_GROUP_NAME;
        settings.IsPublic = true;
        settings.IsGame = true;
        settings.MaxUsers = 2;
        settings.MaxSpectators = 0;
        settings.MinPlayersToStartGame = 2;
        settings.NotifyGameStarted = false;

        sfsLobby.Send(new ClusterJoinOrCreateRequest(exp, new List<string>() { GAME_ROOMS_GROUP_NAME }, settings));
    }
    #endregion
}
