//////////////////////
// Constants	    //
//////////////////////

var LENGTH = 9;
var SIZE = LENGTH * LENGTH;

var COLORS_CLASSIC = new Array("#000", // 0
			       "#b00", "#d80", "#00a",
			       "#5aa", "#000",
			       "#a0a", "#33f", "#990", "#f00"
		       );
var COLORS = COLORS_CLASSIC;

var RATINGS = new Array("easy", "medium", "hard", "devilish");

var UPDATE_TIME = 2000;

var RETRY_TIME = 7;
var K = 24; // Constant for the rating system used for scores

//////////////////////
// Global variables //
//////////////////////

var _retry = 0;

var _blurred = 0;
var _start = 0;
var _puzzleEmpty = null;
var _puzzleOpponent = null;
var _puzzle = null;
var _puzzleChanged = 0;

var _coloredNumbers = true;
var _multiNumbers = false;
var _stickyKeys = false;
var _stickyNumber = 0;

var _type; // Type of game single(0) multiplayer-with-friend(2) or multiplayer(1)
var _rating; // 0, 1, 2, 3 (easy, medium, hard, evil)

var _name = "Guest";
var _score = 0;
var _scoreOld = 0;
var _games = 0;
var _clientOpp = null;

var _currentCell = null;
function NullCurrentCell() {_currentCell = null;}
var _currentCellRO = 0;

// multiplayer data
var _friendlyGrid = 0;
var _sid = null;
var _player = null;
var _nameOpp = null;
var _scoreOpp = 0;
var _scoreOppOld = 0;
var _id = 0;
var _idOpp = 0;
var _playAgain = 0;
var _combatState = 0; // 0=not connected, 1=connected, 2=playing, 3=gameDone

/////////////////////
// Graphics	   //
/////////////////////

// Updates the opponent grid
function UpdateState(data, name, state) {
  if (_combatState != 2)
    return;
  var i;
  for (i = 0; i < data.length; i++) {
    if (data.charAt(i) == _puzzleOpponent.charAt(i))
      continue;
    var element = document.getElementById(name + i);
    if (data.charAt(i) == '0') {
      element.style.backgroundColor = "#fff";
      element.value = '';
    } else {
      if (state % 2 == 0)
	element.style.backgroundColor = "#999";
      else
	element.style.backgroundColor = "#000";
      if (data.charAt(i) != 'a')
	element.value = data.charAt(i);
      else
	element.value = 'X';
    }
  }
  if (state == 0)
    _puzzleOpponent = data;
  else {
    state--;
    setTimeout("UpdateState('"+data+"','"+name+"', "+state+")", 150);
  }
}

// Create the grid
function CreateTable(data, container, type) {
  var table;
  var sizeClass, sizeHeight;
  
  //type = 1;
  table = document.getElementById(container);
  if(type != 0) {
  	sizeClass = 'miniGameBoard';
 	sizeHeight = '16px'; 
  } else {
	sizeClass = 'gameBoard';
	sizeHeight = '33px';
  }
  var buffer = "<div id='"+sizeClass+"' align='center'><div style='clear:left; height: "+sizeHeight+";'>";
  var i;
  var elementName = "cell";
  if (type != 0)
    elementName += "Op";

  for (i = 0; i < data.length; i++) {
    // pick the number
    var current = data.charAt(i);
    if (current == 0)
      current = "";
    // Set cell style
    var cellClass = "cell";
    if (i % 27 < 9)
      cellClass += "top";
    else if (i % 27 > 17)
      cellClass += "bottom";
    if (i % 3 == 0)
      cellClass += "left";
    else if (i % 3 == 2)
      cellClass += "right";
    var inputClass = "inputempty";
    var readonly = "";
    if (current != "") {
      inputClass = "inputfixed";
      readonly = "readonly='readonly'";
    }
    if (type != 0)
      inputClass += "Op";
    // cell id
    var cellId = elementName+i;
    // print the html
    if (i % 9 == 0 && i != 0)
      buffer += "</div><div style='clear:left; height: "+sizeHeight+";'>";
    if (type == 0)
      buffer += "<div class='givenCell cell' onclick='selectCell(\""+cellId+"\")'><input class='"+inputClass+ "' id='"+cellId+"' onKeyDown='InputOnKeyDown(this)'  onmousedown='InputOnMouseDown(this)' value='"+current+"' size='2' autocomplete='off' "+readonly+"/></div>";
    else
      buffer += "<div class='miniCell'><input class='"+inputClass+"' id='"+cellId+"' size='1' value='"+current+"' readonly='readonly'/></div>";
  }
  buffer += "</div></div>";
  table.innerHTML = buffer;
  if (type == 0)
    SetCellsColor(data);
}

