//---------------------- GLOBALS ----------------------------//
var kTxt_MoreGames 			= 'More Games';
var kTxt_NotTimed			= 'Not Timed';
var kTxt_Paused				= 'Paused';
var kTxt_Pause				= 'Pause';
var kTxt_Resume				= 'Resume';
var kTxt_ReturnToLobby		= 'Go to Lobby';
var kTxt_StartOver			= 'Start Over';
var kTxt_Timed				= 'Timed';

var kTxt_NoTimedOption = 'This game does not have a \'Timed\' option.  Please choose \'Not Timed\' instead.';
var kTxt_LoggedInToPlay = 'You must be logged in to play.';

var kMsg_GameOver_Congrats = 'Congratulations on achieving a new high score!';
var kMsg_GameOver_BetterLuckNextTime = 'No new high score this round. Maybe next time.';

var kMsg_WarnNotSubmittedHighScore 	= 	'You have not submitted your new personal high score.\n';
kMsg_WarnNotSubmittedHighScore 		+=  'Click \'OK\' to continue without submitting your high score.\n';
kMsg_WarnNotSubmittedHighScore 		+=  'To submit your high score, click \'Cancel\' and then click \'Submit Score\'.';

var kMsg_MPWarnQuit = 'You are about to quit the game.\nYou will be permanently removed from it and your rating will be negatively affected.';

var kMaxTime = 5*60*1000; //milliseconds (need for the lobby and game)
var gbLoggedIn 		= false;
var gType = Search_GetValue( 'type' );
if ( gType !== undefined ) { ConvertToInt( gType ); }
var gbMultiplayer = false;

//-------------------------------------------------------------------------------------------------------------------------------------------//
window.onbeforeunload = function()
{
	var g = Game.mSingleton;
	if ( g && g.OnBeforeUnload )
	{
		return g.OnBeforeUnload();
	}
};

document.onkeydown = function( evt )
{
	var g = Game.mSingleton;
	if ( g && g.OnKeyDown ) 
	{
		return g.OnKeyDown( evt );	
	}
};

window.LogInAfterScore = function( prevScore, rank, totalPlayers, numid )
{
	var g = Game.mSingleton;
	if ( !g ) return;
	
	gbLoggedIn = true;
	g.LogInAfterScore( prevScore, rank, totalPlayers, numid );
};

//-------------------------------------------------------------------------------------------------------------------------------------------//
function GameMPCategory( id, name, actives )
{
	this.mID = id;
	this.mName = name;
	this.mActiveGames = actives;
}

//-------------------------------------------------------------------------------------------------------------------------------------------//
GameVariation.SetupCurrentVariation = function ( index, variation )
{
	if ( index <= -1 ) { ErrorOutput( 'Undefined index: ' + index ); return false; }	
	GameVariation.SetCurrentVariationAtIndex( index ); 
	
	if ( !GameVariation.mCurrentVariation ) { ErrorOutput( 'invalid variation index: ' + index );  return false; }	
	GameVariation.mCurrentVariation.SetCurrentID( variation );
	return true;
};

GameVariation.SetCurrentVariationAtIndex = function( index )
{
	if ( index < 0 || index > GameVariation.mVariations.length ) { return; }
	
	GameVariation.mCurrentVariation = GameVariation.mVariations[index];  
	if ( !GameVariation.mCurrentVariation ) { ErrorOutput( 'No variation for index=' + index ); return; }
	return GameVariation.mCurrentVariation;
};

GameVariation.IsVariationTimed = function ( id )
{
	for ( var i = 0; i < GameVariation.mVariations.length; ++i )
	{
	 	var v = GameVariation.mVariations[i];
		if ( v && v.IsTimed( id ) )
		{
			return true;
		}
	}
	return false;
};

GameVariation.GoToLobby = function ()
{
	if ( !GameVariation.mCurrentVariation ) { return; }
	var s = GameVariation.mCurrentVariation.GetLobbyHREF(); //alert( s );
	RedirectImmediate ( s );
};

GameVariation.GoToRoom = function ( id )
{
	if ( !GameVariation.mCurrentVariation ) { return; }
	var s = GameVariation.mCurrentVariation.GetRoomHREF( id ); //alert( s );
	RedirectImmediate ( s );
};

GameVariation.mCurrentVariation = undefined;
GameVariation.mVariations = [];

function GameVariation()
{
	this.mCurVariation = undefined;
	
	this.mType		= gType; // this should be in Game class...
	this.mIndex 	= -1;
	this.mName 		= '';
	this.mElementID = '';
	this.mID		= undefined;
	this.mRulesDivID= undefined;
	
	this.mLobbyPage 	= '';
	this.mRoomPage 		= '';
	this.mGamePage 		= '';
	this.mRulesPage 	= '';
	this.mScoresPage	= '';
	
	this.mbTimeable		= true;
}

GameVariation.prototype.SetCurrentID = function ( v )
{
	if ( gType !== undefined && this.mType != gType ) { this.mType = gType; }
	this.mCurVariation = v;
};

GameVariation.prototype.GetCurrentID = function ()
{
	return this.mCurVariation;
};

GameVariation.prototype.IsTimed = function ( id )
{
	return false;
};

GameVariation.prototype.IsMultiplayer = function( id )
{
	return false;
};

GameVariation.prototype.GetRulesDivID = function () 
{
	return this.mRulesDivID;
};

GameVariation.prototype.GetRulesHREF = function ()
{
	return '/' + this.mRulesPage + '?v=' + (this.mCurVariation ? this.GetCurrentID() : this.DetermineID( false ) );
};

GameVariation.prototype.GetScoresHREF = function ()
{
	return '/' + this.mScoresPage + '?v=' + (this.mCurVariation? this.GetCurrentID() : this.DetermineID( false ) );
};
	
GameVariation.prototype.GetLobbyHREF = function ()
{
	var argKey = '?type=' + (this.mType > 0 ? this.mType : gType );
	if ( this.mCurVariation )
	{
		argKey += '&from=' + this.GetCurrentID();
	}
	
	return '/' + this.mLobbyPage + argKey;
};
	

GameVariation.prototype.GetGameHREF = function ()
{
	return '/' + this.mGamePage + '?' + this.GetGameArgs();
};

GameVariation.prototype.GetRoomHREF = function ( id )
{
	return '/' + this.mRoomPage + '?v=' + (this.mCurVariation ? this.GetCurrentID() : (id !== undefined? id : this.DetermineID(false)));
};
	
GameVariation.prototype.GetGameArgs = function ()
{
	return 'v=' + (this.mCurVariation ? this.GetCurrentID() : this.DetermineID(false));
};

GameVariation.prototype.GetGameInstanceArgs = function ()
{
	return this.GetGameArgs();
};

GameVariation.prototype.GetGameInstanceHREF = function()
{
	var more = Search_GetValue( 'gk' );
	if ( more )
	{
		more = '&gk=' + more;
	}
	else
	{
		more = '';
	}
	
	return '/' + this.mGamePage + '?' + this.GetGameInstanceArgs() + more;
};
	
GameVariation.prototype.DetermineID = function ()
{
	return this.mID;
};

//-------------------------------------------------------------------------------------------------------------------------------------------//
Game.kTitleLetterClass = 'wg_title_letter';
Game.kLetterClassDisabled= 'wg_title_letter_disabled';
Game.kLetterClassOver 	= 'wg_title_letter_over';
Game.kLetterClassSel 	= 'wg_title_letter_sel';
Game.kLetterClass 		= 'wg_title_letter_link wg_title_letter';
Game.kLetterSpace 		= 'wg_title_letter_link_space';
Game.kTitleLetterSpace 	= 'wg_title_letter_space';
Game.kTitleLeterLinkEmbed='wg_title_letter_link_embeded';
Game.mGameName = ''; 

// REVISIT -- shouldn't be static?
Game.mGameTitleElement;
Game.mVariationTitleElement;

Game.mSingleton;
Game.CreateNav = function( link, buttonTxt, rolloverTxt )
{
	if ( !link ) { return; }
	
	link.innerHTML = '<INPUT type="button" value="'+buttonTxt+'" style="font-weight:bold;" onclick="RedirectImmediate( \'' + link.getAttribute( 'href' ) + '\' );">';
//	link.innerHTML = '<SPAN style="padding:4px; font-weight:bold;">' + buttonTxt + '</SPAN>';
	link.onclick = function(){ return false;};
	link.onmouseover = function( evt )
	{
		UI_ShowPopup( true, rolloverTxt, undefined, evt );
	};
	
	link.style.cursor = 'default';
};

Game.CreateGameNav = function( e, prevLink, nextLink, typeName )
{
	if ( !(e && prevLink && nextLink) ) { return; }
	
	var prevLinkTxt = prevLink.innerHTML;
	var nextLinkTxt = nextLink.innerHTML;
	
	if ( !(prevLinkTxt && nextLinkTxt) )
	{
		// no text, no need for links
		prevLink.setAttribute( 'href', 'javascript:void(0)' );
		nextLink.setAttribute( 'href', 'javascript:void(0)' );
		return;
	}
		
	var html = '<TABLE><TR id="ze_game_nav">';
	//<TD><INPUT type="button" value="&lt;"></TD><TD><INPUT type=button value="&gt;"></TD>';
	html += '</TR></TABLE>';
	e.innerHTML = html;
	
	var row = GetElement( 'ze_game_nav' );
	if ( row )
	{
		var td = document.createElement( 'TD' );
		if ( !td ) { return; }

		row.appendChild( td );
		var buttonTxt = " &lt; ";
		var rolloverTxt = 'Click to go to<BR>' + typeName + ' ' + prevLinkTxt;
		td.appendChild( prevLink );
		
		Game.CreateNav( prevLink, buttonTxt, rolloverTxt );
		td = document.createElement( 'TD' );
		if ( !td ) { return; }

		row.appendChild( td );
		buttonTxt = " &gt; ";
		var otherRollover = 'Click to go to<BR>' + typeName + ' ' + nextLinkTxt;
		td.appendChild( nextLink );
		Game.CreateNav( nextLink, buttonTxt, otherRollover );
	}
};

