//**********************************************************************************
// This file was originally modified from Mayhem 2090 client Client - John W Vanderbeck
// This file has been modified by Karl Wang to work with Unexceptional.net protocol
//**********************************************************************************
$GRID_PROTO::RECEIVE_INV = "1";
$GRID_PROTO::SEND_INV = "2";
$GRID_PROTO::SEND_STATS = "3";
$GRID_PROTO::RECEIVE_STATS = "4";
$GRID_PROTO::AUTH_USER = "5";
$GRID_PROTO::QUERY_PLAYER_ID = "6";
$GRID_PROTO::GET_STREET_IMG_LOC = "7";
$GRID_PROTO::GET_STRUCTURE_IMG_LOC = "8";
$GRID_PROTO::GET_REGION_INFO = "9";
$GRID_PROTO::DELIM = "|";
$GRID_PROTO::EOF_DELIM = "~";
$GRID_PROTO::EOL_DELIM = "$";

//New Protocol
$GRID_PROTO::AUTHORIZE = "Au";
$GRID_PROTO::LOAD_PLAYER = "LdPl";
$GRID_PROTO::SAVE_PLAYER = "SvPl";
$GRID_PROTO::LOAD_LOCAL_REGION_LIST = "LdLR";
$GRID_PROTO::LOAD_REGION = "LdRg";
$GRID_PROTO::LOAD_CHAR = "LdCh";
$GRID_PROTO::LOAD_QUEST = "LdQ";
$GRID_PROTO::COMPLETE_QUEST = "QC";

$GRID_PROTO::END_ENTRY = "|";
$GRID_PROTO::END_TUPLE = ":";
$GRID_PROTO::END_COMMAND = "";
$GRID_PROTO::END_CONNECTION = "^";
$GRID_PROTO::ESCAPE_CHAR = "/";

$GRID_PROTO::currentTOT = "0"; // TOT (Type of Transaction)

$GRID_PROTO::SUCCESS = "S";
$GRID_PROTO::ERROR = "E";
$GRID_PROTO::GUY_PLAYER_ID = "17";

//-------Address of Servlet-------\\
$SERVER_ADDRESS = "gamelab.no-ip.info";

$connected = false;
$password = "";
$userid = "";

$regionLoaded = 0;
$isLoaded = 0;

//-----------------------------------------------------------------------------
// Load up default console values.

$GRID_PROTO::NUM_OF_ITEM_TYPES = 31;
$GRID_PROTO::NUM_OF_ITEM_DATA = 5;
$GRID_PROTO::NUM_OF_STAT_TYPES = 8;
$GRID_PROTO::NUM_OF_STAT_DATA = 4;

// temporary storage of stats and items until datablocks are set up
// linked to the gui variables/datablocks

//format:ID | Item Name | Item Desc | Amt Held   Amt Used ***
$playerItems[$GRID_PROTO::NUM_OF_ITEM_TYPES,$GRID_PROTO::NUM_OF_ITEM_DATA]="";

//***format:ID | Stat Name | Amt | Stat Desc ***
$playerStats[$GRID_PROTO::NUM_OF_STAT_TYPES,$GRID_PROTO::NUM_OF_STAT_DATA]="";

//*********************************************************
// client Client Overview
//
// The underlying concept here is to totally seperate the
// networking/client code from the GUI.  This will not only
// make it more clear, it will allow easy changes to the
// GUI in just a few minutes worth of work.
//
// Function named prefixed with "client" are underlying client
// calls, while those prefixed by "gui" are gui hooks.
//*********************************************************

// Instructs the underlying client code to attempt a connection
// to the specified server on the specified port.  The user
// will be logged in with the specified nickname.
function clientConnect(%server, %port, %phoneNumber)
{

	// build address string (server:port)
	%address = %server @ ":" @ %port;

	// create a new TCPObject for our network code
	new TCPObject(clientConnection);

	echo(%address);
	// attempt to connect to the server
	clientConnection.connect(%address);

	// flag us as not connected at this point
	$connected = false;

	// save our nickname
	//$username = %username;
	//$password = %password;
	//if(%password $= ""){}
	//else{clientLogin(%password);}

	$phoneNumber = %phoneNumber;
}


function authorize(%phoneNumber)
{
	//Build Command	
	%command = $GRID_PROTO::AUTHORIZE @ $GRID_PROTO::END_ENTRY @ $GRID_PROTO::END_TUPLE
	           @ %phoneNumber @ $GRID_PROTO::END_ENTRY @ $GRID_PROTO::END_TUPLE
	           @ $GRID_PROTO::END_COMMAND;

	//Print Command to Console
	echo(%command);

	//Send Command with Null Character at the end
	clientConnection.sendWithNull(%command);

	//Set current token for purpopse of handling the command response
	$GRID_PROTO::currentTOT = $GRID_PROTO::AUTHORIZE;
}