function selectCell(cellId) {

	document.getElementById(cellId).focus();	
}
function SetCellsColor(data) {
  for (var i = 0; i < data.length; i++) {
    if (data[i] == 0)
      continue;
    var element = document.getElementById("cell" + i);
    SetCellColor(element);
  }
}

function SetCellColor(element) {
  element.style.color = COLORS[0];
  if (element.value.length == 0)
    return 0;
  if (element.value.charAt(0) > 0 && element.value.charAt(0) < 10) {
    if (_coloredNumbers == "true" || _coloredNumbers == true)
	element.style.color = COLORS[element.value.charAt(0)];
    return 1;
  }
  return 0;
}


function UpdateRatings(result) {
  _scoreOld = _score;
  _scoreOppOld = _scoreOpp;
  var exMe = 1.0 / (1.0 + Math.pow(10.0,(_scoreOpp-_score)/400.0));
  var exOpp = 1.0 / (1.0 + Math.pow(10.0,(_score-_scoreOpp)/400.0));
  if (result == 0) { // I lose
    _score = _score + K * (-exMe);
    _scoreOpp = _scoreOpp + K * (1-exOpp);
    CreateCookie("sGames", ++_games, 365);
  } else if (result == 1) { // I win
    _score = _score + K * (1-exMe);
    _scoreOpp = _scoreOpp + K * (-exOpp);
    CreateCookie("sGames", ++_games, 365);
  } else if (result == 5) { // I leave
    _score = _score + K * (-exMe*1.6);
    CreateCookie("sGames", ++_games, 365);
  } else if (result == 2) { // he left
    _scoreOpp = _scoreOpp + K * (-exOpp*1.6);
  } else if (result == 3) { // he left, I am done
    _score = _score + K * (1-exMe);
    CreateCookie("sGames", ++_games, 365);
  } else if (result == 4) { // reset score
    _score = 0;
  }
  if (_score < 0)
    _score = 0;
  if (_scoreOpp < 0)
    _scoreOpp = 0;
  _scoreOpp = Math.round(_scoreOpp);
  _score = Math.round(_score);
  CreateCookie("sScore", Math.floor(_score), 365);
}

function SetTitle() {

  var loader = document.getElementById("loader");
  var oppGrid = document.getElementById("oppGrid");
  // print title
  if (_type == 0) {
	oppGrid.style.display = 'none';
    loader.innerHTML = "<img class='avaBor' height='70' width='70' src='/avatar.php?id="+_id+"'><BR/> <b>"+_name+" ("+_score+")</b>";
    return;
  }
  if (_nameOpp == null) {
    return;
  }
  var color1 = "#000000";
  if (_scoreOld < _score)
    color1 = "#00ff00";
  else if (_scoreOld > _score)
    color1 = "#ff0000";

  var color2 = "#000000";
  if (_scoreOppOld < _scoreOpp)
    color2 = "#00ff00";
  else if (_scoreOppOld > _scoreOpp)
    color2 = "#ff0000";
  
  var p1score = document.getElementById("p1Score");
  var p1name = document.getElementById("p1Name");
  var p1ava = document.getElementById("p1Ava");
  p1score.innerHTML = _scoreOld;
  p1name.innerHTML = _name;
  p1ava.innerHTML = "<img class='avaBor' height='70' width='70' src='/avatar.php?id="+_id+"'>";
  
  var p2score = document.getElementById("p2Score");
  var p2name = document.getElementById("p2Name");
  var p2ava = document.getElementById("p2Ava");
  p2score.innerHTML = _scoreOppOld;
  p2name.innerHTML = _nameOpp;
  if(_clientOpp == 'iPhoneWeb') {
	  p2ava.innerHTML = "<img class='avaBor' height='70' width='70' src='/img/iPhone.gif'>";
  } else {
  	p2ava.innerHTML = "<img class='avaBor' height='70' width='70' src='/avatar.php?id="+_idOpp+"'>";
  }
  var vs = document.getElementById("vs");
  vs.innerHTML = 'V';
  
  var gameHeader = document.getElementById("gameHeader");
  gameHeader.style.display = 'inline';
  loader.style.display = 'none';
  if (_score != _scoreOld ||
      _scoreOpp != _scoreOppOld) {
    _scoreOld = AnimScore(_score, _scoreOld);
    _scoreOppOld = AnimScore(_scoreOpp, _scoreOppOld);
    setTimeout("SetTitle();", 250);
  }
}
function AnimScore(s1, s2) {
  if (s1 == s2)
    return s1;
  var step = Math.ceil(Math.abs(s1 - s2)/6);
  step = step < 1 ? 1 : step;
  s2 += s1 > s2 ? step : -step;
  return s2;
}