Game.TabOnMouseOver = function( e )
{
	if ( e )
	{
		e.className = 'wg_tab_over';	
	}
};

Game.TabOnMouseOut = function( e )
{
	if ( e )
	{
		e.className = 'wg_tab';	
	}
};

Game.RulesInlineOnClick = function( divID )
{
	if ( IsEmbededMini() ) return;
	
	if ( !divID && Game.mSingleton && Game.mSingleton.mCurrentVariation )
	{
		divID =Game.mSingleton.mCurrentVariation.GetRulesDivID();
	}
	
	var e = GetElement( divID );
	if ( e )
	{
		var r = e.innerHTML;
		r += '<DIV style="text-align:center; padding:8px;"><INPUT type="button" onclick="UI_ShowOverlay(false);" value="Done"></DIV>';
		UI_ShowOverlay( true, r );
	}
};

Game.InfoOnMouseOver = function( evt, index )
{
	if ( !evt ) evt = window.event;
	var e = Event_GetElement( evt );
	var i = index;
	if ( e && i > 0 && !e.mPopupMenu )
	{
		var d = '';
		var txt = 'How To Play';
		if ( IsEmbeded() )
		{
			d = GetHTTPDomain( true );
		}
		if ( IsEmbededMini() )
		{
			txt = '<A href="'+ d + GameVariation.mVariations[i].GetRulesHREF() + '" target="_blank">' + txt + '</A>';
		}
		var html = 	'<TABLE style="margin:0px;">';
		var id = 'ze_item1_' + i;
		html += 	'<TR><TD id="'+id+'" class="wg_popup" onmouseover="var e=GetElement(\''+id+'\'); UI_PopupMenuItemOnMouseOver(e);" onmouseout="var e=GetElement(\''+id+'\'); UI_PopupMenuItemOnMouseOut(e);" onclick="Game.RulesInlineOnClick(\'' + GameVariation.mVariations[i].GetRulesDivID() + '\');">' + txt + '</TD></TR>';
		id = 'ze_item2_' + i;
		html +=		'<TR><TD id="'+id+'" class="wg_popup" onmouseover="var e=GetElement(\''+id+'\'); UI_PopupMenuItemOnMouseOver(e);" onmouseout="var e=GetElement(\''+id+'\'); UI_PopupMenuItemOnMouseOut(e);"><A href="' + d + GameVariation.mVariations[i].GetScoresHREF() + '" ' + (IsEmbededMini()?'target="_blank"':'') + '>High Scores</A></TD></TR>';
		html +=		'</TABLE>';

		e.mPopupMenu = new UI_PopupMenu( e );
		e.mPopupMenu.SetData( html );
		e.mPopupMenu.Format( undefined, 1, (IsEmbededMini() ? 2 : 0), undefined, 2 );
	}
	
	e.mPopupMenu.Show( true );
};

//Game.InfoOnMouseOut = function()
//{
//	UI_PopupMenuTimer_Start();
//};

Game.TitleOnMouseOver = function( e ) 
{
	if ( !e ) { ErrorOutput( 'VariationOnMouseOver -- no element' ); return;}
	var cells = e.getElementsByTagName('DIV'); 
	for (var i = 0; i < cells.length; ++i) 
	{ 
		var c = cells[i];
		if ( c && c.mbTitleLetter ) 
		{
			c.className = c.mClassNameOver + ' ' + c.mClassNameDefault;
		}
	}				
};

Game.TitleOnMouseOut = function( e ) 
{
	if ( !e ) { ErrorOutput( 'VariationOnMouseOut -- no element' ); return; }
	var cells = e.getElementsByTagName('DIV'); 
	for ( var i = 0; i < cells.length; ++i ) 
	{ 
		var c = cells[i];
		if ( c && c.mbTitleLetter ) 
		{
			c.className = c.mClassNameDefault;
		}
	}
};

Game.VariationOnMouseOver = function( evt, e ) 
{
	if ( !evt ) evt = window.event;
	if ( evt )
	{
		Event_Cancel( evt );
	}
	
	if ( !e ) { ErrorOutput( 'VariationOnMouseOver -- no element' ); return;}
	var p = e.parentNode; if ( !p ) { ErrorOutput( 'VariationOnMouseOver -- no parent.' ); return; }

	if ( e.mbDisabled )
	{
		UI_ShowPopup( true, gbMultiplayer && !gbLoggedIn ? kTxt_LoggedInToPlay : kTxt_NoTimedOption, undefined, evt );
	}
	else
	{
		var cells = p.getElementsByTagName('DIV'); 
		for (var i = 0; i < cells.length; ++i) 
		{ 
			if ( cells[i].mbRolloverable && !cells[i].mbDisabled ) 
			{
				cells[i].className = cells[i].mOverClassName;
			}
		}
	}				
};

Game.VariationOnMouseOut = function( evt, e ) 
{
	if ( !evt ) evt = window.event;
	if ( evt )
	{
		Event_Cancel( evt );
	}
	
	if ( !e ) { ErrorOutput( 'VariationOnMouseOut -- no element' ); return; }
	var p = e.parentNode; if ( !p ) { ErrorOutput( 'VariationOnMouseOut -- no parent.' ); return; }
	
	var cells = p.getElementsByTagName('DIV'); 
	for ( var i = 0; i < cells.length; ++i ) 
	{ 
		if ( cells[i].mbRolloverable ) 
		{
			cells[i].className = cells[i].mbDisabled ? cells[i].mDisabledClassName : cells[i].mDefaultClassName;
		}
	}

	if ( e.mbDisabled )
	{
		UI_ShowPopup( false );
	}
};

Game.VariationOnMouseOverSel = function( e ) 
{
	if ( !e ) { ErrorOutput( 'VariationOnMouseOver -- no element' ); return; }
	var cells = e.getElementsByTagName('DIV'); 
	for (var i = 0; i < cells.length; ++i) 
	{ 
		cells[i].className = cells[i].className.replace( '_sel', '_over' );
	}				
};

Game.VariationOnMouseOutSel = function( e ) 
{
	if ( !e ) { ErrorOutput( 'VariationOnMouseOut -- no element' ); return;}
	var cells = e.getElementsByTagName('DIV'); 
	for ( var i = 0; i < cells.length; ++i ) 
	{ 
		cells[i].className = cells[i].className.replace( '_over', '_sel' );
	}				
};

Game.prototype.SetTypeNameDisplay = function( type, addedTypeInfo )
{
	if ( type )
	{
		this.mTypeDisplayElement = type;
	}
	if ( !this.mTypeDisplayElement ) { return; }
	
	var typeName = GameVariation.GetTypeName( GameVariation.mCurrentVariation.mType );
	if ( typeName )
	{
		typeName += (GameVariation.mCurrentVariation && GameVariation.mCurrentVariation.IsTimed()?' Timed' : '') + (addedTypeInfo ? (':  <SPAN class="small" style="font-weight:normal;">Daily Puzzle for ' + addedTypeInfo + '</SPAN>') : '');
	}	
	this.mTypeDisplayElement.innerHTML = typeName; 
};

Game.CreateTitleAndVariation = function( e, bSmall, bWithType, navDivName )
{
	if ( !e) { return ''; }
	if ( IsEmbededMini() ) return '';
	if ( bWithType === undefined ) { bWithType = false; }
	
	var display = e.style.display;
	if ( !display ) { display = ''; }
	e.style.display = 'none';

	var div = document.createElement( 'DIV' );
	div.style.paddingBottom = '16px';
	div.style.margin = 'auto';
	e.appendChild( div );
		
	var table = document.createElement( 'TABLE' );
	div.appendChild( table );

	var tbody = document.createElement( 'TBODY' );
	table.appendChild( tbody );

	var row = document.createElement( 'TR' );
	tbody.appendChild( row );
		
	var td = document.createElement( 'TD' );
	row.appendChild( td );
		
	var name = GameVariation.mCurrentVariation ? GameVariation.mCurrentVariation.mName.toUpperCase() : '';
	if ( bSmall )
	{
		Game.CreateHTML_TitleSmall( td );
		if ( name && bWithType )
		{
			var td = document.createElement( 'TD' );
			td.style.fontWeight = 'bold';
			td.innerHTML = '&nbsp;:&nbsp;';
			row.appendChild( td );
		}
	}
	else
	{
		Game.CreateHTML_Title( td );
	}
				
	if ( !IsEmbededMini() )
	{
		if ( name )
		{
			var element;
			if ( bSmall )
			{
				element = document.createElement( 'TD' );
				row.appendChild( element );
			}
			else
			{
				element = document.createElement( 'DIV' );
				e.appendChild( element );
			}
			
			Game.CreateHTML_VariationTitle( element, name );
		}			
	}
	
	var typeName = '';
	if ( bWithType && GameVariation.mCurrentVariation && Game.mSingleton )
	{
		var type = document.createElement( 'DIV' );
		type.style.fontWeight = 'bold';
		Game.mSingleton.SetTypeNameDisplay( type );
		div.appendChild( type );
	}
		
	if ( navDivName )
	{
		var links;
		var nav = GetElement( navDivName );
		if ( nav )
		{
			var anchors = nav.getElementsByTagName( 'A' );
			if ( anchors && anchors.length )
			{
				links = {mPrev:anchors[0], mNext:anchors[1]};
				nav.style.display = 'none';
			}
		}

		var div2 = document.createElement( 'DIV' );
		div.appendChild( div2 );
		Game.CreateGameNav( div2, links.mPrev, links.mNext, typeName );
	}
		
	e.style.display = display;
}