function authorizeResponse(%line)
{
	//[Player ID][Name][Player's Latitude][Player's Longitude]

	echo("User has been authenticated");
	echo("Line: " @%line);

	//User ID
	%startPos = 0;
	%endPos = strpos(%line, $GRID_PROTO::END_ENTRY, %startPos);

	$userid = getSubStr(%line, %startPos, %endPos - %startPos);
	playerID();

	//User Name
	%startPos = %endPos + 1;
	%endPos = strpos(%line, $GRID_PROTO::END_ENTRY, %startPos);

	$username = getSubStr(%line, %startPos, %endPos - %startPos);
	echo("User = " @ $username);

	//Latitude
	%startPos = %endPos + 1;
	%endPos = strpos(%line, $GRID_PROTO::END_ENTRY, %startPos);

	$playerLat = getSubStr(%line, %startPos, %endPos - %startPos);

	//Longitude
	%startPos = %endPos + 1;
	%endPos = strpos(%line, $GRID_PROTO::END_ENTRY, %startPos);

	$playerLon = getSubStr(%line, %startPos, %endPos - %startPos);
	
	$playerLat = $playerLat / 10;
	$playerLon = $playerLon / 10;
	
	$PlayerRealLat = $playerLat;
	$PlayerRealLon = $playerLon;

	echo("Player Lat, Long: ( " @ $playerLat @ " , " @ $playerLon @ " )");
	
	test();
	
}

function test()
{
	if($loadingDone == 1)
	{
		error("---------------- Loading-----------------------");
		load();
	}
	else
	{
		error("waiting");
		schedule(25, 0, test);
	}
}

function load()
{
	%command = $GRID_PROTO::LOAD_PLAYER @ $GRID_PROTO::END_ENTRY @ $GRID_PROTO::END_TUPLE
		   @ $userid @ $GRID_PROTO::END_ENTRY @ $GRID_PROTO::END_TUPLE
		   @ $GRID_PROTO::END_COMMAND;

	echo(%command);

	clientConnection.sendWithNull(%command);

	$GRID_PROTO::currentTOT = $GRID_PROTO::LOAD_PLAYER;
}