function SetTimer(state) {
  if (state == null)
    return;
  var element = document.getElementById("timer");
  if (state == true || state == "true")
    element.style.display = "block";
  else
    element.style.display = "none";
}

//////////////////////
// Utilities	    //
//////////////////////

function Settings(element) {
  if (element == 0) {
    element = document.getElementById("gameOptionsParent");
    var chat = document.getElementById("chatParent");
	var optionsButt = document.getElementById("optionsButt")
	if (element.style.display == "none" || element.style.display == "") {
	  chat.style.display = 'none';
	  optionsButt.innerHTML = '&nbsp;&nbsp;&nbsp;Show Chat&nbsp;&nbsp;&nbsp;';
      element.style.display = "inline";
    } else {
	  chat.style.display = 'inline';
	  optionsButt.innerHTML = 'Show Options';
      element.style.display = "none";
      SetTitle();
    }
    return;
  }
  if (element.id == "sTimer")
    SetTimer(element.checked);
  else if (element.id == "sSticky") {
    _stickyKeys = element.checked;
  } else if (element.id == "sMulti") {
    _multiNumbers = element.checked;
  }  else if (element.id == "sColors") {
    _coloredNumbers = element.checked;
    SetCellsColor(_puzzle);
  } else if (element.id == "sName") {
    _name = element.value;
    CreateCookie(element.id, element.value, 365);
    return;
  } else if (element.id == "sScore") {
    var res = confirm("Do you really want to reset your score?");
    if (res == false)
      return;
    UpdateRatings(4);
    SetTitle();
    return;
  }
  CreateCookie(element.id, element.checked, 365);
}

function FriendlyGrid() {
  // update the data and tell the users
  if (_friendlyGrid == 0) {
    _friendlyGrid = 1;
    AddMessage("Your grid is now visible to your opponent. Click again to hide it.", "info");
  } else {
    _friendlyGrid = 0;
    AddMessage("Your grid is now hidden", "info");
  }
  _puzzleChanged = 1;
}

function Wipe() {
  var res = confirm("Do you really want to clear the grid?");
  if (res == false)
    return;
  _currentCell = null;
  CreateTable(_puzzleEmpty, "gameGridHolder", 0);
}

function Done() {
  if (!Check(_puzzle))
    return;

  // check and save the time
  var val = ReadCookie("sBestTime"+_rating);
  if (val == null || val == "" || val < 0) {
    val = 100000;
  }
  var msgTime = "";
  if (UpdateTimer() < val) {
    val = UpdateTimer();
    CreateCookie("sBestTime"+_rating, val, 365);
    msgTime = "New best time!<br/>";
  }
  msgTime += "Your fastest time is "+(val/60)+" minute(s) "+(val%60)+" seconde(s)<br/>";

  // Two players mode
  if (_type != 0) {
    if (_start == 0)
      return;
    HTTPComm('/communication.php?sid='+_sid+'&player='+_player, UpdateGame, "done=1&grid="+data+"&time="+val);

    // One player mode
  } else {
    // stop the timer
    _start = 0;
    //info.innerHTML = "You made it!<br/><br/>"+msgTime;
   // info.innerHTML += "<button onMouseUp='window.location.reload()'>Play again</button><br/>";
  }
}

// Start another game with the same player ("play again")
function Again() {
  if (_start != 0)
    return;
  HTTPComm('/communication.php?sid='+_sid+'&player='+_player, UpdateGame, "grid=again");
  if (_playAgain == 0)
  AddMessage("The game will start when "+_nameOpp+" accepts your request", "info");
}

