
var requestTreeNumber = null;
var requestNodeID = null;

var treePrefixes = null;
var selectedTreeNodes = null;
var idCounters = null;

/**
 * Initializes the tree with the specified treeNumber.
 **/ 
function NicKeyTree_SetRootNode(treeNumber, nicKey, containerID)
{
	this.idCounters[treeNumber] = 0;
	this.selectedTreeNodes[treeNumber] = null;

	var container = this.GetElementByID(containerID);	
	container.innerHTML = "<div id=\"" + this.treePrefixes[treeNumber] + "Loading\" style=\"display: none\">"
		+ "<img height=\"11\" class=\"treeLoadingIcon\" src=\"Images/Controls/NicKeyTree/Loading.gif\" width=\"11\" />"
		+ "Loading..."
		+ "</div>";
	container.innerHTML += "<div id=\"" + this.treePrefixes[treeNumber] + "TreeNodes\"></div>";
	container.innerHTML += "<div id=\"" + this.treePrefixes[treeNumber] + "Info\"></div>";
	
	var treeNodes = this.GetElementByID(this.treePrefixes[treeNumber] + "TreeNodes");
	treeNodes.innerHTML = this.NicKeyTreeNode_Draw(treeNumber, nicKey);
}

/**
 * Returns an unique identifier for a tree node.
 **/
function NicKeyTree_GetUniqueID(treeNumber)
{
	return this.treePrefixes[treeNumber] + this.idCounters[treeNumber]++;
}

/**
 * Returns the icon of the node with the specified nodeID.
 **/
function NicKeyTree_GetIcon(nodeID)
{
	return this.GetElementByID(nodeID + "Icon");
}

/**
 * Returns the text link of the node with the specified nodeID.
 **/
function NicKeyTree_GetLink(nodeID)
{
	return this.GetElementByID(nodeID + "Link");
}

/**
 * Returns the container for the children of the node with the specified nodeID.
 **/
function NicKeyTree_GetContainer(nodeID)
{
	return this.GetElementByID(nodeID + "Container");
}

/**
 * Creates a container for the children of the node with the specified nodeID
 * and returns it.
 **/
function NicKeyTree_CreateContainer(nodeID)
{
	var node = this.GetElementByID(nodeID);
	node.innerHTML += "<div id=\"" + nodeID + "Container\" class=\"treeNodeContainer\" style=\"display: none\"></div>";
	
	return this.NicKeyTree_GetContainer(nodeID);
}

/**
 * Fires a command to the board to retrieve the child keys of a NICKey.
 **/
function NicKeyTree_GetNicKeyChildren(treeNumber, nodeID, nicKeyCode)
{
	this.NicKeyTree_SetLoadingVisibility(treeNumber, true);

	this.requestTreeNumber = treeNumber;
	this.requestNodeID = nodeID;

	this.Board_SetCommandParameter("NicKeyCode", nicKeyCode);
	this.Board_ExecuteCommand("GetNicKeyChildren");
}

/**
 * Fires a command to the board to retrieve the child moves of a NICKey or move.
 **/
function NicKeyTree_GetMoveChildren(treeNumber, nodeID, nicKeyCode, parentMoves)
{
	this.NicKeyTree_SetLoadingVisibility(treeNumber, true);

	this.requestTreeNumber = treeNumber;
	this.requestNodeID = nodeID;

	this.Board_SetCommandParameter("NicKeyCode", nicKeyCode);
	this.Board_SetCommandParameter("ParentMoves", parentMoves);
	this.Board_ExecuteCommand("GetMoveChildren");
}

/**
 * Sets the selected tree node.
 **/
function NicKeyTree_SetSelectedNode(treeNumber, nodeID)
{
	if (this.selectedTreeNodes[treeNumber] != null)
	{
		this.NicKeyTree_GetLink(this.selectedTreeNodes[treeNumber]).className = "";
	}
	
	this.NicKeyTree_GetLink(nodeID).className = "treeNodeSelected";
	this.selectedTreeNodes[treeNumber] = nodeID;
}

/**
 * Sets the visibility of the loading message on or off.
 **/