Game.FancifyText = function( t, c, space_c, id, bCenterTable )
{
	return t;
};

Game.CreateHTML_VariationTitle = function( e, name )
{
	var html = '';
	var txt = Game.FancifyText( name, Game.kLetterClassSel + ' ' + Game.kLetterClass, Game.kLetterSpace, 'ze_variation_title', true );
	// REVISIT -- letter value dots aren't the correct color
	//	need to set the letter class to kLetterClass and then cause it to add to kLetterClassSel
	html +=	txt;
	
	if ( e )
	{
		e.innerHTML = html;
		var title = GetElement( 'ze_variation_title' );
		if ( title )
		{
			title.onclick 		= function() { UI_ShowPopup(false); Game.VariationOnMouseOutSel(title); RedirectImmediate( GameVariation.mCurrentVariation.GetRoomHREF() ); }
			title.onmouseover 	= function(evt) { UI_ShowPopup( true, 'Go to Game', 100, evt ); Game.VariationOnMouseOverSel(title); }
			title.onmouseout	= function() { UI_ShowPopup(false); Game.VariationOnMouseOutSel(title); }
		}
		Game.mVariationTitleElement = title;
	}
	else
	{
		return e;
	}
};


Game.CreateHTML_TitleSmall = function( e )
{
	if ( IsEmbededMini() ) return '';

	Game.CreateHTML_Title( e, Game.kLetterClass, Game.kLetterClassOver, Game.kLetterSpace );
}

Game.CreateHTML_Title = function( e, clName, clOver, clSpace, bRoom )
{
	if ( IsEmbededMini() ) return '';
	if ( bRoom === undefined ) { bRoom = false; }
	
	clName = clName ? clName : Game.kTitleLetterClass;
	clSpace = clSpace ? clSpace : Game.kTitleLetterSpace;
	clOver = clOver ? clOver : Game.kLetterClassOver;
	var txt = Game.FancifyText( Game.mGameName, clName, clSpace, 'ze_title', true );
	var html = '';
//	html += 	'<TABLE style="margin-bottom: 12px;"><TR><TD>';
	html +=	txt;
//	html +=		'</TD></TR></TABLE>';

	if ( e )
	{
		e.innerHTML = html;
		var titleE = GetElement( 'ze_title' );
		if ( titleE )
		{
			titleE.onclick		= function() { UI_ShowPopup(false); Game.TitleOnMouseOut(titleE); if(bRoom){GameVariation.GoToRoom();}else{GameVariation.GoToLobby();} };
			titleE.onmouseover	= function(evt) { UI_ShowPopup(true, 'Go to '+(bRoom?'Room':'Lobby'), 100, evt ); Game.TitleOnMouseOver(titleE); }
			titleE.onmouseout 	= function() { UI_ShowPopup(false); Game.TitleOnMouseOut(titleE); }
			var cells = titleE.getElementsByTagName( 'DIV' ); 
			for (var i = 0; i < cells.length; ++i) 
			{
				var cell = cells[i];
				if ( cell.className === clName ) 
				{
					cell.mbTitleLetter 		= true;
					cell.style.cursor 		= 'pointer';
					cell.mClassNameDefault 	= clName;
					cell.mClassNameOver 	= clOver;
				}
			}
			titleE.style.cursor = 'pointer';
		}
		Game.mGameTitleElement = titleE;
	}
}


function Game()
{
	this.mbLoggedIn 	= true;
	this.mScore			= 0;
	this.mRank			= 0;
	this.mTotalPlayers	= 0;
	this.mGIPDivName 	= '';
	this.mNavLinksDivName = '';
	this.mMainContainer = '';
	this.mUserDisplayName = '';
	this.mUserID		= 0;

	this.mMinPlayers 	= 1;
	this.mMaxPlayers 	= 1;
	this.mCategories 	= undefined;
	
	this.mNumPlayers 	= 1;
	this.mCategory 		= undefined;
	
	this.mTypeDescription = '';
	
	Game.mSingleton = this;	
}

Game.prototype.SetNavAnchors = function()
{
	if ( !this.mNavLinksDivName ) { return; }
	
	var nav = GetElement( this.mNavLinksDivName );
	if ( nav )
	{
		var anchors = nav.getElementsByTagName( 'A' );
		if ( anchors && anchors.length )
		{
			this.mNavLinks = { mGame:anchors[0], mRoom:anchors[1], mLobby:anchors[2], mPrev:anchors[3], mNext:anchors[4] };
			nav.style.display = 'none';
		}
	}
};

Game.prototype.CreateHeading = function( e, dailyPuzzleDate )
{
	if ( !e ) { return; }

	var display = e.style.display;
	e.style.display = 'none';
		
	Game.CreateTitleAndVariation( e, true, true, undefined, dailyPuzzleDate );
		
	e.style.display = display;
};

Game.prototype.CreateBody = function( element )
{
};

Game.prototype.CreateEnding = function( element )
{
};

Game.prototype.SetupPage = function( parent )
{
	var parentE = GetElement( parent );
	if ( !parentE ) { ErrorOutput( 'No valid parent' ); return; }
	
	if ( IsEmbededMini() )
	{
		parentE.style.width = '300px';
		parentE.style.height = '300px';
	}
	
	this.CreateHeading( parentE );

	this.mMainContainer = document.createElement( 'DIV' );
	if ( !this.mMainContainer ) { return; }

	this.mMainContainer.id = 'ze_container';	
	parentE.appendChild( this.mMainContainer );

	this.SetNavAnchors();
	
	this.CreateBody( this.mMainContainer );
	
	if ( !IsEmbededMini() )
	{
		var end = document.createElement( 'DIV' );
		if ( end )
		{
			end.style.paddingTop = '4px';
//			end.style.margin = '12px';
			parentE.appendChild( end );
			this.CreateEnding( end );
		}
	}
	else
	{
		this.SetElement_EmbededMenuOnMouseOver();
	}	
};

Game.prototype.SetElement_EmbededMenuOnMouseOver = function()
{
	var g = this;
	this.mEmbededMenuElement = GetElement( 'ze_embeded_menu' );
	if ( this.mEmbededMenuElement )
	{
		this.mEmbededMenuElement.onmouseover = function( evt )
		{
			g.EmbededMenuOnMouseOver( evt );					
		}
	}
};

Game.prototype.EmbededMenuOnMouseOver = function( evt )
{
	if ( !(IsEmbededMini() && this.GetHTML_EmbededMenu) ) return;
	
	if ( !evt ) evt = window.event;
	var e = Event_GetElement( evt );
	if ( e )
	{
		var html = this.GetHTML_EmbededMenu();
		var func = e.onmouseover;
		UI_ShowPopupMenu( true, html, e, 2, 2 ); // onmouseover function gets replaced so restore
		e.onmouseover = func;
	}
};

Game.prototype.FatalError = function( msg, textColor )
{
	if ( !msg ) { msg = 'A fatal error has occurred and a report has been sent to ZooEscape.com.<BR>Please try again later.'; }
	if ( !textColor ) { textColor = '#FF0000'; }
	
	var margin = IsEmbededMini() ? 8 : 16;
	var fontSize = IsEmbededMini() ? ' font-size:80%;' : '';
	var html = 	'<TABLE style="margin:'+ margin+'px;">';	
	html +=			'<TR><TD style="color:' + textColor + ';'+fontSize+'">' + msg + '</TD></TR>';
	html +=		'</TABLE>';
	UI_ShowOverlay( true, html );
};

Game.prototype.FullscreenMessage = function( msg )
{
	if ( !msg ) { return; }
	
	var margin = IsEmbededMini() ? 8 : 16;
	var fontSize = IsEmbededMini() ? ' font-size:80%;' : '';
	var html = 	'<TABLE style="margin:'+ margin+'px;">';	
	html +=			'<TR><TD style="padding-bottom:4px;'+fontSize+'">' + msg + '</TD></TR>';
	html +=			'<TR><TD><INPUT type="button" onclick="UI_ShowOverlay(false);" value=" OK "></TD></TR>';
	html +=		'</TABLE>';
	UI_ShowOverlay( true, html );
};

Game.prototype.StartRemoteRequest = function( rr )
{
	if ( !rr ) return false;
	
	if ( !this.mRemoteRequests ) this.mRemoteRequests = new Array();
	this.mRemoteRequests.push( rr );
	if ( !rr.Issue() )
	{
		this.DeleteRemoteRequest( rr );
		return false;
	}
	return true;
};

Game.prototype.DeleteRemoteRequest = function( rr )
{
	if ( !this.mRemoteRequests ) return true;
	
	for ( var i = this.mRemoteRequests.length - 1; i >= 0; --i )
	{
		var myRR = this.mRemoteRequests[i];
		if ( myRR == rr )
		{
			delete this.mRemoteRequests[i];
			RemoteRequest.DeleteRequest( rr );			
			return true;
		}
	}
	return false;
};

Game.prototype.DeleteRemoteRequests = function()
{
	if ( !this.mRemoteRequests ) return true;
	
	while ( this.mRemoteRequests.length )
	{
		var myRR = this.mRemoteRequests.pop();
		RemoteRequest.DeleteRequest( myRR );
	}
	delete this.mRemoteRequests;
};

Game.prototype.RemoteRequest_Timeout = function ( rr )
{
	if ( this.DeleteRemoteRequest( rr ) )
	{
		this.FatalError();
	}
};