function Check(data) {
	var alerted = 0;
  // read the grid (again)
  for (var i = 0; i < data.length; i++) {
    var element = document.getElementById("cell" + i);
    if (element.value.length != 1) {
		if(alerted == 0) {
		  alerted = 1;
      alert("Each cell can and must only have one number in it!");
		}
    }
    if (element.value.charAt(0) > 0 && element.value.charAt(0) < 10)
      data[i] = element.value.charAt(0);
  }

  // check if there are empty cells
  var i, j;
  var c = 0;
  for (i = 0; i < data.length; i++)
    if (data[i] == 0)
      c++;
  if (c > 0) {
	  if(alerted == 0) {
		  alerted = 1;
		  alert("Sorry, you still have "+c+" empty cell(s)");
	  }
    return 0;
  }
  // Check if there are bad cells
  var sumH, sumV, sumS;
  for (i = 0; i < LENGTH; i++) {
    sumH = 0;
    sumV = 0;
    sumS = 0;
    for (j = 0; j < LENGTH; j++) {
      sumH += Number(data[i*LENGTH + j]);
      sumV += Number(data[j*LENGTH + i]);
      index = i * Math.floor(LENGTH/3) + Math.floor(i/3) * 2 * LENGTH +	j % 3 + Math.floor(j/3) * LENGTH;
      sumS += Number(data[index]);
    }
    if (sumH != 45 || sumV != 45 || sumS != 45) {
		if(alerted == 0) {
		  alerted = 1;
      alert("Sorry, one or more cells are incorrect");
		}
      return 0;
    }
  }
  return 1;
}

///////////////////
// Chat 	 //
// System	 //
///////////////////

function SendMessage() {
  var element = document.getElementById("chatInput");
  message = element.value;
  if (message == "")
    return;
  element.value = "";
  AddMessage(message, "me");

  // send the message
  HTTPComm('/communication.php?sid='+_sid+'&player='+_player, null, "msg="+message);
}

function AddMessage(message, type) {
  // display the message
  var area = document.getElementById("chatArea");
  var textbox = document.getElementById("chatInput");
  date = new Date();
  minutes = date.getMinutes();
  zero = "";
  if (minutes < 10)
    zero = "0";
  name = _nameOpp;
  textbox.style.backgroundColor ="#ffbbbb";
  if (type == "me") {
    name = _name;
    textbox.style.backgroundColor ="#ffffff";
  } else if (type == "info") {
    name = "System";
  }
  var clr;
  if(type == 'me') {
	  clr = "#666666; display: inline;";
  } else {
	  clr = "#333333; display: inline;";
  }
  area.contentWindow.document.body.innerHTML += "<div style='color:"+clr+"'>["+date.getHours()+":"+zero+minutes+"] <b>"+name+"</b>:</div> "+message+"<br/>";
	   
  area.contentWindow.scrollTo(0, 100000);
}

///////////////////
// Events	 //
///////////////////

function CommitInputOnDown(mouse) {
  var element = document.getElementById("cell" + _currentCell);
  if (element.value.len != "")
    _puzzle[_currentCell] = 0;
  if (mouse &&_currentCellRO == 0 && (_stickyKeys == true || _stickyKeys == "true") && _stickyNumber != 0) {
    if (_multiNumbers)
      element.value += _stickyNumber;
    else
      element.value = _stickyNumber;
  }
  if (_multiNumbers) {
    if (element.value.length > 1)
      element.style.fontSize = "12px";
    else
      element.style.fontSize = "20px";
  }
  _puzzleChanged = 1;
  if (!SetCellColor(element))
    return;
  _puzzle[_currentCell] = element.value.charAt(0);
  if (element.value.length > 1)
    _puzzle[_currentCell] = 0;
  if (!mouse)
    _stickyNumber = element.value.charAt(element.value.length-1);
}

// OnKeyDown is called before this
function InputOnDown(input, mouse) {
  // unselect the last cell
  if (_currentCell != null && mouse) {
    var element = document.getElementById("cell"+_currentCell);
    element.focus();
    element.style.textDecoration = "none";
  }
  _currentCell = input.id;
  _currentCell = Number(_currentCell.substr(4));
  _currentCellRO = 0;
  setTimeout("CommitInputOnDown("+mouse+")", 30);
  if (!mouse)
    return;
  input.style.textDecoration = "underline";
}
function InputOnKeyDown(input) {
  InputOnDown(input, 0);
}
function InputOnMouseDown(input) {
  InputOnDown(input, 1);
}