function NicKeyTree_SetLoadingVisibility(treeNumber, visible)
{
	var loading = this.GetElementByID(this.treePrefixes[treeNumber] + "Loading");
	loading.style.display = visible ? "" : "none";
}

/**
 * Toggles the visibility of the node container that belongs to node with the
 * specified nodeID.
 **/
function NicKeyTree_ToggleContainerVisibility(nodeID)
{
	var container = this.NicKeyTree_GetContainer(nodeID);	
	var icon = this.NicKeyTree_GetIcon(nodeID);	

	if (container.style.display == "")
	{
		container.style.display = "none";
		icon.src = icon.src.substring(0, icon.src.length - 12) + "Collapsed.gif";
	}
	else
	{
		container.style.display = "";
		icon.src = icon.src.substring(0, icon.src.length - 13) + "Expanded.gif";
	}
}

/**
 * Updates the score information in the info panel.
 **/
function NicKeyTree_UpdateInfo(treeNumber, nrGames, nrWhiteWins, nrBlackWins, nrDraws, score)
{
	var info = this.GetElementByID(this.treePrefixes[treeNumber] + "Info");
	
	if (nrGames == 0)
	{
		info.innerHTML = "";
	}
	else
	{
		info.innerHTML = "<table width=\"100%\">"
			+ "<tr>"
			+ "<td width=\"40%\">" + nrGames + " game(s):</td>"
			+ "<td width=\"60%\">" + nrWhiteWins + " white win(s)</td>"
			+ "</tr>"
			+ "<tr>"
			+ "<td>&nbsp;</td>"
			+ "<td>" + nrBlackWins + " black win(s)</td>"
			+ "</tr>"
			+ "<tr>"
			+ "<td>&nbsp;</td>"
			+ "<td>" + nrDraws + " draw(s)</td>"
			+ "</tr>"
			+ "<tr>"
			+ "<td>White score:</td>"
			+ "<td>" + score + "</td>"
			+ "</tr>"
			+ "</table>";
	}
}
		
/**
 * Called when the tree script is loaded for the first time.
 **/		
function NicKeyTree_Load(treePrefixes)
{
	this.treePrefixes = treePrefixes;
	this.selectedTreeNodes = new Array(treePrefixes.length);
	this.idCounters = new Array(treePrefixes.length);
}

/**
 * Called when there are NICKeys available to be added to the tree.
 **/
function NicKeyTree_NicKeysAvailable(data)
{
	this.NicKeyTree_SetLoadingVisibility(this.requestTreeNumber, false);

	var nicKeys = data.split("|*");
	
	var output = "";
	
	for (var i = 0; i < nicKeys.length; i++)
	{
		var nicKey = nicKeys[i].split('|');

		output += this.NicKeyTreeNode_Draw(this.requestTreeNumber, nicKey);
	}
	
	var container = this.NicKeyTree_CreateContainer(this.requestNodeID);
	container.innerHTML = output;
	
	this.NicKeyTree_ToggleContainerVisibility(this.requestNodeID);
}

/**
 * Called when there are moves available to be added to the tree.
 **/
function NicKeyTree_MovesAvailable(data)
{
	//alert(data);
	this.NicKeyTree_SetLoadingVisibility(this.requestTreeNumber, false);

	var moves = data.split('|*');
	
	var output = "";
	
	for (var i = 2; i < moves.length; i++)
	{
		var move = moves[i].split('|');

		output += this.MoveTreeNode_Draw(this.requestTreeNumber, move, moves[0], moves[1]);
	}
	
	var container = this.NicKeyTree_CreateContainer(this.requestNodeID);
	container.innerHTML = output;
	
	this.NicKeyTree_ToggleContainerVisibility(this.requestNodeID);
}

/**
 * Called when a NICKey node needs to be drawn.
 **/