function loadResponse(%line)
{
	echo("Player has been loaded");
	echo("Line: " @%line);

	//[Inventory Size][Statistics Size]
	//[ID][Name][Description][Amount Held][is Chakra Key][Item Maximum Limit][is Visible][Item Worth]
	//[ID][Name][Current Value][Description][is Visible]

	//Inventory Size
	%startPos = 0;
	%endPos = strpos(%line, $GRID_PROTO::END_ENTRY, %startPos);

	%inventorySize = getSubStr(%line, %startPos, %endPos - %startPos);

	//Statistics Size
	%startPos = %endPos + 1;
	%endPos = strpos(%line, $GRID_PROTO::END_ENTRY, %startPos);

	%statisticsSize = getSubStr(%line, %startPos, %endPos - %startPos);

	echo("Statistics Size: " @ %statisticsSize);

	//Create wrapper for inventory array
	//Work around for array passing limitation
	//$inventory = new ScriptObject();
	$loadInventory = new ScriptObject();

	//Go to start of Inventory
	%startPos = strpos(%line, $GRID_PROTO::END_TUPLE, %endPos) + 1;
	%endPos = strpos(%line, $GRID_PROTO::END_TUPLE, %startPos);

	//Build Invetory Array
	for(%i = 0; %i < %inventorySize; %i++)
	{
		%inventoryString = getSubStr(%line, %startPos, %endPos - %startPos);

		%invStartPos = 0;
		%invEndPos = strpos(%inventoryString, $GRID_PROTO::END_ENTRY, %invStartPos);
		%ctr = 0;

		while(%invEndPos != -1)
		{
			$loadInventory.contents[%i, %ctr] = getSubStr(%inventoryString, %invStartPos, %invEndPos - %invStartPos);

			%invStartPos = %invEndPos + 1;
			%invEndPos = strpos(%inventoryString, $GRID_PROTO::END_ENTRY, %invStartPos);
			%ctr++;
		}

		%startPos = %endPos + 1;
		%endPos = strpos(%line, $GRID_PROTO::END_TUPLE, %startPos);
	}

	$loadInventory.count = %inventorySize;

	setInventory($loadInventory);
	
//	echo("PARSED INVENTORY:");
//	for(%i = 0; %i < %inventorySize; %i++)
//	{
//		%curr = "";
//
//		for(%j = 0; %j < 1; %j++)
//		{
//			%curr = $inventory.contents[%i, 0] @ " " @ $inventory.contents[%i, 1] @ ":  " @ $inventory.contents[%i, 3];
//		}
//		echo(%curr);
//	}

	$loadStatistics = new ScriptObject();

	//Build Statistics Array
	for(%i = 0; %i < %statisticsSize; %i++)
	{
		%statisticsString = getSubStr(%line, %startPos, %endPos - %startPos);

		%statStartPos = 0;
		%statEndPos = strpos(%statisticsString, $GRID_PROTO::END_ENTRY, %statStartPos);
		%ctr = 0;

		while(%statEndPos != -1)
		{
			$loadStatistics.contents[%i, %ctr] = getSubStr(%statisticsString, %statStartPos, %statEndPos - %statStartPos);

			%statStartPos = %statEndPos + 1;
			%statEndPos = strpos(%statisticsString, $GRID_PROTO::END_ENTRY, %statStartPos);
			%ctr++;
		}

		%startPos = %endPos + 1;
		%endPos = strpos(%line, $GRID_PROTO::END_TUPLE, %startPos);
	}

	$loadStatistics.count = %statisticsSize;

	setStatistics($loadStatistics);

	//echo("PARSED STATISTICS:");
	//for(%i = 0; %i < %statisticsSize; %i++)
	//{
		//%curr = "";

		//for(%j = 0; %j < %ctr; %j++)
		//{
			//%curr = %curr @ " | " @ %statistics.contents[%i, %j];
		//}
		//echo(%curr);
	//}

   	//Build Inventory Scripts
   	echo("\c2BUILDING SCRIPTS");
   	createScripts();
   	
    	for(%i = 0; %i < %inventorySize; %i++)
    	{
    		echo($inventory.contents[%i, 1]);
    		%itemName = $inventory.contents[%i, 1];
 
 		if( getWord(%itemName, 1) !$= "" )
 			%itemName = getWord(%itemName, 0) @ "_" @ getWord(%itemName, 1);
 		
 		exec("~/data/inventory/" @ %itemName @ ".cs");   	
    	}
    	
    	error("-------------ttttt------" @ $playerLat @ " " @ $playerLon @ "-----------------");
	//Improve Loading time?
	//schedule(7500, 0, loadRegion, $playerLat, $playerLon);
	loadRegion($playerLat, $playerLon);
	
	//Initial Region selected = 1st region
	// Can be modified so none is selected
	$RegionSelected = 1;

}