Game.prototype.SetStats = function( score, rank, totalPlayers )
{
	this.mScore = score !== '' ? Math.floor( score ) : 0;
	this.mRank = ConvertToInt(rank);
	this.mTotalPlayers = totalPlayers;

//	alert( 'rank=' + this.mRank + ', total=' + this.mTotalPlayers );

	this.UpdateStats();
};

Game.CallbackHandler = function( funcName, arg )
{
	var g = Game.mSingleton;
	if ( !g || !funcName ) { return false; }
	
	if ( g[funcName] )
	{
		return g[funcName](arg);
	}
};

Game.prototype.UpdateStats = function()
{
	// override
};

//--- Begin GameInstance -----------------------------------------------------------------------------------------------------------------//
GameInstance.prototype = new Game();
GameInstance.prototype.constructor = GameInstance;
function GameInstance( variation )
{
	Game.call( this );
	this.mCurrentVariation = variation;
	this.mbUpdating		= false;
	this.mbGameOver		= false;
	this.mbExitingGame	= false;
	this.mbNavigateWarn = true;
	this.mbPaused		= false;
	this.mCurTime		= 0;	
	this.mBoard;
}


GameInstance.CallbackHandler = function( funcName, arg ) // should remove all calls to this one and call Game.CallbackHandler
{
	var g = Game.mSingleton;
	if ( !g || !funcName ) { return false; }
	
	if ( g[funcName] )
	{
		return g[funcName](arg);
	}
};

GameInstance.prototype.GameLinkOnClick = function()
{
	if ( this.mbUpdating ) { return; }
	
	this.PauseGame( true );
	var v = this.mCurrentVariation;
	var name = v.mName;
	var link = v.GetGameHREF();
	if ( IsEmbeded() )
	{
		link = GetHTTPDomain(true) + link;
	}
	else
	{
		link = 'http://' + GetDomain() + link; // REVISIT	
	}
	
	this.DoOverlayWithLinks( name, link );
	return false;
};

GameInstance.prototype.DoOverlayWithLinks = function( name, link )
{
	var embed = '<A href=&quot;' + link + '&quot;>' + Game.mGameName + ' -- ' + name;
	var v = this.mCurrentVariation;
	if ( v.mbTimeable )
	{
		embed += ' ('+ (v.IsTimed()?kTxt_Timed:kTxt_NotTimed) + ')';
	}
	embed += '</A>';

	var title = Game.FancifyText( name.toUpperCase(), Game.kLetterClassSel + ' ' + Game.kLetterClass, undefined, 'wg_variation_title' );
	// REVISIT -- see comment in wordgamecommon.js
	
	title =	'<TABLE style="margin-bottom:12px;"><TR><TD style="font-weight:bold;">Link To:&nbsp</TD><TD>' + title + '</TD></TR></TABLE>';

	var html = '<TABLE style="margin:16px;"><TR><TD>' + title + '</TD></TR>';	
	html +=		'<TR><TD><TABLE class="wg_text user_info">';
	html +=		'<TR><TD>Paste Link in an Email or IM:</TD><TD ><INPUT id="wg_gamelink_link" type=text readOnly size=50 value="' + link + '" ></TD></TR>';
	html +=		'<TR><TD>Paste HTML to Embed in Webpage:</TD><TD><INPUT type=text readOnly size=50 value="' + embed + '"></TD></TR>';
	html += 	'<TR><TD colspan=2 style="text-align:center; padding:8px;"><INPUT type="button" onclick="UI_ShowOverlay(false);" value="Done"></TD></TR></TABLE>';
	html +=	'</TD></TR></TABLE>';
	UI_ShowOverlay( true, html, 'overlay_gamelink overlay' );
	var e = GetElement( 'wg_gamelink_link' )
	if ( e ) e.select();
};

GameInstance.prototype.LogInAfterScore = function( prevScore, rank, totalPlayers, numid )
{
	this.mbLoggedIn = true;
	this.mUserID = numid;
	this.SetStats( prevScore, rank, totalPlayers );
	UI_ShowOverlay( false );
	this.UpdateLogInMsg();
};

GameInstance.LogInOnClick = function( evt )
{
	var g = Game.mSingleton;
	if ( !g ) { return; }
	
	return g.LinkOnClick( evt, 'las' );
};

GameInstance.RegisterOnClick = function( evt )
{
	var g = Game.mSingleton;
	if ( !g ) { return; }
	return g.LinkOnClick( evt, 'ras' );
};

GameInstance.prototype.LinkOnClick = function( evt, cookie )
{
	if ( !evt ) { evt = window.event; }
	
	if ( this.mbLoggedIn ) { return; }
	if ( this.mbUpdating ) 
	{ 
		Event_Cancel( evt ); 
		return false;
	}
	
	this.PauseGame( true );
	CookieSet( cookie, GameVariation.mCurrentVariation.GetCurrentID() );
	return true;
};

GameInstance.prototype.StartOverOnClick = function() 
{
	if ( !this.mbUpdating ) { this.EnterGame(); }
};

GameInstance.prototype.RulesOnClick = function()
{
	if ( this.mbUpdating ) { return false; }
		
	this.PauseGame( true );
	if ( GameVariation.mCurrentVariation )
	{
		var id = GameVariation.mCurrentVariation.GetRulesDivID();
		if ( id )
		{
			var el = GetElement( id );
			if ( el )
			{
				var r = el.innerHTML;
				r += '<DIV style="text-align:center; padding:8px;"><INPUT type="button" onclick="UI_ShowOverlay(false);" value="Done"></DIV>';
				UI_ShowOverlay( true, r );
			}
		}
	}
	return false;
};

GameInstance.prototype.BoardOnMouseOver = function( evt, e ) 
{
	if ( this.mBoard ) { this.mBoard.OnMouseOver( evt, e ); }	
}

GameInstance.prototype.BoardOnMouseOut = function( evt, e ) 
{
	if ( this.mBoard ) { this.mBoard.OnMouseOut( evt, e ); }	
}

GameInstance.prototype.EnterGame = function() 			
{
	if ( this.mbExitingGame ) { return; }
	this.mbGameOver = false;
	this.mbPaused 	= false;
	
	this.StartGame();
};

GameInstance.prototype.StartGame = function() 			{ this.StopGame(); };
GameInstance.prototype.StopGame	= function()			{};
GameInstance.prototype.PauseGame = function( bPause )	{};

GameInstance.prototype.SetTypeNameDisplay = function( type )
{
	var extra = '';
	if ( this.mDailyPuzzleDate )
	{
		extra = this.mDailyPuzzleDate;
	}
	Game.prototype.SetTypeNameDisplay.call( this, type, extra );
};

GameInstance.prototype.SetupPage = function( parent, notLoggedInDivName, adRightDivName )
{

	if ( notLoggedInDivName )
	{
		this.mNotLoggedInDiv = GetElement( notLoggedInDivName );
		
		if ( this.mNotLoggedInDiv )
		{
			var anchors = this.mNotLoggedInDiv.getElementsByTagName( 'A' );
			for ( var i = 0; i < anchors.length; ++i )
			{
				var a = anchors[i];
				if ( a )
				{
					a.target = '_blank';
					var index = a.href.search( /register\.pl/ );
					if ( index > -1 )
					{
						a.onclick = function( evt ) { GameInstance.RegisterOnClick( evt ); }
					}
					else // index page, main page
					{
						a.onclick = function( evt ) { GameInstance.LogInOnClick( evt ); }
					}
				}
			}
		}
		
		this.UpdateLogInMsg();
	}
	
	if ( adRightDivName )
	{
		this.mAdRightDiv = GetElement( adRightDivName );
	}
	
	Game.prototype.SetupPage.call( this, parent );
};

GameInstance.prototype.UpdateLogInMsg = function()
{
	if ( this.mNotLoggedInDiv )
	{
		this.mNotLoggedInDiv.style.display = (this.mbLoggedIn || IsEmbededMini()) ? 'none' : ''; 
	}
	if ( this.UpdateStats )
	{
		this.UpdateStats();
	}
};


GameInstance.prototype.FatalError = function ( msg, textColor )
{
	if ( !msg ) { msg = 'A fatal error has occurred. An error has been sent to ZooEscape.com. Please try again later.'; }
	if ( !textColor ) { textColor = '#FF0000'; }
	
	var html = '<DIV style="color:' + textColor + '">' + msg + '</DIV>';
	var padding = IsEmbededMini() ? 2 : 8;
	html += 	'<DIV style="text-align:center; padding-top:'+padding+'px;"><INPUT type="button" onclick="GameVariation.GoToLobby();" value="Return to Lobby"></DIV>';

	this.mbNavigateWarn = false;
	Game.prototype.FatalError.call( this, html, '#000000' );
};

GameInstance.prototype.ShowBoard = function( bShow )
{
	if ( this.mBoard )
	{
		this.mBoard.Show( bShow );
	}
};

//--- Begin GameLobby ----------------------------------------------------------------------------------------------------------------------//
GameLobby.SetupRankNotifications = function( notifyRankDivName, notifyGran, currGran )
{
	var g = Game.mSingleton;
	if ( !g ) { return; }

	g.mRankNotifyElement 		= GetElement( notifyRankDivName );
	g.mRankNotifyGranularities 	= notifyGran;
	g.mCurrRankGranularity		= currGran;
};

GameLobby.GoToRoom = function( index )
{
	if ( Game.mSingleton )
	{
		Game.mSingleton.GoToRoom( index );
	}	
};

GameLobby.prototype = new Game();
GameLobby.prototype.constructor = GameLobby;
function GameLobby()
{
	this.mTabElements;
	this.mVariationElements;
	this.mType;
	Game.call( this );
}