function NicKeyTreeNode_Draw(treeNumber, nicKey)
{
	var output = "";	
	
	var id = this.NicKeyTree_GetUniqueID(treeNumber);

	var hasChildren = (nicKey[NIC_KEY_HAS_CHILDREN] != 0);
	var expandable = hasChildren || (nicKey[NIC_KEY_NR_GAMES] > 0);
	var iconFileName = expandable ? "Collapsed.gif" : "Leaf.gif";
	
	output += "<div id=\"" + id + "\" class=\"treeNode\">";
	
	if (expandable)
	{
		output += "<a href=\"javascript:NicKeyTreeNode_IconClick("
			+ "'" + treeNumber + "'"
			+ ", '" + id + "'"
			+ ", '" + nicKey[NIC_KEY_CODE] + "'"
			+ ", " + hasChildren
			+ ")\">"
	}
	
	output += "<img id=\"" + id + "Icon\" class=\"treeNodeIcon\" height=\"14\" src=\"Images/Controls/NicKeyTree/" + iconFileName + "\" width=\"15\" />";

	if (expandable)
	{
		output += "</a>";
	}
	
	output += "<a id=\"" + id + "Link\" href=\"javascript:NicKeyTreeNode_TextClick("
		+ "'" + treeNumber + "'"
		+ ", '" + id + "'"
		+ ", " + (!hasChildren && expandable)
		+ ", '" + nicKey[NIC_KEY_CODE] + "'"
		+ ", '" + nicKey[NIC_KEY_FEN_POSITION] + "'"
		+ ", '" + nicKey[NIC_KEY_NR_GAMES] + "'"
		+ ", '" + nicKey[NIC_KEY_NR_WHITE_WINS] + "'"
		+ ", '" + nicKey[NIC_KEY_NR_BLACK_WINS] + "'"
		+ ", '" + nicKey[NIC_KEY_NR_DRAWS] + "'"
		+ ", '" + nicKey[NIC_KEY_SCORE] + "'"
		+ ")\">"
		+ nicKey[NIC_KEY_CODE]
		+ " - "
		+ Figures_Replace(nicKey[NIC_KEY_DESCRIPTION], true)
		+ "</a>";

	output += "</div>";

	return output;
}

/**
 * Called when a move node needs to be drawn.
 **/
function MoveTreeNode_Draw(treeNumber, move, nicKeyCode, parentMoves)
{
	var output = "";	
	
	var newParentMoves = (parentMoves == "") ? "" : parentMoves + ", ";
	var newMoves = move[MOVE_TEXT].split('%');
	var repMoves = "";
	for(i=0;i<newMoves.length;i++)
	{
		newParentMoves += newMoves[i].substring(newMoves[i].lastIndexOf('.')+1);
		if((i+1) < newMoves.length) newParentMoves += ", ";
		repMoves += " " + newMoves[i];
	}	
	move[MOVE_TEXT] = repMoves;
	
	var id = this.NicKeyTree_GetUniqueID(treeNumber);

	var expandable = (move[MOVE_HAS_CHILDREN] != 0);
	var iconFileName = expandable ? "Collapsed.gif" : "Leaf.gif";
	
	output += "<div id=\"" + id + "\" class=\"treeNode\">";

	if (expandable)
	{	
		output += "<a href=\"javascript:MoveTreeNode_IconClick("
			+ "'" + treeNumber + "'"
			+ ", '" + id + "'"
			+ ", '" + nicKeyCode + "'"
			+ ", '" + newParentMoves + "'"
			+ ")\">";
	}
	
	output += "<img id=\"" + id + "Icon\" height=\"14\" src=\"Images/Controls/NicKeyTree/" + iconFileName + "\" class=\"treeNodeIcon\" width=\"15\" />";
	
	if (expandable)
	{
		output += "</a>";
	}

	output += "<a id=\"" + id + "Link\" href=\"javascript:MoveTreeNode_TextClick("
		+ "'" + treeNumber + "'"
		+ ", '" + id + "'"
		+ ", '" + nicKeyCode + "'"
		+ ", '" + newParentMoves + "'"
		+ ", '" + move[MOVE_FEN_POSITION] + "'"
		+ ", '" + move[MOVE_NR_GAMES] + "'"
		+ ", '" + move[MOVE_NR_WHITE_WINS] + "'"
		+ ", '" + move[MOVE_NR_BLACK_WINS] + "'"
		+ ", '" + move[MOVE_NR_DRAWS] + "'"
		+ ", '" + move[MOVE_SCORE] + "'"		
		+ ")\">"
		+ Figures_Replace(move[MOVE_TEXT], false)
		+ "</a>";

	output += "</div>";
	
	return output;
}