function save()
{
	echo("SAVING PLAYER");
//	BE CAREFUL WHEN TESTING - WHEN COMMENTING OUT PARTS OF THE COMMAND, CERTAIN END TUPLES
//	WILL BE LEFT OUT OF THE COMMAND CAUSING IT TO MALFUNCTION. CHECK SERVER DOC FOR MORE INFO.
	
//	Command format:
//	[Player ID]
//	[Inventory Update Size]		represents # of inventory types that were changed
//	[Statistics Update Size]	represents # of stat types changed
	
//	for( inventory update size )
//		[ID][Change]
	
//	for( stat update size )
//		[ID][Change]

//	[Player Identity]
//	[Latitude][Longitude]
//	

	%inventory = getInventory();
	%statistics = getStatistics();
	
	//Need to figure out how to determine new player latitude and longitude
	//$playerLat =  "33.6671982";
	//$playerLon =  "-117.79540";

	// SvPl|:[Player ID]|
	%command = $GRID_PROTO::SAVE_PLAYER @ $GRID_PROTO::END_ENTRY @ $GRID_PROTO::END_TUPLE
		   @ $userid @ $GRID_PROTO::END_ENTRY;

	%changes = 0;
	
	%inventoryCommand = "";

	for(%i = 0; %i < %inventory.count; %i++)
	{
		if( $playerItems[%i, 3] != 0 )
		{
			
			%changes++;

			%difference = $playerItems[%i, 3];

			%inventoryCommand = %inventoryCommand @ %inventory.contents[%i, 0] @ $GRID_PROTO::END_ENTRY
								@ %difference @ $GRID_PROTO::END_ENTRY
								@ $GRID_PROTO::END_TUPLE;
								
			$playerItems[%i, 3] = 0;	//set back to zero to track new changes
		}
	}

	//[Inventory Update Size]
	%command = %command @ %changes @ $GRID_PROTO::END_ENTRY;

	%changes = 0;

	%statisticsCommand = "";

	for(%i = 0; %i < %statistics.count; %i++)
	{
		if(%statistics.contents[%i, 3] != $loadStatistics.contents[%i, 3])
		{
			%changes++;

			%difference = %statistics.contents[%i, 3] - $loadStatistics[%i, 3];

			%statisticsCommand = %statisticsCommand @ %statistics.contents[%i, 0] @ $GRID_PROTO::END_ENTRY
								@ %difference @ $GRID_PROTO::END_ENTRY
								@ $GRID_PROTO::END_TUPLE;
		}
	}

	//[Stat Update Size]
	%command = %command @ %changes @ $GRID_PROTO::END_ENTRY @ $GRID_PROTO::END_TUPLE;
	
	//Player Identity ID not used anymore  If this needs to
	//be updated in the future, uncomment next line and comment out last line
	//%command = %command @ "1" @ $GRID_PROTO::END_ENTRY @ $GRID_PROTO::END_TUPLE;
	%command = %command @ $GRID_PROTO::END_TUPLE;

	//[Latitude][Longitude]
	
	
	
	//Converting Lat/Lon back to 4 decimal places.
	
	if(strpos($playerLat, ".", 0) < 1)
		%lat = $playerLat @ 0;
	else
		%lat = $playerLat * 10;

	if(strpos($playerLon, ".", 0) < 1)
		%lon = $playerLon @ 0;
	else	
		%lon = $playerLon * 10;
	
	%latUnits = getSubStr(%lat, 0, strlen(%lat) - 4);
	%latDecimal = getSubStr(%lat, strlen(%lat) - 4, 4);
	%newLat = %latUnits @ "." @ %latDecimal;
	
	%lonUnits = getSubStr(%lon, 0, strlen(%lon) - 4);
	%lonDecimal = getSubStr(%lon, strlen(%lon) - 4, 4);
	%newLon = %lonUnits @ "." @ %lonDecimal;
		
	//%lat = %newLat;
	//%lon = %newLon;
	
	error("////////////////////NEW LAT LONG: " @ %lat @ ", " @ %lon @ " //////////////////");
	
	
	//%lat = $playerLat @ 0;
	//%lon = $playerLon @ 0;
	
	%command = %command @ %lat @ $GRID_PROTO::END_ENTRY @ %lon @ $GRID_PROTO::END_ENTRY @ $GRID_PROTO::END_TUPLE;

	//Inventory and Stats
	//[ID][Change]
	
	%command = %command @ %inventoryCommand @ %statisticsCommand @ $GRID_PROTO::END_COMMAND;

	echo(%command);

	
	$GRID_PROTO::currentTOT = $GRID_PROTO::SAVE_PLAYER;
	
	clientConnection.sendWithNull(%command);
	
	//Schedules save in 30 seconds
	//schedule(30000, 0, save);
	//schedule(5000, 0, save);
	
}

function loadLocalRegionList()
{
	//[Latitude][Longitude]
	
	if(strpos($playerLat, ".", 0) < 1)
		%lat = $playerLat @ 0;
	else
		%lat = $playerLat * 10;
		
	if(strpos($playerLon, ".", 0) < 1)
		%lon = $playerLon @ 0;
	else	
		%lon = $playerLon * 10;
		
	error("LAT LON HERE: " @ %lat @ ", " @ %lon);
	
	%command = $GRID_PROTO::LOAD_LOCAL_REGION_LIST @ $GRID_PROTO::END_ENTRY @ $GRID_PROTO::END_TUPLE
		 @ %lat @ $GRID_PROTO::END_ENTRY @ %lon @ $GRID_PROTO::END_ENTRY @ $GRID_PROTO::END_TUPLE
		 @ $GRID_PROTO::END_COMMAND;
	
	
	$GRID_PROTO::currentTOT = $GRID_PROTO::LOAD_LOCAL_REGION_LIST;
	
	clientConnection.sendWithNull(%command);
}

