/*Copyright 2008 Jack Wellborn.*/

/*------------------------------------------------------------------------------
########################### menuParser.js ReadMe ###############################

Created By: Jack Wellborn
On: 2008-12-08
Version 1.0

Modified By: Jack Wellborn
On: 2008-12-08
Changes: Created external.js file and added comments.

This code is designed to parse a the data found in menu.xml. There are two basic
functions that should be used externally: getAllItems() and getItemsByTagData().
See below for details.
------------------------------------------------------------------------------*/
var http_request = false;
var num_dataAttemptCount = 0;
var xmlDoc = null;
var itemCount = 0;
var bool_dataIsReady = false;
var arr_displayedItems = new Array();

makeRequest("data/menu.xml");
function makeRequest(url) {
  if (window.XMLHttpRequest) { // Mozilla, Safari, IE7...
      http_request = new XMLHttpRequest();
  } else if (window.ActiveXObject) { // IE6 and older
      http_request = new ActiveXObject("Microsoft.XMLHTTP");
  }
  http_request.onreadystatechange = getXml;
  http_request.open('GET', url, true);
  http_request.send(null);

}

function getXml() {
  if (http_request.readyState == 4) {
      if (http_request.status == 200) { 
          //alert(http_request.responseText);
		  parseXml(http_request.responseText);
      } else {
          alert('There was a problem with the request.');
      }
  }
}
function parseXml(xmlRequest){
	try //Internet Explorer
	  {
	  xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
	  xmlDoc.async="false";
	  xmlDoc.loadXML(xmlRequest);
	  }  
	catch(e)
	  {
	  try // Firefox, Mozilla, Opera, etc.
	    {
	    parser=new DOMParser();
	    xmlDoc = parser.parseFromString(xmlRequest,"text/xml");
	    }
	  catch(e)
	    {
	    alert("ERROR:" + e.message);
	    return;
	    }
	}
	 bool_dataIsReady = true;
}
/*############################################# getAllItems(targetId) ############################################# 
-------------------------------------------------------------------------------------------------------------------
PARAMETERS:
targetId[String]:Name of HTML id attribute to write innerHTML to.

DESCRIPTION: 
getAllItems gets every item in menu.xml. Items are ordered as they exist in menu.xml.

EXAMPLE: 
getAllItems("menuDiv") 
-----------------------------------------------------------------------------------------------------------------*/
function getAllItems(targetId){
	if(bool_dataIsReady){
		num_dataAttemptCount = 0;
		var arr_query = new Array();
		for(nodeCount=0;nodeCount<xmlDoc.firstChild.getElementsByTagName("item").length;nodeCount++){
			arr_query.push(nodeCount);
		}
		arr_displayedItems = arr_displayedItems.concat(arr_query);
		displayItems(targetId, arr_query);
	}else if(num_dataAttemptCount < 5){
		num_dataAttemptCount++;
		setTimeout("getAllItems('" + targetId + "')", 500);
	}else{
		alert("No data is available at this time.");
	}	
}
/*###############################################################################################################*/


/*############## getItemsByTagData(targetId, tagName, tagValue, bool_unique, num_limit, bool_random) ##############
-------------------------------------------------------------------------------------------------------------------
PARAMETERS:
targetId[String]:Name of HTML id attribute to write innerHTML to.
tagName[String]:Which XML tag to search (i.e. price).
tagValue[String]:Value of XML to look for (i.e $5.95).
bool_unique[Boolean](optional): Determines whether or not the function retrieves items that aren't already displayed.
num_limit[Number](optional): Determines the limit of items retrieved.
bool_random[boolean](optional): Determine whether or not the retrieved items are randomized.

DESCRIPTION: 
getItemsByTagData creates an array of item numbers based on a query of the menu.xml using tag name and tag value.
Upon completetion, the function hands the array to displayItems() which retrieves the item data from  
menu.xml and then publishes formatted items.

EXAMPLE 1: 
getItemsByTagData("menuDiv", "price", "$6.25"); 
Retrieves and publishes all items that have a price of $6.25.

EXAMPLE 2:
getItemsByTagData("menuDiv", "category", "Salad", true, 6, true);
Retrieves 6 randomized items that are currently not displayed that have the category "Salad".

-----------------------------------------------------------------------------------------------------------------*/
function getItemsByTagData(targetId, tagName, tagValue, bool_unique, num_limit, bool_random){
	if(bool_dataIsReady){
		num_dataAttemptCount = 0;
		var arr_query = new Array();
		for(nodeCount=0;nodeCount<xmlDoc.firstChild.getElementsByTagName("item").length;nodeCount++){
			if(getTextNodeValue(xmlDoc.firstChild.getElementsByTagName("item")[nodeCount], tagName) == tagValue){
				if(bool_unique == true){
					if(isItemDisplayed(nodeCount) == false){
						arr_query.push(nodeCount);
					}
				}else{
					arr_query.push(nodeCount);
				}
			}
		}
		if(bool_random == true){
			arr_query = randomizeArray(arr_query);
		}
		if(num_limit<arr_query.length){
			arr_query = arr_query.slice(0, num_limit);
		}
		displayItems(targetId, arr_query);
		arr_displayedItems = arr_displayedItems.concat(arr_query);
	}else if(num_dataAttemptCount < 100){
		num_dataAttemptCount++;
		setTimeout("getItemsByTagData('" + targetId + "','" + tagName + "','" + tagValue + "'," + bool_unique + "," + num_limit + "," + bool_random + ")", 500);
	}else{
		//alert("No data is available at this time.");
	}
}
/*###############################################################################################################*/


