/*******************************************************************************************
 * 
 * TITLE: 		SFS2X Space Race
 * VERSION:		1.0
 * RELEASE:		2011-03-15
 * COPYRIGHT:	2011 gotoAndPlay() - http://www.smartfoxserver.com
 * DEVELOPER:	A51 Integrated - http://a51integrated.com
 * 
 * This file is part of SFS2X Space Race.
 * 
 * Contributers: Wayne Helman, Fabricio Medeiros, David Irons,
 * 				 Steve Schoger, Ryan Albrecht, Andy Rohan
 * 
 * SFS2X Space Race is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * included license for more details.
 *
 * You are not allowed to rent, lend, lease, license or distribute SFS2X Space Race or a
 * modified version of SFS2X Space Race to any other person or organization in any way.
 * 
 * For commercial licensing information, please contact gotoAndPlay().
 * 
 *******************************************************************************************/

package sfs2x.extensions.games.spacerace.handlers;

import com.smartfoxserver.v2.SmartFoxServer;
import com.smartfoxserver.v2.core.ISFSEvent;
import com.smartfoxserver.v2.core.SFSEventParam;
import com.smartfoxserver.v2.entities.Zone;
import com.smartfoxserver.v2.entities.Room;
import com.smartfoxserver.v2.entities.User;
import com.smartfoxserver.v2.entities.data.ISFSObject;
import com.smartfoxserver.v2.entities.data.SFSObject;
import com.smartfoxserver.v2.entities.variables.ReservedRoomVariables;
import com.smartfoxserver.v2.entities.variables.RoomVariable;
import com.smartfoxserver.v2.entities.variables.SFSRoomVariable;
import com.smartfoxserver.v2.entities.variables.UserVariable;
import com.smartfoxserver.v2.exceptions.SFSException;
import com.smartfoxserver.v2.exceptions.SFSVariableException;
import com.smartfoxserver.v2.extensions.BaseServerEventHandler;


import java.util.ArrayList;
import java.util.List;
import java.util.Iterator;

import sfs2x.extensions.games.spacerace.SpaceRaceZoneExtension;

/**
 * SFS2X Space Race demo - OnUserVarChange Event Handler
 * Called when a userVariable change event is fired
 *  
 * @author A51 Integrated
 *
 */
public class OnUserVarChange extends BaseServerEventHandler
{	
	SpaceRaceZoneExtension zoneExt;
	Room curRoom;
	Zone curZone;
	
	boolean start = true;
	ISFSObject obj = new SFSObject();
	
	
	@SuppressWarnings("unchecked")
	@Override
	public void handleServerEvent(ISFSEvent event) throws SFSException
	{ 		
    	// Obtain the user who fired the event and the room they are in
		User player = (User) event.getParameter(SFSEventParam.USER);
    	curRoom = player.getLastJoinedRoom();		
	
		// We set UserVariable before joining a room, if this is the case, ignore this event
		if(curRoom == null) return;
		
		// Obtain a reference to the parent extension and the current Zone
		zoneExt = (SpaceRaceZoneExtension) getParentExtension();
		curZone = zoneExt.getZone();
		
		// Obtain a reference to the 'lobby' room
		Room lobby = curZone.getRoomByName(SpaceRaceZoneExtension.LOBBY_ROOM);
		
		// Get the list of variables that have changed
		List<UserVariable> vars	= (List) event.getParameter(SFSEventParam.VARIABLES);

		if(curRoom.isGame()) // the player is in a game
		{			
			// Add the player name to the object so all users know who has updated their UserVariable
			obj.putUtfString(SpaceRaceZoneExtension.PLAYER_NAME, player.getName());
			
			Iterator<UserVariable> iterator = vars.iterator();
			while (iterator.hasNext())
			{				
				UserVariable uVar = iterator.next();
				String changedVar = uVar.getName();
				
				/* We always send player status updates to the lobby, so we do that before bloating the
				response object with other data. */
				if(changedVar.equals(SpaceRaceZoneExtension.PLAYER_STATUS))
				{
					// Add users new status and broadcast to the lobby using UDP
					obj.putUtfString(SpaceRaceZoneExtension.PLAYER_STATUS, uVar.getStringValue());
					zoneExt.send(SpaceRaceZoneExtension.PLAYER_STATUS, obj, lobby.getUserList(), true);
				}
				// When a user updates their status to 'ready' pre-race we check if all users are ready to race
				else if(changedVar.equals(SpaceRaceZoneExtension.PLAYER_READY))
				{
					if(uVar.getBoolValue().equals(true))
					{
						checkStartGate();
					}
				}
			}
		}
	}
    
    /**
     * Check have all users in game room have updated their status to 'Ready'
     * @throws SFSVariableException 
     */
	private void checkStartGate() throws SFSVariableException
	{
		List<User> userList = curRoom.getUserList();
		Iterator<User> iterator = userList.iterator();
			
		
		User u = null;
		notReady:
		// Check all user in the room 
		while (iterator.hasNext())
		{
			u = iterator.next();
			boolean ready = u.getVariable(SpaceRaceZoneExtension.PLAYER_READY).getBoolValue();
			
			// If any user has not indicated they are ready to race then set the game start indicator to false and break
			if (!ready)
			{
				start = false;
				break notReady;
			}
		}
		
		// All users in room have indicated they are ready to race
		if (start)
		{		
			// Create and broadcast a global RoomVariable to notify all users not in game room that game has started
			RoomVariable rv = new SFSRoomVariable(ReservedRoomVariables.RV_GAME_STARTED, true);
			rv.setGlobal(true);
			List<RoomVariable> listOfVars = new ArrayList<RoomVariable>();
			listOfVars.add(rv);
			
			// Update the RoomVariables
			SmartFoxServer.getInstance().getAPIManager().getSFSApi().setRoomVariables(u, curRoom, listOfVars);
			
			// Broadcast, using TCP, 'cd' extension to initiate countdown timer on each client
			zoneExt.send(SpaceRaceZoneExtension.COUNTDOWN, null, curRoom.getUserList(), false);
		}
	}
}