function loadLocalRegionListResponse(%line)
{
	echo(%line);
	
	%startPos = 0;
	%endPos = strpos(%line, $GRID_PROTO::END_TUPLE, %startPos);	
	
	%region = getSubStr(%line, %startPos, %endPos - %startPos);
	
	echo("Region Sub String: " @ %region);
	
	%regionArray = new ScriptObject();
	%count = 0;
	
	while(strlen(%region) != 0)
	{
		echo(%region);
		
		//Region Name
		%subStartPos = 0;
		%subEndPos = strpos(%region, $GRID_PROTO::END_ENTRY, %subStartPos);
		
		%regionArray.contents[%count, 0] = getSubStr(%region, %subStartPos, %subEndPos - %subStartPos);
		
		//Latitude
		%subStartPos = %subEndPos + 1;
		%subEndPos = strpos(%region, $GRID_PROTO::END_ENTRY, %subStartPos);
		
		%regionArray.contents[%count, 1] = getSubStr(%region, %subStartPos, %subEndPos - %subStartPos) / 10;
		
		//Longitude
		%subStartPos = %subEndPos + 1;
		%subEndPos = strpos(%region, $GRID_PROTO::END_ENTRY, %subStartPos);
		
		%regionArray.contents[%count, 2] = getSubStr(%region, %subStartPos, %subEndPos - %subStartPos) / 10;
		
		//Radius
		%subStartPos = %subEndPos + 1;
		%subEndPos = strpos(%region, $GRID_PROTO::END_ENTRY, %subStartPos);
		
		%regionArray.contents[%count, 3] = getSubStr(%region, %subStartPos, %subEndPos - %subStartPos);
		
		%count++;
		
		//Get Next Region
		%startPos = %endPos + 1;
		%endPos = strpos(%line, $GRID_PROTO::END_TUPLE, %startPos);
		
		if(%endPos != -1)
			%region = getSubStr(%line, %startPos, %endPos - %startPos);
		else
			%region = "";
	}
	
	%regionArray.count = %count;
	
	echo("Region Count: " @ %regionArray.count);
	
	//Echo Region List
	for(%i = 0; %i < %regionArray.count; %i++)
	{
		echo("-----------------");
		echo("Region: " @ %regionArray.contents[%i, 0]);
		echo("Lat: " @ %regionArray.contents[%i, 1]);
		echo("Lon: " @ %regionArray.contents[%i, 2]);
		echo("Radius: " @ %regionArray.contents[%i, 3]);
	}
	
	setLocalRegionList(%regionArray);	
	
	//Find the region closest to the player and load it	
	//echo("Region Selected: " @ %regionNumber);
	
	$loading2Done = 1;
		
}

function loadRegion(%latitude, %longitude)
{
	if(strpos($playerLat, ".", 0) < 1)
		%lat = %latitude @ 0;
	else
		%lat = %latitude * 10;

	if(strpos($playerLon, ".", 0) < 1)
		%lon = %longitude @ 0;
	else	
		%lon = %longitude * 10;


	//[Latitude][Longitude]
	
	%command = $GRID_PROTO::LOAD_REGION @ $GRID_PROTO::END_ENTRY @ $GRID_PROTO::END_TUPLE
		 @ %lat @ $GRID_PROTO::END_ENTRY @ %lon @ $GRID_PROTO::END_ENTRY @ "0" @ $GRID_PROTO::END_ENTRY @ $GRID_PROTO::END_TUPLE
		 @ $GRID_PROTO::END_ENTRY @ $GRID_PROTO::END_TUPLE
		 @ $GRID_PROTO::END_COMMAND;
	
	
	$GRID_PROTO::currentTOT = $GRID_PROTO::LOAD_REGION;
	
	clientConnection.sendWithNull(%command);
}