GameLobby.prototype.GoToRoom = function( index, arg )
{
	var v = GameVariation.SetCurrentVariationAtIndex( index );
	if ( !v ) { return; }
	var id = v.DetermineID( arg );
	if ( id > 0 )
	{
		GameVariation.GoToRoom( id );
	}
};

GameLobby.prototype.CreateHeading = function( e )
{
	if ( !e ) { return; }
	
	Game.CreateTitleAndVariation( e, false );
};

GameLobby.prototype.GetHTML_Variations = function()
{
	var html = '';
	if ( GameVariation.mVariations && GameVariation.mVariations.length )
	{
		var rowHeight = IsEmbededMini() ? 36 : 40;
		for ( var i=0; i <= GameVariation.mVariations.length; ++i ) 
		{
			if ( GameVariation.mVariations[i] && (!gbMultiplayer || GameVariation.mVariations[i].mMPID > 0) )
			{
				var fancyTxt = Game.FancifyText( GameVariation.mVariations[i].mName.toUpperCase(), (IsEmbededMini() ? (Game.kTitleLeterLinkEmbed + ' ') : '') + Game.kLetterClass );
				var id 	= GameVariation.mVariations[i].mElementID;			
				html +=			'<TR id="' + id + '" style="height:' + rowHeight + 'px;">';
				html +=				IsEmbededMini() ? '' : ('<TD id="' + id + 'play' +'" style="vertical-align:middle; padding-left:12px; font-weight:bold; cursor:pointer;">&gt;&gt;</TD>');
				html +=				'<TD id="' + id + 'title' + '" class="wg_text" style="vertical-align:middle; padding-left:4px; padding-right:8px;">' + fancyTxt + '</TD>';
				html +=				'<TD style="padding-right:'+ (IsEmbededMini() ? '4' : '12') + 'px;"><IMG id="' + id + 'info' + '" class="info" src="/img/info.png"></TD>';
				html +=			'</TR>';
				if ( !IsEmbededMini() )
				{
					var desc = GameVariation.mVariations[i].mDesc;
					if ( desc )
					{
						desc += '...&nbsp;&nbsp;&nbsp;<A href="" onclick="Game.RulesInlineOnClick(\'' + GameVariation.mVariations[i].GetRulesDivID() + '\'); return false;">more &raquo;</A>';
					}
					else
					{
						desc = '';
					}
					html +=		'<TR'+ (desc ? ' style="height:20px;"' : '') +'><TD></TD><TD class="wg_text" style="text-align:left; vertical-align:top; padding-left:12px; padding-right:12px; padding-bottom:4px;' + (desc ? ' width:350px;' : '') + '">' + desc + '</TD></TR>';
				}
			}
		}
	}	
	return html;
};

GameLobby.prototype.GetHTML_Tabs = function()
{
	if ( !this.mTabElements ) { return ''; }
	var html = '';	
	var tabClass = IsEmbededMini() ? 'wg_tab_embed' : 'wg_tab';
	html +=		'<TABLE cellpadding=0 cellspacing=0 border=0 style="width:100%;"><TR>';
	for ( var i = 0; i < this.mTabElements.length; ++i )
	{
		var el = this.mTabElements[i];
		if ( el )
		{
			var id = 'id= "ze_lobby_tab_' + i + '"';
			el.mType = el.getAttribute( 'href' );
			var stuff = el.mType.match( /type=(.+)/ );
			el.mType = ConvertToInt( stuff[1] );
			var cName = 'class="' + ((el.mType == this.mType) ? 'wg_tab_sel' : tabClass) + '"';
			html +=		'<TD class="wg_tab_empty">&nbsp;</TD><TD ' + id + cName+'></TD>';
		}
	}
	
	html +=	 		'<TD class="wg_tab_empty">&nbsp;</TD>';
	html +=		'</TR></TABLE>';
	return html;
};

GameLobby.prototype.SetupTabs = function()
{
	if ( !this.mTabElements ) { return; }
	var lobby = this;
	for ( var i = 0; i < this.mTabElements.length; ++i )
	{
		var el = this.mTabElements[i];
		if ( el )
		{
			var id = 'ze_lobby_tab_' + i.toString();
			var td = GetElement( id );
			if ( td )
			{
				el.parentNode.style.display = 'none';
				td.appendChild( el );
				td.mHREF = el.getAttribute( 'href' );
				td.mTypeName = el.innerHTML;
				td.mTypeDescription = '<TABLE><TR><TD style="font-weight:bold; border-bottom:1px solid #000000;">' + td.mTypeName + '</TD></TR><TR><TD>' + el.getAttribute( 'desc' ) + '</TD></TR></TABLE>';
				if ( el.mType == this.mType )
				{
					this.mTypeDescription = td.mTypeDescription;
				}
				if ( el.mType != this.mType )
				{
					td.onmouseover = function ()
					{
						var obj = this;
						if ( lobby.mTypeDescriptionElement )
						{
							lobby.mTypeDescriptionElement.style.verticalAlign = 'top';
							lobby.mTypeDescriptionElement.innerHTML = obj.mTypeDescription;
						}
						Game.TabOnMouseOver( obj );
					};
					td.onmouseout = function ()
					{
						var obj = this;
						if ( lobby.mTypeDescriptionElement )
						{
							lobby.mTypeDescriptionElement.innerHTML = lobby.mTypeDescription;
						}
						Game.TabOnMouseOut( obj );
					};
					td.onmouseup = function ()
					{
						RedirectImmediate( this.mHREF );
					};
					td.onclick = function()
					{
						return false;
					};
				}
			}			
		}
	}
};

GameLobby.prototype.SetupVariations = function()
{
	for ( var i=0; GameVariation.mVariations && i <= GameVariation.mVariations.length; ++i ) 
	{
		if ( !GameVariation.mVariations[i] ) { continue; }
		
		var e = GetElement( GameVariation.mVariations[i].mElementID );
		if ( e )
		{	
			e.mbDisabled = (gbMultiplayer && !this.mbLoggedIn) ? true : false;
			e.mWGIndex = i;

			var parent = e.parentNode;
			var anchor = this.mVariationElements ? this.mVariationElements[i] : undefined;
			if ( anchor && parent )
			{
				anchor.style.display = 'none';
				e.appendChild( anchor );
			}

			var divs = e.getElementsByTagName( 'DIV' );
			for ( var j = 0; j < divs.length; ++j )
			{
				var div = divs[j];
				if ( div.className.indexOf( Game.kLetterClass ) >= 0 )
				{
					div.mbRolloverable = true;
					div.mbDisabled = e.mbDisabled;
					div.mDefaultClassName = div.className;
					div.mDisabledClassName = Game.kLetterClassDisabled + ' ' + div.className;
					div.mOverClassName = Game.kLetterClassOver + ' ' + div.className;
					
					if ( div.mbDisabled )
					{
						var inputs = e.getElementsByTagName( 'INPUT' );
						for ( var k = 0; k < inputs.length; ++k )
						{
							if ( inputs[k].type == 'button' )
							{
								inputs[k].disabled = true;
							}
						}
						
						div.className = div.mDisabledClassName;
					}
				}
			}
			
		}
		
		var description =  (GameVariation.mVariations[i].mDesc ? GameVariation.mVariations[i].mDesc : '');
		var titleE = GetElement( GameVariation.mVariations[i].mElementID + 'title' );
		if ( titleE )
		{
			titleE.mbDisabled = e.mbDisabled;
			titleE.style.cursor = 'pointer';
			titleE.mWGIndex = i;
			titleE.mDesc = description;
			titleE.onmouseover = function ( evt )
			{
				var obj = this;
				if ( IsEmbededMini() && obj.mDesc )
				{
					UI_ShowPopup( true, obj.mDesc, 200, evt );
				}
				Game.VariationOnMouseOver( evt, obj );
			};
			titleE.onmouseout = function ( evt )
			{
				var obj = this;
				if ( IsEmbededMini() && obj.mDesc )
				{
					UI_ShowPopup( false );
				}
				Game.VariationOnMouseOut( evt, obj );
			};			
			titleE.mOrigOnMouseOut = titleE.onmouseout;
			titleE.onclick = function ( evt )
			{
				var obj = this;
				GameLobby.GoToRoom( obj.mWGIndex );
			};
		}	
			
		var playE = GetElement( GameVariation.mVariations[i].mElementID + 'play' );
		if ( playE )
		{			
			playE.mWGIndex = i;
			playE.mDesc = description;
			playE.onmouseover = function ( evt )
			{
				var obj = this;
				if ( IsEmbededMini() )
				{
					UI_ShowPopup( true, obj.mDesc, 200, evt );
				}
				Game.VariationOnMouseOver( evt, obj );
			};
			playE.onmouseout = function ( evt )
			{
				var obj = this;
				if ( IsEmbededMini() )
				{
					UI_ShowPopup( false );
				}
				Game.VariationOnMouseOut( evt, obj );
			};
			playE.onclick = function ( evt )
			{
				var obj = this;
				GameLobby.GoToRoom( obj.mWGIndex );
			};
		}
		
		var infoE = GetElement( GameVariation.mVariations[i].mElementID + 'info' );
		if ( infoE )
		{
			infoE.mWGIndex = i;
			infoE.onmouseover = function ( evt )
			{
				Game.InfoOnMouseOver( evt, this.mWGIndex );
			}
		}		
	}

};