/**
 * Called when the icon of a NICKey node is clicked.
 * Gets the children if it's the first time the node is clicked, otherwise
 * toggles the visibility of the children.
 **/
function NicKeyTreeNode_IconClick(treeNumber, nodeID, nicKeyCode, hasChildren)
{
	this.NicKeyTree_SetLoadingVisibility(treeNumber, false);

	var container = this.NicKeyTree_GetContainer(nodeID);
	
	if (container == null)
	{
		if (hasChildren)
		{
			this.NicKeyTree_GetNicKeyChildren(treeNumber, nodeID, nicKeyCode);
		}
		else
		{
			this.NicKeyTree_GetMoveChildren(treeNumber, nodeID, nicKeyCode, "");
		}
	}
	else
	{
		this.NicKeyTree_ToggleContainerVisibility(nodeID);
	}
}

/**
 * Called when the icon of a move node is clicked.
 * Gets the children if it's the first time the node is clicked, otherwise
 * toggles the visibility of the children.
 **/
function MoveTreeNode_IconClick(treeNumber, nodeID, nicKeyCode, parentMoves)
{
	this.NicKeyTree_SetLoadingVisibility(treeNumber, false);

	var container = this.NicKeyTree_GetContainer(nodeID);
	
	if (container == null)
	{
		this.NicKeyTree_GetMoveChildren(treeNumber, nodeID, nicKeyCode, parentMoves);
	}
	else
	{
		this.NicKeyTree_ToggleContainerVisibility(nodeID);
	}
}

/**
 * Called when the text of a NICKey node is clicked.
 * Fires an event to the board to show a position, or fires an event
 * to the board to show a position and search for games if the node has
 * no children but does have games.
 * Also fills the information panel.
 **/
function NicKeyTreeNode_TextClick(treeNumber, nodeID, searchGames, nicKeyCode,
	fenPosition, nrGames, nrWhiteWins, nrBlackWins, nrDraws, score)
{
	this.NicKeyTree_SetSelectedNode(treeNumber, nodeID);
	this.NicKeyTree_SetLoadingVisibility(treeNumber, false);
	this.NicKeyTree_UpdateInfo(treeNumber, nrGames, nrWhiteWins, nrBlackWins, nrDraws, score);

	if (searchGames)
	{
		this.Board_SetCommandParameter("FenPosition", fenPosition);
		this.Board_SetCommandParameter("NicKeyCode", nicKeyCode);
		this.Board_SetCommandParameter("ParentMoves", "");
		this.Board_ExecuteCommand("GetGames");
	}
	else
	{
		this.Board_SetCommandParameter("FenPosition", fenPosition);
		this.Board_ExecuteCommand("ViewPosition");
		
		this.GameList_Clear();
	}
}

/**
 * Called when the text of a move node is clicked.
 * Fires an event to the board to the board to show a position and
 * search for games if the node has children.
 * Also fills the information panel.
 **/
function MoveTreeNode_TextClick(treeNumber, nodeID, nicKeyCode, parentMoves,
	fenPosition, nrGames, nrWhiteWins, nrBlackWins, nrDraws, score)
{
	//alert(parentMoves + " " + nicKeyCode);
	this.NicKeyTree_SetSelectedNode(treeNumber, nodeID);
	this.NicKeyTree_SetLoadingVisibility(treeNumber, false);
	this.NicKeyTree_UpdateInfo(treeNumber, nrGames, nrWhiteWins, nrBlackWins, nrDraws, score);

	this.Board_SetCommandParameter("FenPosition", fenPosition);
	this.Board_SetCommandParameter("NicKeyCode", nicKeyCode);
	this.Board_SetCommandParameter("ParentMoves", parentMoves);
	this.Board_ExecuteCommand("GetGames");
}