function loadRegionResponse(%line)
{
	echo(%line);
	
	//Setup Containers
	%RegionInfo = new ScriptObject();
	%TerrainInfo = new ScriptObject();
	%StructureInfo = new ScriptObject();
	%AvatarInfo = new ScriptObject();
	%CharacterInfo = new ScriptObject();
	
	//Parse Region Info
	//[ID][Name][is Meta-Region][Latitude][Longitude][Radius][Color R][Color G][Color B]
	
	%startPos = 0;
	%endPos = strpos(%line, $GRID_PROTO::END_TUPLE, %startPos);
	
	%subString = getSubStr(%line, %startPos, %endPos - %startPos);
	error("Old region is " @ $regionLoaded);
	error("New Region is " @ %subString);
	
	// </region gui>
	if(($regionLoaded $= %subString) || ($regionLoaded == %subString))
	{
		error("Entering the same region...nothing is updated");
	}
	else
	{
		$regionLoaded = %subString;
		
		%regStartPos = strpos(%subString, $GRID_PROTO::END_ENTRY, 0);
		%regEndPos = strpos(%subString, $GRID_PROTO::END_ENTRY, %regStartPos);
		%region = getSubStr(%subString, %regStartPos, %regEndPos - %regStartPos);
		error("Entering new region!");

		%subStartPos = 0;

		for(%i = 0; %i < 9; %i++)
		{
			%subEndPos = strpos(%subString, $GRID_PROTO::END_ENTRY, %subStartPos);

			%RegionInfo.contents[0, %i] = getSubStr(%subString, %subStartPos, %subEndPos - %subStartPos);

			%subStartPos = %subEndPos + 1;
		}

		//-----------
		// REGION GUI
		//-----------
		Region.setText(%RegionInfo.contents[0, 1] @ " Region");
		$RegionName = %RegionInfo.contents[0, 1];
		
		%RegionInfo.count = 9;

		//Parse Terrain Info
		//[Probability for Terrain][...]
		//[Terrain ID][Type][Maximum Character Count][Character List Size]
		//[Character ID][Likelihood]

		%startPos = %endPos + 1;
		%endPos = strpos(%line, $GRID_PROTO::END_TUPLE, %startPos);

		%subString = getSubStr(%line, %startPos, %endPos - %startPos);

		//Terrain Probabilities
		%subStartPos = 0;
		%subEndPos = strpos(%subString, $GRID_PROTO::END_ENTRY, %subStartPos);
		%TerrianInfo.count = 0;

		while(%subEndPos != -1)
		{
			%TerrainInfo.contents[%TerrainInfo.count, 0] = getSubStr(%subString, %subStartPos, %subEndPos - %subStartPos);
			%TerrainInfo.count++;

			%subStartPos = %subEndPos + 1;
			%subEndPos = strpos(%subString, $GRID_PROTO::END_ENTRY, %subStartPos);
		}

		//Read the rest of the Terrain Info
		for(%i = 0; %i < %TerrainInfo.count; %i++)
		{
			%startPos = %endPos + 1;
			%endPos = strpos(%line, $GRID_PROTO::END_TUPLE, %startPos);

			%subString = getSubStr(%line, %startPos, %endPos - %startPos);	

			%subStartPos = 0;
			for(%j = 0; %j < 4; %j++)
			{
				%subEndPos = strpos(%subString, $GRID_PROTO::END_ENTRY, %subStartPos);

				%TerrainInfo.contents[%i, %j + 1] = getSubStr(%subString, %subStartPos, %subEndPos - %subStartPos);

				%subStartPos = %subEndPos + 1;
			}

			//Character List
			for(%k = 0; %k < %TerrainInfo.contents[%i, 4]; %k++)
			{
				%startPos = %endPos + 1;
				%endPos = strpos(%line, $GRID_PROTO::END_TUPLE, %startPos);

				%subString = getSubStr(%line, %startPos, %endPos - %startPos);	

				%subStartPos = 0;
				%subEndPos = strpos(%subString, $GRID_PROTO::END_ENTRY, %subStartPos);

				%TerrainInfo.contents[%i, 4, 2 * %k] = getSubStr(%subString, %subStartPos, %subEndPos - %subStartPos);

				%subStartPos = %subEndPos + 1;
				%subEndPos = strpos(%subString, $GRID_PROTO::END_ENTRY, %subStartPos);

				%TerrainInfo.contents[%i, 4, 2 * %k + 1] = getSubStr(%subString, %subStartPos, %subEndPos - %subStartPos);
			}
		}

		//Parse Structure Info
		//[Probability for Structure][...]
		//[Structure ID][Max Character Count][Max Inventory Count][Char. List Size][Inv. List Size]
		//[Char. ID][Likelihood]
		//[Inv. ID][Likelihood]

		%startPos = %endPos + 1;
		%endPos = strpos(%line, $GRID_PROTO::END_TUPLE, %startPos);

		%subString = getSubStr(%line, %startPos, %endPos - %startPos);	

		//Structure Probabilities
		%subStartPos = 0;
		%subEndPos = strpos(%subString, $GRID_PROTO::END_ENTRY, %subStartPos);
		%StructureInfo.count = 0;

		while(%subEndPos != -1)
		{
			%StructureInfo.contents[%StructureInfo.count, 0] = getSubStr(%subString, %subStartPos, %subEndPos - %subStartPos);
			%StructureInfo.count++;

			%subStartPos = %subEndPos + 1;
			%subEndPos = strpos(%subString, $GRID_PROTO::END_ENTRY, %subStartPos);
		}

		//Read the rest of the Structure Info
		for(%i = 0; %i < %StructureInfo.count; %i++)
		{
			%startPos = %endPos + 1;
			%endPos = strpos(%line, $GRID_PROTO::END_TUPLE, %startPos);

			%subString = getSubStr(%line, %startPos, %endPos - %startPos);	

			%subStartPos = 0;
			for(%j = 0; %j < 5; %j++)
			{
				%subEndPos = strpos(%subString, $GRID_PROTO::END_ENTRY, %subStartPos);

				%StructureInfo.contents[%i, %j + 1] = getSubStr(%subString, %subStartPos, %subEndPos - %subStartPos);

				%subStartPos = %subEndPos + 1;
			}

			//Character List
			for(%k = 0; %k < %StructureInfo.contents[%i, 4]; %k++)
			{
				%startPos = %endPos + 1;
				%endPos = strpos(%line, $GRID_PROTO::END_TUPLE, %startPos);

				%subString = getSubStr(%line, %startPos, %endPos - %startPos);	

				%subStartPos = 0;
				%subEndPos = strpos(%subString, $GRID_PROTO::END_ENTRY, %subStartPos);

				%StructureInfo.contents[%i, 4, 2 * %k] = getSubStr(%subString, %subStartPos, %subEndPos - %subStartPos);

				%subStartPos = %subEndPos + 1;
				%subEndPos = strpos(%subString, $GRID_PROTO::END_ENTRY, %subStartPos);

				%StructureInfo.contents[%i, 4, 2 * %k + 1] = getSubStr(%subString, %subStartPos, %subEndPos - %subStartPos);
			}

			//Inventory List
			for(%k = 0; %k < %StructureInfo.contents[%i, 5]; %k++)
			{
				%startPos = %endPos + 1;
				%endPos = strpos(%line, $GRID_PROTO::END_TUPLE, %startPos);

				%subString = getSubStr(%line, %startPos, %endPos - %startPos);	

				%subStartPos = 0;
				%subEndPos = strpos(%subString, $GRID_PROTO::END_ENTRY, %subStartPos);

				%StructureInfo.contents[%i, 5, 2 * %k] = getSubStr(%subString, %subStartPos, %subEndPos - %subStartPos);

				%subStartPos = %subEndPos + 1;
				%subEndPos = strpos(%subString, $GRID_PROTO::END_ENTRY, %subStartPos);

				%StructureInfo.contents[%i, 5, 2 * %k + 1] = getSubStr(%subString, %subStartPos, %subEndPos - %subStartPos);
			}		
		}
		
	//Parse Avatar Info
	//**NOT CURRENTLY IMPLEMENTED IN CLIENT**\\
	
	//Parse Character Info
	//**NOT CURRENTLY IMPLEMENTED IN CLIENT**\\
	
	setCurrentRegion(%RegionInfo, %TerrainInfo, %StructureInfo);
	// FOR SOME REASON THIS SAVE FUNCTION CALL PREVENTS THE ECHO ERROR STATEMENTS WITHIN loadRegionResponse
	// IT MAY ALSO HAVE OTHER IMPLICATIONS WE'RE UNAWARE OF 03-21-06
	// MIGHT WANT TO PLACE THE SAVE FUNCTION CALL SOMEWHERE ELSE
	//schedule(45000, 0, save);
	//COMMENTED UNTIL WE FIGURE OUT WHY SAVE'S SPAMMING THE SERVER!!!!
	//save();
	}
	
	loadLocalRegionList();
}