function OnKeyDown(input) {
  if (!input)
    input = window.event;
  var key = Number(input.keyCode);
  if (key == 13)
    SendMessage();
  // Some init
  if (_multiNumbers)
    return;
  if (_currentCell == null)
    return;
  var element = document.getElementById("cell"+_currentCell);
  element.style.textDecoration = "none";

  // Manage arrows
  switch (key) {
    case 37:
      if (_currentCell % 9 == 0)
	_currentCell = _currentCell + LENGTH - 1;
      else
	_currentCell--;
      break;
    case 39:
      if (_currentCell % 9 == 8)
	_currentCell = _currentCell - LENGTH + 1;
      else
	_currentCell++;
      break;
    case 38:
      _currentCell -= 9;
      if (_currentCell < 0)
	_currentCell = SIZE + _currentCell;
      break;
    case 40:
      _currentCell = _currentCell + 9;
      if (_currentCell >= SIZE)
	_currentCell -= SIZE;
      break;
  }

  element = document.getElementById("cell"+_currentCell);
  element.style.textDecoration = "underline";
  element.select();

  // Clean up..
  if (input.stopPropagation)
    input.stopPropagation();
  if (window.event)
    window.event.cancelBubble = true;
}

function GameCommunication() {
  if (_combatState == 0)
    return;
  data = null;
  if (_combatState == 2 && _puzzleChanged == 1) {
    _puzzleChanged = 0;
    data = "grid=";
    for (i = 0; i < _puzzle.length; i++) {
      if (_puzzle[i] != _puzzleEmpty.charAt(i)) {
	if (!_friendlyGrid)
	  data += "a";
	else
	  data += _puzzle[i];
      } else
	data += _puzzleEmpty.charAt(i);
    }
  }
  if (_retry <= 0) {
    _retry = RETRY_TIME;
    HTTPComm('/communication.php?sid='+_sid+'&player='+_player, UpdateGame, data);
  }
  setTimeout("GameCommunication()", UPDATE_TIME);
  _retry--;
}

function UpdateTimer() {
  if (_start == 0)
    return;
  // Update the timer
  var timer;
  timer = document.getElementById("timer");
  var timeDiff = new Date();
  timeDiff = (timeDiff - _start) / 1000;
  var zero = "";
  if (timeDiff % 60 < 10)
    zero = "0";
  timer.innerHTML = Math.floor((timeDiff / 60))+":"+zero+Math.floor((timeDiff % 60));
  setTimeout("UpdateTimer()", 1000);
  return timeDiff;
}


//////////////////
// Destroy      //
//////////////////

function ConfirmExit() {
  if (_combatState == 2)
    return "\n\nYou are about to leave a game! If you leave you may lose points.\nAre you sure? \n\n";
  return;
}

function Destroy() {
  if (_type == 0)
    return;
  if (_combatState == 2)
    UpdateRatings(5);
  HTTPComm('/communication.php?sid='+_sid+"&player=destroy&state="+_combatState, null, null);
}

//////////////////
// Init         //
//////////////////

function Blurred() {
  _blurred = 1;
}
function Focus() {
  _blurred = 0;
}
function Init() {
	
  var params = RequestObject();
  LoadSettings();
  _type = params["type"];
  _rating = params["rating"];
  
  document.onkeydown = OnKeyDown;
  if (_type != 0)
    window.onbeforeunload = ConfirmExit;
  SetTitle();

  // one player game
  if (_type == 0) {
    HTTPComm('/generator.php?rating='+params["rating"], StartTheGame, null);

  // if it's a multiplayer game,
  } else {
    var id = "";
    // play with a friend
    if (_type == 2) {
      id = params["id"];
      if (id == undefined)
	id = 1;
      id = "&privateGame="+id;
    }
    HTTPComm('/register.php?rating='+params["rating"]+"&score="+_score+"&gameid="+params["gameid"]
	     , Registration, "lost=0&won=0"+id+"&name="+_name);
  }
  
}