/*####################################### displayItems(targetId, arr_items) ####################################### 
-------------------------------------------------------------------------------------------------------------------
PARAMETERS:
targetId[String]:Name of HTML id attribute to write innerHTML to.
arr_items[Array]: Array of xml node numbers to publish. 

DESCRIPTION: 
displayItems retrieves and published data for all item nodes contained in the arr_items.
-----------------------------------------------------------------------------------------------------------------*/
function displayItems(targetId, arr_items){
	for(item_count=0;item_count<arr_items.length;item_count++){
		var currentNode = getItemNode(arr_items[item_count]);
		var num_id = getTextNodeValue(currentNode, "id");
		var str_itemName = getTextNodeValue(currentNode, "name");
		var str_description = getTextNodeValue(currentNode, "description");
		var str_image = getTextNodeValue(currentNode, "image");		
		var str_category = getTextNodeValue(currentNode, "category");
		var str_price = getTextNodeValue(currentNode, "price");
		var str_featured = getTextNodeValue(currentNode, "featured");
		var targetHtmlTag = document.getElementById(targetId);
		targetHtmlTag.innerHTML = targetHtmlTag.innerHTML + "<div class='pt10 pb10'><p><strong>" + str_itemName + "</strong><br />" + str_description + " <br/><h5> " + str_price + "</h5></p></div>";
	}
}
/*###############################################################################################################*/


/*########################################### getItemNode(itemNumber) ############################################# 
-------------------------------------------------------------------------------------------------------------------
PARAMETERS:
itemNumber[Number]: Item child node number. 

DESCRIPTION: 
Retrieves xml node data based on item number passed.

RETURNS:
Item XML Node.
-----------------------------------------------------------------------------------------------------------------*/
function getItemNode(itemNumber){
	if(itemNumber <  xmlDoc.firstChild.getElementsByTagName("item").length){
		itemNode = xmlDoc.firstChild.getElementsByTagName("item")[itemNumber];
		return itemNode;
	}
}
/*###############################################################################################################*/


/*###################################### getTextNodeValue(thisNode, tagName) ###################################### 
-------------------------------------------------------------------------------------------------------------------
PARAMETERS:
thisNode[XML Node]: Item child node. 
tagName[String]: Item child node tag to retrieve data from.

DESCRIPTION: 
Retrieves specific data from menu item based on node name.

RETURNS:
The value of the requested tag.
-----------------------------------------------------------------------------------------------------------------*/
function getTextNodeValue(thisNode, tagName){
	if(thisNode.getElementsByTagName(tagName)[0].hasChildNodes()){
		var textNodeValue = thisNode.getElementsByTagName(tagName)[0].childNodes[0].nodeValue;
		return textNodeValue;
	}
}
/*###############################################################################################################*/


/*########################################## isItemDisplayed(itemNumber) ########################################## 
-------------------------------------------------------------------------------------------------------------------
PARAMETERS:
itemNumber[itemNumber]: Item child node number. 

DESCRIPTION: 
Checks itemNumber to see if the item is already being displayed on the current page.

RETURNS:
Boolean.
-----------------------------------------------------------------------------------------------------------------*/
function isItemDisplayed(itemNumber){
	var bool_isDisplayed = false;
	for(displayedCount = 0;displayedCount < arr_displayedItems.length;displayedCount++){
		if(itemNumber == arr_displayedItems[displayedCount]){
			bool_isDisplayed = true;
		}
	}
	return bool_isDisplayed;
}
/*###############################################################################################################*/


/*############################################# randomizeArray(arr) ############################################### 
-------------------------------------------------------------------------------------------------------------------
PARAMETERS:
arr[Array]: An Array.

DESCRIPTION: 
Creates a new, randommized array based off of the provided array.

RETURNS:
A randomized array.
-----------------------------------------------------------------------------------------------------------------*/
function randomizeArray(arr){
	var savedArray = new Array();
	savedArray = arr;
	var arrayStart = new Array();
	var arrayEnd = new Array();
	var randomizedArray = new Array();
	var num_arrayLength = arr.length;
	for(i=0;i<num_arrayLength;i++){
		num_randomIndex = Math.floor(Math.random()*arr.length);
		randomizedArray.push(arr[num_randomIndex]);
		arrayStart = arr.slice(0,num_randomIndex);
		arrayEnd = arr.slice(num_randomIndex+1);
		arr = arrayStart.concat(arrayEnd);
	}
	//alert("randomizedArray: " + randomizedArray + "\narray: " + savedArray);
	return randomizedArray;
}
/*###############################################################################################################*/