// instructs the underlying client code to send
// a client command to the server.
function clientSend(%message)
{
	//clientConnection.send( %message );
}

// instructs the underlying client code to log the
// user out of the client server and terminate the
// server connection.
function clientLogout()
{
	echo("goodbye:" @ $username @ " has logged out.\n");
	// this is technically redundant.  Once we issue the goodbye command
   // the server will disconnect us anyway.  This is mainly here just
   // in case.  Hopefully it won't cause any problems.
	clientConnection.disconnect();
}

// This is one of the standard callbacks for TCPObject.
// Whenever the TCPobject is disconnected from an active
// connection, this callback is called automaticly by the
// engine.
function clientConnection::onDisconnect(%this)
{
   	guiOnText("You have been disconnected.");
	$connected = false;
	clientConnection.destroy();
}

// This is one of the standard callbacks for TCPObject.
// Whenever the TCPobject connects to a server this
// callback is called automaticly by the engine.
function clientConnection::onConnected(%this)
{
	guiOnText("Welcome to the Unexceptional");
	$connected = true;
	// now that we've connected to the server, log the user in
}

// This is one of the standard callbacks for TCPObject.
// Whenever the TCPobject tries to connect to a server but
// fails to make a connection, this callback is called
// automaticly by the engine.
function clientConnection::onConnectFailed(%this)
{
   	guiOnText("Connection to server failed!");
}