function LoadSettings() {
  // colors
  var element = document.getElementById("sColors");
  var val = ReadCookie("sColors");
  if (val != null && element != undefined) {
    _coloredNumbers = val;
    if (val == "false")
      val = "";
    element.checked = val;
  }
  // sticky keys
  var element = document.getElementById("sSticky");
  var val = ReadCookie("sSticky");
  if (val != null && element != undefined) {
    _stickyKeys = val;
    if (val == "false")
      val = "";
    element.checked = val;
  }
  // multiple numbers
  var element = document.getElementById("sMulti");
  var val = ReadCookie("sMulti");
  if (val != null && element != undefined) {
    _multiNumbers = val;
    if (val == "false") {
      val = "";
      _multiNumbers = false;
    }
    element.checked = val;
  }
  // timer
  var element = document.getElementById("sTimer");
  var val = ReadCookie("sTimer");
  if (val != null && element != undefined) {
    SetTimer(val);
    if (val == "false")
      val = "";
    element.checked = val;
  }
  // name
  var element = document.getElementById("sName");
  var val = ReadCookie("sName");
  if (val != null && element != undefined) {
    _name = val;
    element.value = val;
  }

  // Deprecated
  var val = ReadCookie("sGameWon");
  var won = 0;
  if (val != null) {
    won = val;
  }
  var val = ReadCookie("sGameLost");
  var lost = 0;
  if (val != null) {
    lost = val;
  }
  if (won * lost != 0) {
    _score = GetScore(won, lost);
    _games = Number(won)+Number(lost);
  }

  // score
  var val = ReadCookie("sScore");
  if (val != null) {
    _score = Number(val);
  }

  // number of games
  var val = ReadCookie("sGames");
  if (val != null) {
    _games = val;
  }

}

///////////////////////////////////
// Functions triggered by 	 //
// xmlrequest			 //
///////////////////////////////////

var staticCounter = " *";
function UpdateGame(data) {
  _retry = 0;

  if (data == 0) {
    return;
  }
  staticCounter += " *";
  if (staticCounter.length > 6)
    staticCounter = "";
  var waiter, gameMsg, gameMsgContainer;
  var Msg = null;
  var temp = "";
  gameMsgContainer = document.getElementById("gameMsgContainer");
  gameMsg = document.getElementById("gameMsg");
  waiter = document.getElementById("waiter");
  //alert(data);
  eval(data);

  // Waiting for the other player
  if (State == 1) {
    if (_combatState > 1)
      _combatState = 0;
    else {
	  waiter.innerHTML = staticCounter+" Waiting for opponent"+staticCounter;
	}
    // Opponent found!
  } else if (State == 2) {
    _puzzleEmpty = Grid;
    _playAgain = 0;
	
    if (_nameOpp == null) {
      _nameOpp = Name;
      _scoreOpp = Score;
	  _clientOpp = Avatar;
      _idOpp = Id;
      SetTitle();
    }

    // Synchronization
  } else if (State == 3) {
    waiter.innerHTML = staticCounter+" Linking with server"+staticCounter;

    // The communication is established
  } else if (State == 4) {
    // read the messages and display
    if (Msg != null) {
      AddMessage(Msg, "opp");
      Msg = null;
    }
    // Manage the game states
    if (Grid == "lost" || Grid == "won") {
      _start = 0;
      if (Score != _score || ScoreOpp != _scoreOpp) {
	_score = Score;
	_scoreOpp = ScoreOpp;
	_clientOpp = Avatar;
	SetTitle();
	CreateCookie("sScore", Math.floor(_score), 365);
	CreateCookie("sGames", ++_games, 365);
      }
      if (_playAgain != More) {
	_playAgain = More;
	AddMessage(_nameOpp+" wants to play again. Press '<b>Play again</b>' to start a new game", "info");
      }
      _combatState = 3;
    }
    if (Grid == "lost") {
		gameMsg.innerHTML = "You lost! <br> <button onMouseUp='Again()'>Play again</button><button onMouseUp='window.location=\"index.php\"'>Play with someone else</button>";
    	gameMsgContainer.style.display = 'inline';
    } else if (Grid == "won") {
		gameMsg.innerHTML = "Victory! <br> <button onMouseUp='Again()'>Play again</button><button onMouseUp='window.location=\"index.php\"'>Play with someone else</button>";
    	gameMsgContainer.style.display = 'inline';
    } else if (_start == 0) {
      StartTheGame(_puzzleEmpty);
    } else if (Grid.length > 1) {
      UpdateState(Grid, "cellOp", 4);
    }
  } else if (State == 5) {
    _combatState = 0;
    // The other player left!
  } else if (State == 6) {
    _combatState = 0;
    _score = Score;
    _scoreOpp = ScoreOpp;
	_clientOpp = Avatar;
    CreateCookie("sScore", Math.floor(_score), 365);
    CreateCookie("sGames", ++_games, 365);
    if (Do == 2) {
      _start = 0;
      temp = "You made it!";
    }
  }
  if (_combatState == 0) {
    if (temp == "")
      alert(_nameOpp+" left the game");
    if (_start != 0)
      temp = "You can still increase your score if you solve the sudoku!";
    gameMsg.innerHTML = "<font color='red'>"+_nameOpp+" left the game.</font> "+temp+"<br><a href='index.php'>Start a new game</a>";
    gameMsgContainer.style.display = 'inline';
	SetTitle();
  }
}