GameLobby.prototype.SetupLinks = function()
{
	var g = this;
	
	if ( this.mRankNotifyElement )
	{
		var div = this.mRankNotifyElement;
		div.onclick = function()
		{
			var html = '';
			if ( g.mbLoggedIn )
			{
				g.mRankNotifyButtonNames = new Array();
				var radioName = div.id;
				html = '<TABLE border=0 cellpadding=4 cellspacing=6 style="margin:10px;"><TR><TD colspan=2 style="font-weight:bold; border-bottom:1px solid #000000;">Notify me when my rank drops by:</TD></TR>';
				for ( var i=0; i< g.mRankNotifyGranularities.length; ++i )
				{
					var desc = g.mRankNotifyGranularities[i];
					if ( i > 0 )
					{
						desc += ' or more positions';
					}
					var id = radioName +  '_' + i;
					g.mRankNotifyButtonNames[i] = id;
					html += '<TR><TD style="vertical-align:middle;" onclick="GameLobby.OnClickRankNotifyOption('+i+');">';
					html += '<INPUT type="radio" id="'+id+'" name="'+radioName+'"'+(i==g.mCurrRankGranularity?' checked':'')+' value="'+i+'"></TD>';
					html += '<TD style="small" style="text-align:left; vertical-align:middle;" onclick="GameLobby.OnClickRankNotifyOption('+i+');"><LABEL for="'+id+'">'+ desc +'</LABEL></TD></TR>';
				}
				html += '<TR><TD colspan=2 style="padding-top:4px;"><INPUT id="ze_button_submit_rank" type="button" value="Submit" onclick="GameLobby.OnSubmitRankNotifyOptions(\''+radioName+'\');">&nbsp;<INPUT type="button" value="Cancel" onclick="UI_ShowOverlay(false);"></TD></TR></TABLE>';
			}
			else
			{
				html = '<TABLE border=0 cellpadding=4 cellspacing=6 style="margin:10px;"><TR><TD>You must be <A href="/">logged in</A> to sign up for notifications.</TD></TR><TR><TD style="padding-top:4px;"><INPUT type="button" value=" OK " onclick="UI_ShowOverlay(false);"></TD></TR></TABLE>';
			}

			UI_ShowOverlay( true, html );
			g.mButton_SubmitRankNotify = GetElement( 'ze_button_submit_rank' );
			if ( g.mButton_SubmitRankNotify )
			{
				g.mButton_SubmitRankNotify.disabled = true;	
			}
		};
	}
};

GameLobby.OnClickRankNotifyOption = function( index )
{
	var lobby = Game.mSingleton;
	if ( !lobby ) { ErrorOutput( 'No lobby object' ); return; }
	
	lobby.mButton_SubmitRankNotify.disabled = (index == lobby.mCurrRankGranularity);
};

GameLobby.OnSubmitRankNotifyOptions = function( groupName )
{
	var lobby = Game.mSingleton;
	if ( !lobby ) { ErrorOutput( 'No lobby object' ); return; }

	if ( lobby.mRR ) { ErrorOutput( 'Remote request already pending' ); return; }

	var bDoGenericError = false;
	if ( lobby.mRankNotifyButtonNames )
	{
		lobby.mNewRankGranularity = lobby.mCurrRankGranularity;
		for ( var i = 0; i < lobby.mRankNotifyButtonNames.length; ++i )
		{
			var el = GetElement( lobby.mRankNotifyButtonNames[i] );
			if ( el )
			{
				if ( el.checked )
				{
					lobby.mNewRankGranularity = el.value;
					break;
				}
			}
			else
			{
				ErrorOutput( 'No notify radio button with name ' + lobby.mRankNotifyButtonNames[i] );
			}
		}
		
		if ( lobby.mNewRankGranularity != lobby.mCurrRankGranularity )
		{		
			var reqTxt = groupName + '=' + lobby.mNewRankGranularity;
			//DebugOutput( reqTxt );
			this.mRR = RemoteRequest.NewRequest( '/notifications.pl', reqTxt, {mCompletion:{obj:lobby,funcName:'PostHandler_Complete'}, mTimeout:{obj:lobby,funcName:'PostHandler_Timeout'}}, true );
			if ( !(this.mRR && this.mRR.Issue()) )
			{
				bDoGenericError = true;
				lobby.PostCleanup();
			}
			else
			{
				UI_ShowOverlay( true, '<DIV style="margin:10px;">Sending request...</DIV>' );
			}
		}	
		else
		{	
			UI_ShowOverlay( false );
			DebugOutput( 'no changes' );
		}
	}
	else
	{
		ErrorOutput( 'No lobby radio button names array' );
		bDoGenericError = true;
	}	
	
	if ( bDoGenericError )
	{
		UI_ShowOverlay( false );
		UI_ShowGenericErrorPopup();		
	}
};

GameLobby.prototype.PostCleanup = function()
{
	if ( this.mRR )
	{
		RemoteRequest.DeleteRequest( this.mRR );
		this.mRR = undefined;
	}
};

GameLobby.prototype.PostHandler_Complete = function( response, rr )
{
	DebugOutput( response );
	this.PostCleanup();
	UI_ShowOverlay( false );
	var args = response.split( '&' );
	if ( args && args[0] == 'ze_ok' )
	{
		var div = this.mRankNotifyElement;
		if ( div.id == args[1] ) 
		{
			var html = '<TABLE><TR><TD style="vertical-align:top; padding-right:4px;">' + GetHTML_StatusIcon(1) + '</TD><TD style="vertical-align:middle;">Game rank change notification has been submitted.</TD></TR></TABLE>';
			this.mCurrRankGranularity = this.mNewRankGranularity;
			this.mNewRankGranularity = undefined;
			UI_ShowPopupMessage( true, html, 1, 1 );
		}
	}
	else
	{
		UI_ShowGenericErrorPopup();
	}
};

GameLobby.prototype.PostHandler_Timeout = function( response, rr )
{
	this.PostCleanup();
	UI_ShowOverlay( false );
	UI_ShowRequestTimeoutPopup();
};

//--- Begin GameRoom -----------------------------------------------------------------------------------------------------------------------//
GameRoom.prototype = new Game();
GameRoom.prototype.constructor = GameRoom;
function GameRoom( v )
{
	Game.call( this );
	this.mCurrentVariation = v;
	this.mHighScoresOverallDivName = '';
	this.mHighScoresMonthlyDivName = '';
	this.mHighScoresDailyDivName = '';
}

GameRoom.prototype.CreateEnding = function( e )
{
	if ( !e ) { return; }
	
	var html = '<TABLE><TR><TD><DIV id="ze_nav_links_dest" style="padding-bottom:4px;"></DIV></TD></TR><TR><TD><INPUT id="ze_nav_lobby" type=button value="'+kTxt_ReturnToLobby+'" onclick="GameVariation.GoToLobby();"></TD></TR></TABLE>';
	e.innerHTML = html;
	if ( this.mNavLinksDivName )
	{
		var lobby = GetElement( 'ze_nav_lobby' );
		if ( lobby )
		{
			var link = this.mNavLinks.mLobby;
			if (link )
			{
				link.innerHTML = '';
				link.style.cursor = 'default';
				lobby.parentNode.appendChild( link );
				//link.appendChild( lobby ); // REVISIT -- exception happens here
				lobby.mHREF = link.getAttribute( 'href' );
				lobby.onclick = function ()
				{
					var obj = this;
					RedirectImmediate( obj.mHREF );	
				};
			}
		}		

		var parent = GetElement( 'ze_nav_links_dest' );
		if ( parent && !this.mGIPDivName )
		{
			var link = this.mNavLinks.mPrev;
			var typeName = GameVariation.GetTypeName( GameVariation.mCurrentVariation.mType ) + (GameVariation.mCurrentVariation && GameVariation.mCurrentVariation.IsTimed()?' Timed' : '');
			if ( link )
			{
				parent.appendChild( link );
				Game.CreateNav( link, ' &lt; ', 'Click to go to<BR>' + typeName + ' ' + link.innerHTML + ' Room' );
				link.style.marginRight = '2px';
			}
				
			link = this.mNavLinks.mNext;
			if ( link )
			{
				parent.appendChild( link );
				Game.CreateNav( link, ' &gt; ', 'Click to go to<BR>' + typeName + ' ' + link.innerHTML + ' Room' );
				link.style.marginLeft = '2px';
			}
		}
		else
		{
			var src = GetElement( this.mNavLinksDivName );
			if ( src )
			{
				src.style.display = 'none';
			}
		}
	}		

};


//--- Begin BoardElement -----------------------------------------------------------------------------------------------------------------------//
function BoardElement( e, row, col ) 
{
	this.mRowIndex = row;
	this.mColIndex = col;
	this.mElement = e;

	this.mMarginLeft = BoardElement.kMarginLeft;
	this.mMarginRight = BoardElement.kMarginRight;

	this.mbMutable = true;
	this.mbEnabled = true;

	this.mClassDefault = 'bg_point';
	this.mClassSelected = 'bg_point_sel';
	this.mClassOver = 'bg_point_over';	
	
	this.mHeightOffset = 0;
	this.mWidthOffset = 0;
}

BoardElement.kEmbedFactor 		= 0.8;
BoardElement.kElementIDPrefix 	= 'ze_el';
BoardElement.kBorder 			= 1;
BoardElement.kFontSize 			= 16;
BoardElement.kWidth 			= 25;
BoardElement.kHeight			= 25;
BoardElement.kMarginLeft		= 0;
BoardElement.kMarginRight		= 0;
BoardElement.kPadding 			= 0;

BoardElement.prototype.SetMutable = function( bOn )
{
	this.mbMutable = bOn ? true : false;
};

BoardElement.prototype.Reset = function() 
{
	this.Clear();
};