// This is one of the standard callbacks for TCPObject.
// Whenever the TCPobject receives a line of text
// this callback is called automaticly by the engine.
function clientConnection::onLine(%this, %data)
{
	echo("CLIENT SCRIPT ONLINE");
	//%delim_pos = strpos(%line, $GRID_PROTO::DELIM);
		//$GRID_PROTO::currentTOT = getSubStr(%line, 0, %delim_pos);
	echo("command: " @ $GRID_PROTO::currentTOT );
		//%data = getSubStr(%line,%delim_pos + 1,strlen(%line));
	if($GRID_PROTO::currentTOT $= "0")
	{
		echo("Data: " @ %data);
	}
	else
	{
		if( $GRID_PROTO::currentTOT $= $GRID_PROTO::AUTHORIZE )
		{
			$GRID_PROTO::currentTOT = "0";
			authorizeResponse(%data);
		}
		else if( $GRID_PROTO::currentTOT $= $GRID_PROTO::LOAD_PLAYER )
		{
			$GRID_PROTO::currentTOT = "0";
			loadResponse(%data);
		}
		else if( $GRID_PROTO::currentTOT $= $GRID_PROTO::SAVE_PLAYER )
		{
			$GRID_PROTO::currentTOT = "0";
			//COMMENTED DUE TO RECURSIVE CALL - WAS SPAMMING SERVER WITH CONNECTS
			//WHEN SAVE WAS CALLED UP AT END OF loadRegionResponse
			//CURRENTLY SAVE IS BEING CALLED ON onMissionEnded IN GAME.CS
			//save();
		}
		else if( $GRID_PROTO::currentTOT $= $GRID_PROTO::LOAD_LOCAL_REGION_LIST )
		{
			$GRID_PROTO::currentTOT = "0";
			loadLocalRegionListResponse(%data);
		}
		else if( $GRID_PROTO::currentTOT $= $GRID_PROTO::LOAD_REGION )
		{
			$GRID_PROTO::currentTOT = "0";
			loadRegionResponse(%data);
		}
		else
		{
			echo("ERROR: " @ %data);
		}
	}
}

$offset = 0;
$curToken = " ";
$delim = "|";

function resetTokenizer()
{
	$offset = 0;
	$curToken = "";
	$delim = "|";
}

function nextToken( %line )
{
	%nextoffset = strpos(%line,"|", $offset);
	%lineEnd = strpos(%line,"$", $offset);
	//echo("\n\n$offset: " @ $offset @ ", next $offset: " @ %nextoffset @ ", line end: " @ %lineEnd @ "\n");
	if( %nextoffset >= 0 && %nextoffset < %lineEnd)
	{
		//echo("\n**|\n");
		$delim = "|";
		%newOff = %nextoffset;
		$curToken = getSubStr(%line, $offset, %nextoffset-$offset );
		$offset = %newOff + 1;
		return true;
	}
	else if( %lineEnd >= 0)
	{
		$delim = "$";
		%newOff = %lineEnd;
		$curToken = getSubStr(%line, $offset, %lineEnd-$offset );
		$offset = %newOff + 1;
		return true;
	}

	%nextoffset = strpos(%line,"~", $offset);
	if( %nextoffset  >= 0)
	{
		$delim = "~";
		return false;
	}


	return false;
}

// This is a helper function to test functionality, automatically connects to local DB and sets playerID
function connect()
{
	//clientConnect($SERVER_ADDRESS, 7704, $username,$password);
	clientConnect("unexceptional.arts.uci.edu", "7705", "0000000000");
}
// helper testing function
function setID(%id)
{
	$userid = %id;
}

// This is a GUI callback used by the underlying client
// system to inform the GUI of new client text that
// should be displayed.
function guiOnText(%text)
{
   // place GUI hook here to do whatever is desired to display
   // the new client text.
   echo(%text);
}

// this is a GUI callback used by the underlying client
// system to inform the GUI that a new user has logged
// on to the client server.  The GUI can use this to
// keep some sort of user display.
function guiOnAddUser(%user)
{
   echo("[ADD USER] " @ %user);
}

// this is a GUI callback used by the underlying client
// system to inform the GUI that an existing user has
// logged off the client server.The GUI can use this to
// keep some sort of user display.
function guiOnRemoveUser(%user)
{
   echo("[REMOVE USER] " @ %user);
}


//-----------------------------------------------------------------------------
//Region Text Display
//-----------------------------------------------------------------------------

function GameConnection::setRegionTextHud(%client, %amount)
{
   commandToClient(%client, 'SetRegionDistanceHud', %amount);
}


//-------------------------------------------------------------------
// Dan Sample RegionDistance Hud usage.
//-------------------------------------------------------------------

//9999.99
//   %currentDistance = "";
//   %obj.client.setRegionDistanceHud(%currentDistance);
   RegionDistance.setText("mi: ");