// Register the	game
function Registration(data) {
  eval(data);
  _combatState = 1;
  _sid = Sid;
  _player = Player;
  _id = Id;
  if (GameId != 0) {
    var e = document.getElementById("gameGridHolder");
    // show the form
    var url = "http:"+"/"+"/www.sudokushootout.com/game.php?type=2&id="+GameId+"&rating="+_rating;
    e.innerHTML = "To play a friend you will need to send them the below link:<p> <b>"+url+"</b><br/><br/>Alertnativly you can fillin the form below and it will be emailed to them.<br/><br/>Email this link to: <input class='formInput' type='text' id='email' value='email' /><br/>Message: <em>(optional)</em> <input class='formInput' type='text' id='message' value='' size='30'/><button onMouseUp='SendInvite(\""+url+"\")'>Send</button></p><br/>";
  }
  GameCommunication();
}

function SendInvite(url) {
  var email = document.getElementById("email");
  var message = document.getElementById("message");
  var filter = /^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]*)\.([a-z]+(?:\.[a-z]+)?)$/i;
  if (!filter.test(email.value)) {
    alert("It appears that the email you have entered is invalid.\nPlease try again.");
    return;
  }
  // send the data
  url = url.replace(/&/g, "_I_");
  HTTPComm('/sendinvite.php', SendInviteCompleted, "url="+url+"&email="+email.value+"&message="+message.value+"&name="+_name);
}
function SendInviteCompleted() {
  alert("Invitation sent");
}

////////////////////
// Start the game //
////////////////////

function StartTheGame(data) {
  // Display
  var e = document.getElementById("clearButt");
  e.style.display = "inline";
  e = document.getElementById("doneButt");
  e.style.display = "inline";
  if (_type != 0) {
    e = document.getElementById("shareButt");
    e.style.display = "inline";
  }
  _puzzleEmpty = data;
  // init the player data
  _puzzle = new Array();
  for (i = 0; i < _puzzleEmpty.length; i++)
    _puzzle.push(_puzzleEmpty.charAt(i));
  // Create the grids
  if (_type != 0) {
    CreateTable(_puzzleEmpty, "tableOpponent", 1);
    _puzzleOpponent = _puzzleEmpty;
    UpdateState(data, "cellOp", 0);
    e = document.getElementById("chat");
    e.style.display = "inline";
  }

  // Start the game
  AddMessage("This grid is rated as <strong>"+RATINGS[_rating]+"</strong>.", "info");
  _start = new Date();
  var c = 5;
  if (_type == 0)
    c = 0;
  StartCountdown(c);
  if (_blurred == 1)
    alert("The game is about to start!");
}

// Countdown before the game starts
function StartCountdown(state) {
  var table = document.getElementById("gameGridHolder");
  table.innerHTML = "<br/><br/><br/><br/><br/><br/><h1>Game starts in "+state+" seconds...</h1><br/><br/><br/>";
  if (_type > 0)
    table.innerHTML += "The first person to correctly complete the grid will win<br/><br/>Keep your eye on your opponents grid at the top right.<br/><br/><br/><br/><br/><br/><br/><br/>";
  if (state == 0) {
    if (_combatState != 0)
      _combatState = 2;
    _start = new Date();
    UpdateTimer();
    CreateTable(_puzzleEmpty, "gameGridHolder", 0);
    return;
  }
  state--;
  setTimeout("StartCountdown("+state+")", 1000);
}