BoardElement.prototype.SetDefaults = function ()
{
	if ( !(this.mElement && this.mbMutable && this.mbEnabled) ) { return; }

	this.mElement.className = this.mClassDefault; // 'wg_letter_box';
	this.mElement.style.visibility = 'visible'; // this.Show( true ); // ??
};
	
BoardElement.prototype.Clear = function() 
{
	if ( !(this.mbMutable && this.mbEnabled) ) { return; }

	this.KillAnimator();
	this.mbUsed = false;
	this.mbDone = false;
	if ( this.mbMouseOver )
	{
		UI_ShowPopup( false );
	}
	this.mbMouseOver = false;	
	this.SetDefaults();
};

BoardElement.prototype.Show = function ( bShow )
{
	if ( this.mElement )
	{
		this.mElement.style.visibility = bShow ? 'visible' : 'hidden';	
	}
};
		
BoardElement.prototype.Select = function( bSelect ) 
{	
	if ( !(this.mbMutable && this.mbEnabled && this.mElement) ) return;

	if ( bSelect === undefined ) bSelect = true;

	this.mElement.className = bSelect ? this.mClassSelected : this.mClassDefault; // 'wg_letter_box_sel wg_letter_box'; //this.mElement.className; //DebugOutput( this.mElement.className );
	if ( this.mbMouseOver )
	{
		UI_ShowPopup( false );
	}
};

BoardElement.prototype.KillAnimator = function ()
{
	if ( this.mAnimator )
	{
		this.mAnimator.Kill();
		this.mAnimator = undefined;
	}
};

BoardElement.prototype.GetValue = function()
{
	return this.mValue;
};

BoardElement.prototype.SetValue = function( val, html )
{
	if ( !(this.mbMutable && this.mbEnabled) ) { return; }

	this.mValue = val;
//	if ( !html ) 
//	{ 
//		html = val?val.toString():''; 
//	}
	
	this.SetHTML( html );
	return true;
};

BoardElement.prototype.SetHTML = function( h )
{
	if ( !(this.mbMutable && this.mbEnabled) ) { return; }
	if ( !this.mElement ) { return; }
	
	if ( h === undefined ) { h = ''; }
	
	this.mElement.innerHTML = h;
};
	
BoardElement.prototype.OnMouseOver = function ( evt ) 
{	
	if ( !(this.mElement && this.mbMutable && this.mbEnabled) ) { return; }

	this.mbMouseOver = true;
	if ( this.mClassOver )
	{
		this.mElement.className = this.mClassOver + ' ' +  this.mElement.className;
	}
	else
	{
		var curClasses = this.mElement.className.split( ' ' );
		this.mElement.className = '';
		for ( var i=0;i<curClasses.length;++i ) 
		{
			this.mElement.className += ' ' + curClasses[i] + '_over ' + curClasses[i];
		}
	}
//	DebugOutput( this.mElement.className );
};
	
BoardElement.prototype.OnMouseOut = function ( evt ) 
{
	if ( !(this.mElement && this.mbMutable && this.mbEnabled) ) { return; }

//	DebugOutput( 'Mouse out' );
	if ( this.mbMouseOver )
	{
		UI_ShowPopup( false );
	}
	this.mbMouseOver = false;
	var curClasses = this.mElement.className.split( ' ' );
	this.mElement.className = '';
	for ( var i=0;i<curClasses.length;++i ) 
	{
		var bSkip = false;
		if ( this.mClassOver )
		{
			bSkip = curClasses[i] == this.mClassOver ? true : false;
		}
		else
		{
			bSkip = curClasses[i].match( /_over/ ) ? true : false;
		}
		if ( !bSkip )
		{
			this.mElement.className += ' ' + curClasses[i];
		}
	}
	
//	DebugOutput( this.mElement.className );
};
//--- End BoardElement -----------------------------------------------------------------------------------------------------------------------//


//--- Begin BoardSquare -----------------------------------------------------------------------------------------------------------------------//
BoardSquare.prototype = new BoardElement();
BoardSquare.prototype.constructor = BoardSquare;
function BoardSquare( e, row, col ) 
{
	BoardElement.call( this, e, row, col );
	
	this.mClassDefault = 'wg_letter_box';
	this.mClassSelected = 'wg_letter_box_sel wg_letter_box';
	this.mClassOver = 'wg_letter_box_over';	
}

BoardSquare.kEmbedFactor			= 0.8;
BoardSquare.kSquareIDPrefix 		= 'ze_sq';
BoardSquare.kSquareBorder 			= 1;
BoardSquare.kSquareFontSize 		= 16;
BoardSquare.kSquareWidth 			= 25;

BoardSquare.GetWidth = function ()
{
	var width = BoardSquare.kSquareWidth;
	if ( IsEmbededMini() )
	{
		width = Math.floor(BoardSquare.kSquareWidth * BoardSquare.kEmbedFactor);
		//DebugOutput( width );
		if ( width % 2 == 1 )
		{
//			++width;
			//DebugOutput( width );
		}
	}
	return width;
};

BoardSquare.GetFontSize = function ()
{
	return (IsEmbededMini() ? Math.floor(BoardSquare.kSquareFontSize * BoardSquare.kEmbedFactor) : BoardSquare.kSquareFontSize);
};

BoardSquare.prototype.Reset = function() 
{
	if ( !this.mElement ) { return; }
	
	this.Clear();
	this.mOrigTop 				= this.GetTop();
	this.mElement.style.left 	= this.GetLeft() + 'px';
	this.mElement.style.top 	= this.mOrigTop + 'px';
	this.mElement.style.width 	= BoardSquare.GetWidth() + 'px';
	this.mElement.style.height 	= BoardSquare.GetWidth() + 'px';
	this.mElement.style.fontSize = BoardSquare.GetFontSize() + 'px';
	this.mElement.style.padding = '0px';
	this.mElement.style.borderWidth = BoardSquare.kSquareBorder + 'px';
	this.mElement.style.borderStyle = 'solid';
	this.mDestRow 				= -1;
	this.mDestTop 				= -1;
	this.mbPaused 				= false;	
};
	
BoardSquare.prototype.GetTop = function(r) 
{
	if ( r === undefined ) { r = this.mRowIndex; }
	var top = r*(BoardSquare.GetWidth() + (2*BoardSquare.kSquareBorder));
	return top;
};
	
BoardSquare.prototype.GetTopCenter = function(r) 
{
	return this.GetTop(r) + Math.floor((BoardSquare.GetWidth() + (this.mMarginLeft+this.mMarginRight) + 2*BoardSquare.kSquareBorder)*0.5);
};
		
BoardSquare.prototype.GetLeft = function(c) 
{
	if ( c === undefined ) { c = this.mColIndex; }
	var left = c*(BoardSquare.GetWidth() + (2*BoardSquare.kSquareBorder)) + (c+1)*(this.mMarginLeft + this.mMarginRight);
	return left;
};
	
BoardSquare.prototype.GetLeftCenter = function(c) 
{
	return (this.GetLeft(c))+ Math.floor((BoardSquare.GetWidth() + (this.mMarginLeft+this.mMarginRight) + 2*BoardSquare.kSquareBorder)*0.5);
};
	
BoardSquare.prototype.SetRowIndexFromTop = function( top )
{
	if ( !this.mElement ) { return; }
	if ( top === undefined ) { top = this.mElement.offsetTop; }
	//DebugOutput( top );
	var height = BoardSquare.GetWidth() + (2*BoardSquare.kSquareBorder);
	this.mRowIndex = Math.floor( (top + 2*BoardSquare.kSquareBorder) / height );
	if ( this.mRowIndex < 0 ) { ErrorOutput( 'row index is set to ' + this.mRowIndex ); }
};
	

BoardSquare.prototype.SetDefaults = function ()
{
	if ( !(this.mElement && this.mbMutable && this.mbEnabled) ) { return; }

	this.mElement.className = this.mClassDefault; // 'wg_letter_box';
	this.mElement.style.visibility = 'visible'; // this.Show( true ); // ??
};
	
BoardSquare.prototype.Clear = function() 
{
	if ( !(this.mbMutable && this.mbEnabled) ) { return; }

	this.KillAnimator();
	this.mbUsed = false;
	this.mbDone = false;
	if ( this.mbMouseOver )
	{
		UI_ShowPopup( false );
	}
	this.mbMouseOver = false;	
	this.SetDefaults();
};

BoardSquare.prototype.SetPaused = function ( bPaused )
{
	this.mbPaused = bPaused;
	if ( this.mAnimator )
	{
		this.mAnimator.mbPaused = this.mbPaused;
	}
};

BoardSquare.prototype.GetValue = function()
{
	return this.mValue;
};

BoardSquare.prototype.SetValue = function( val, html )
{
	if ( !(this.mbMutable && this.mbEnabled) ) { return; }

	this.mValue = val;
	if ( !html ) 
	{ 
		html = val?val.toString():''; 
	}
	
	this.SetHTML( html );
};

BoardSquare.prototype.SetHTML = function( h )
{
	if ( !(this.mbMutable && this.mbEnabled) ) { return; }
	if ( !this.mElement ) { return; }
	
	if ( h === undefined ) { h = ''; }
	
	this.mElement.innerHTML = h;
};
	
BoardSquare.prototype.OnMouseOver = function ( evt ) 
{	
	if ( !(this.mElement && this.mbMutable && this.mbEnabled) ) { return; }

	this.mbMouseOver = true;
	if ( this.mClassOver )
	{
		this.mElement.className = this.mClassOver + ' ' +  this.mElement.className;
	}
	else
	{
		var curClasses = this.mElement.className.split( ' ' );
		this.mElement.className = '';
		for ( var i=0;i<curClasses.length;++i ) 
		{
			this.mElement.className += ' ' + curClasses[i] + '_over ' + curClasses[i];
		}
	}
};
	
BoardSquare.prototype.OnMouseOut = function ( evt ) 
{
	if ( !(this.mElement && this.mbMutable && this.mbEnabled) ) { return; }

//	DebugOutput( 'Mouse out' );
	if ( this.mbMouseOver )
	{
		UI_ShowPopup( false );
	}
	this.mbMouseOver = false;
	var curClasses = this.mElement.className.split( ' ' );
	this.mElement.className = '';
	for ( var i=0;i<curClasses.length;++i ) 
	{
		var bSkip = false;
		if ( this.mClassOver )
		{
			bSkip = curClasses[i] == this.mClassOver ? true : false;
		}
		else
		{
			bSkip = curClasses[i].match( /_over/ ) ? true : false;
		}
		if ( !bSkip )
		{
			this.mElement.className += ' ' + curClasses[i];
		}
	}	
};
//--- End BoardSquare -----------------------------------------------------------------------------------------------------------------------//
	

//--- Begin Board -----------------------------------------------------------------------------------------------------------------------//
function Board( rows, cols, parent )
{
	this.mNumRows = rows;
	this.mNumCols = cols;
	this.mElements = undefined;
	this.mParentElement = parent;

	if ( this.mElementConstructor === undefined )
	{
		this.mElementConstructor = BoardSquare;
	}
	if ( this.mElementIDPrefix === undefined )
	{
		this.mElementIDPrefix = BoardSquare.kSquareIDPrefix;
	}
}

Board.prototype.Init = function( boardStr, bStartHidden )
{
	var board = this;
	if ( this.mNumRows && this.mNumCols )
	{
		this.mElements = new Array( this.mNumRows );
		for ( var i=0; i < this.mNumRows; ++i ) 
		{
			this.mElements[i] = new Array( this.mNumCols );
			for ( var j=0; j < this.mNumCols; ++j ) 
			{
//				DebugOutput( 'Looking for: ' + this.mElementIDPrefix + i.toString() + '-' + j.toString() );

				var e = GetElement( this.mElementIDPrefix + i.toString() + '-' + j.toString() );
				if ( e )
				{
					e.onmouseover 	= function ( evt ) { var obj=this; board.OnMouseOver(evt,obj); }
					e.onmouseout 	= function ( evt ) { var obj=this; board.OnMouseOut(evt,obj); }	
				}
				var sq = new this.mElementConstructor( e, i, j );
				if ( sq )
				{
					if ( e ) { e.mBoardElement = sq; }
					this.InitElement( sq, i, j, (boardStr?boardStr.charAt(i*this.mNumRows + j):undefined), bStartHidden );
				}
			}
		}
	}
};

Board.prototype.InitElement = function( sq, row, col, val, bHide )
{
	if ( !sq ) { return; }
	if ( bHide === undefined ) { bHide = true; }
	
	this.SetElement( sq, row, col );
	sq.Reset();
	this.SetValue( sq, val );
	if ( bHide && sq.mElement )
	{
		sq.mElement.style.visibility = 'hidden'; // start off hidden for animations
	}
};

Board.prototype.SetValue = function( sq, val )
{
	if ( !sq ) { return; }
	sq.SetValue( val );
};

Board.prototype.SetElement = function ( sq, row, col )
{
	if ( !(row >= 0 && row < this.mNumRows && col >= 0 && col < this.mNumCols && this.mElements && this.mElements[row]) ) { return; }
	this.mElements[row][col] = sq;
};

Board.prototype.GetElement = function ( row, col )
{
	if ( this.mElements && row !== undefined && col !== undefined && this.mElements[row] ) { return this.mElements[row][col]; }
};

Board.prototype.GetElementAtOffset = function ( offset )
{
	var row = Math.floor(offset/this.mNumCols);
	var col = offset%this.mNumCols;
	if ( offset !== undefined ) { return this.GetElement( row, col ); }
};

Board.prototype.OnMouseOver = function ( evt, e )
{
	if ( e && e.mBoardElement ) { e.mBoardElement.OnMouseOver( evt ); }
};

Board.prototype.OnMouseOut = function ( evt, e )
{
	if ( e && e.mBoardElement ) { e.mBoardElement.OnMouseOut( evt ); }
};

Board.prototype.SelectElement = function( sq, bSelect )
{
	if ( !sq ) { return; }
	sq.Select( bSelect );
};

Board.prototype.Show = function( bShow )
{
	if ( this.mParentElement ) 
	{
		this.mParentElement.style.visibility = bShow ? 'visible' : 'hidden';
	}
	
	for ( i=0; i<this.mNumRows; ++i ) 
	{
		for ( j=0; j<this.mNumCols; ++j ) 
		{
			var curSq = this.GetElement( i, j );
			if ( curSq ) 
			{
				curSq.Show( bShow );
			}
		}
	}
};

//--- End Board -----------------------------------------------------------------------------------------------------------------------//

//--- Begin Dice ----------------------------------------------------------------------------------------------------------------------//
function Dice( objs )
{
	this.mDieObjs = objs;
}

Dice.prototype.GetDie = function(i)
{
	if ( !(this.mDieObjs && i>=0 && i<this.mDieObjs.length) ) { return; }
	
	return this.mDieObjs[i];
};

function Die( el )
{
	this.mElement 	= el;
	this.mValue 	= 0;
	this.mColor;
	this.mPipColor;
}

Die.prototype.Set = function( val, color, pipColor, dieClass, pipClass, bActive )
{
	this.mColor 	= color; // this is NOT the mapped color
	this.mPipColor 	= pipColor; // this is used for the image so it's the mapped color
	this.mValue 	= val;
	
	if ( this.mElement )
	{
		this.mElement.innerHTML = '';

		var parent = document.createElement( 'DIV' );
		parent.style.position = 'relative';
		this.mElement.appendChild( parent );
	
		var img = '/img/'+dieClass+ '.png';
		var w = bActive ? Die.kDieWidth_Large : Die.kDieWidth;
		parent.innerHTML = '<IMG src="'+img+'" class="'+dieClass+'" style="width:'+w+'px; height:'+w+'px;">';
		var div = document.createElement( 'DIV' );
		parent.appendChild( div );
		div.style.position = 'absolute';
		var padding = bActive ? 1 : 0; // REVISIT
		div.innerHTML = this.GetHTML_Pips( val, pipClass, padding, bActive ? Die.kPipHeight_Large : Die.kPipHeight );
		var tableWidth = (Die.kPipHeight*3) + (3*2*padding);
		var offset = Math.floor(0.5*(w-tableWidth));
		div.style.top 	= offset + 'px';
		div.style.left 	= offset + 'px';
		div.style.width = tableWidth + 'px';
		div.style.height = tableWidth + 'px';
	}
};

Die.prototype.GetHTML_Pips = function( val, cl, padding, height )
{	
	var html = '';
	if ( val )
	{
		html = '<TABLE cellpadding=0 cellspacing=0 border=0>';
		for ( var i = 0; i < 3; ++i )
		{
			html += '<TR>';
			for ( var j = 0; j < 3; ++j )
			{
				var bVisible = false;
				if ( val==1 || val==3 || val==5 )
				{
					bVisible = (i==1 && j==1) ? true : false;
					if ( !bVisible && (val==3 || val==5) )
					{
						bVisible = ((i==0 && j==0) || (i==2 && j==2)) ? true : false;
						if ( !bVisible && val==5 )
						{
							bVisible = ((i==0 && j==2) || (i==2 && j==0)) ? true : false;
						}
					}
				}
				else
				if ( val==2 || val==4 || val==6 )
				{
					bVisible = ((i==0 && j==0) || (i==2 && j==2)) ? true : false;
					if ( !bVisible && (val==4 || val==6) )
					{
						bVisible = ((i==0 && j==2) || (i==2 && j==0)) ? true : false;
						if ( !bVisible && val==6 )
						{
							bVisible = ((i==1 && j==0) || (i==1 && j==2)) ? true : false;
						}
					}
				}
				else
				{
					ErrorOutput( 'Invalid value for this die: ' + val );
				}
				html += '<TD style="padding:'+padding+'px; visibility:'+(bVisible?'visible':'hidden')+'"><IMG class="'+cl+'" src="/img/'+cl+'.png" style="width:'+height+'px;height:'+height+'px;"></TD>';
			}
			html += '</TR>';
		}
		html += '</TABLE>';
	}
	return html;
};

Die.kDieWidth 		= 44;
Die.kDieWidth_Large	= 62;
Die.kPipHeight		= 7;
Die.kPipHeight_Large= 8;


//--- Begin Player --------------------------------------------------------------------------------------------------------------------------//
function Player( id, name, bOpponent, ml, avatarHTML, onlineStatus )
{
	this.mID = id;
	this.mDisplayName = name;
	this.mbOpponent = bOpponent;
	this.mML = ml;
	this.mAvatarHTML = avatarHTML;
	this.mOnlineStatus = onlineStatus;
}

//--- End Player --------------------------------------------------------------------------------------------------------------------------//


Input.kKey_ArrowLeft 	= 37;
Input.kKey_ArrowRight 	= 39;
Input.kKey_ArrowUp 		= 38;
Input.kKey_ArrowDown 	= 40;

Input.kKey_0			= 48;
Input.kKey_1			= 49;
Input.kKey_2			= 50;
Input.kKey_3			= 51;
Input.kKey_4			= 52;
Input.kKey_5			= 53;
Input.kKey_6			= 54;
Input.kKey_7			= 55;
Input.kKey_8			= 56;
Input.kKey_9			= 57;
function Input()
{
}
Input();
