/*
 *	Variables that are used throughtout the program that might require
 *	tweaking in the near future, if changes to the format of the side 
 *	menu are required.
 */

var _list_id = 0;
var _mLists = new Array();
var HTMLToGenerate = "";
var l = 0;
var nMenuLength = 25;
var nMenuIndentLength = 3;
var collapseimage = "/images/shared/b_arrow.gif";
var expandimage = "/images/shared/b_arrow_down.gif";
var getselecteditem ='';
var getselectedlist ='';

/*
 *	Constructor for the List object. Elements of the side menu are stored
 *	in a List. A List can be a single entity (an item) pr may contain other 
 *	Lists.
 */
function List(visible, width, height, bgColor) 
{
	//alert("Making a new list");
	
	this.lists			= new Array();	// sublists
	this.types			= new Array();	// type
	this.strs			= new Array();	// content
	this.itemid			= new Array();	// item ids
	this.visible			= visible;
	this.width			= width || 200;
	this.height			= height || 22;
	
	if (bgColor) 
	{
		this.bgColor = bgColor;
	}
}

/*
 *	Function which generates the HTML for the side menu, according to the 
 *	list information passed through the function buildMenu()
 */
function _writeList() 
{
	//alert("In _writeList()");
	
	var item;
	var str;
	var liststr;
	var clip;
	var styleObj;
	var i;
	var cellStyle = '';
	
	/*
	 * 	Note IE 5.x treats the background color set on the containing DIV as being
	 *  	inherited by it's children. But that is not the case in CSS1, so for a compliant
	 * 	browser such as Mozilla or Netscape 6, you must set the Table cell's background
	 * 	color as transparent so the parent's background color will show through.
	 * 	Also, Navigator 4, screws up with background color of transparent, so leave it out...
	*/
	
	if (navigator.DOMCSS1)
		cellStyle = 'class="inline"';

	// Iterate through the lists (and its sublists).
	for (i = 0; i < this.types.length; i++) 
	{		
		
		// Get the URL link.
		sURLLink = getSubString(this.strs[i], "\'\/", "\'");

		// Get the menu level number link.
		sMenuLevel = getSubString(this.strs[i], "\'", "\'");

			//Indenting check
			//if List
			if (sMenuLevel == 'menus_level2_list')
			{
				menuLevelclass = 'menulevelindent2';
				selectedlevelclass = 'list_selected_2';
			}
			if (sMenuLevel == 'menus_level3_list')
			{
				menuLevelclass = 'menulevelindent3';
				selectedlevelclass = 'list_selected_3';
			}
			if (sMenuLevel == 'menus_level4_list')
			{
				menuLevelclass = 'menulevelindent4';
				selectedlevelclass = 'list_selected_4';
			}
			
			//if item
			if (sMenuLevel == 'menus_level2_item')
			{
				menuLevelclass = 'menulevelindent2';
				selectedlevelclass = '';
			}
			if (sMenuLevel == 'menus_level3_item')
			{
				menuLevelclass = 'menulevelindent3';
				selectedlevelclass = '';
			}
			if (sMenuLevel == 'menus_level4_item')
			{
				menuLevelclass = 'menulevelindent4';
				selectedlevelclass = '';
			}
			if (sMenuLevel == 'menus_level5_item')
			{
				menuLevelclass = 'menulevelindent5';
				selectedlevelclass = '';
			}
			if (sMenuLevel == 'selected')
			{
				menuLevelclass = 'menulevelindentselected';
			}
//			if (sMenuLevel == 'selected')
//			{
//				menuLevelclass = 'menulevelindent2sel';
//			}
//			alert(menuLevelclass);


		if (sURLLink == "")
		{
			sURLLink = getSubString(this.strs[i], "\"", "\"");
		}

		// This variable stores the html to be generated.
		str = '';
		liststr ='';
		str += '<DIV class="menudiv">';

		// Extra cells for indenting.
//		for (nCounter = 0; nCounter < l; nCounter++) 
//		{
//			str += '<div WIDTH="5" VALIGN="top" class="sidenav-inline">&nbsp;</div>';
//		}

		// Place the arrow image for lists, arrow can either be pointing down
		// for expanded menu items, or pointing to the right for collapsed menu
		// items.
		if (this.types[i] == 'list') 
		{
//			alert ("Selected list = "+getselectedlist + " - URL Link = " +sURLLink);

			if (getselectedlist == sURLLink)
			{
//				alert("list has been selected - yah");
				liststr += '';
				getselectedlist = '';

			}
			else
			{


				if (this.lists[i].visible)
				{
//					liststr = '<div id="list"><img class="' + menuLevelclass + '" SRC="/images/shared/spacer.gif"><A TARGET="_self"  WIDTH="0" HREF="' + sURLLink + '">';
//					liststr += '<IMG BORDER="0" SRC="' + expandimage + '" ID="_img' + this.lists[i].id + '" NAME="_img' + this.lists[i].id + '">';
				}
				else
				{
//					liststr = '<div id="list"><img class="' + menuLevelclass + '" SRC="/images/shared/spacer.gif"><A TARGET="_self"  WIDTH="0" HREF="' + sURLLink + '">';
//					liststr += '<IMG BORDER="0" SRC="' + collapseimage + '" ID="_img' + this.lists[i].id + '" NAME="_img' + this.lists[i].id + '">';
				}
//				liststr += '</A></div>&nbsp;';
			}
		} 

		str += liststr;

		// Merely for indenting.
		if (this.types[i] == 'item')
		{
//			alert ("Selected item = "+getselecteditem + " - URL Link = " +sURLLink);

			if (getselecteditem == sURLLink)
			{
//				alert("item has been selected - yah");
				str += '';
				getselecteditem = "";

			}
			else
			{
//				str += '<img class="' + menuLevelclass + '" SRC="/images/shared/spacer.gif">';

			}
		}
		// Split the text to be placed in the table so that lines are not longer 
		// than the desired side menu width. The variables passed are "magic 
		// numbers" and should be changed if the width of the side menu changes.
		if (this.types[i] == 'list') 
		{
			if (this.lists[i].visible)
			{

				str += '<div id="listitem"><div id="'+selectedlevelclass+'">'+this.strs[i];		
				str += '</div></div></DIV>';
			}
			else
			{

				str += '<div id="listitem">'+this.strs[i];		
				str += '</div></DIV>';
			}
		}
		if (this.types[i] == 'item') 
		{
			str += '<div id="listitem">'+this.strs[i];		
			str += '</div></DIV>';
		}

//alert(this.strs[i]);
		HTMLToGenerate = HTMLToGenerate + str;
		//alert(HTMLToGenerate);

		// Recursive call for sublists in this list. Note: l is the level counter.		
		if (this.types[i] == 'list' && this.lists[i].visible)
		{
			l++;
			this.lists[i]._writeList();		
			l--;
		}
	}
}

/*
 *	Function called to build the list. x, y are the co-ordinates from the old
 *	floating JS menu, there's no use for it now, it can be removed. It hasn't
 *	been removed as I'm leaving today, and it's gonna take too much effort to
 * 	co-ordinate with Stan.
 *
 *	Returns the HTML for the side menu.
 */
function build(x, y) 
{
	this._writeList();

	HTMLToGenerate = '<Div class="navigation">' + HTMLToGenerate + '</Div>';
//	alert("HTML is : " + HTMLToGenerate);
    
//	ChangeClass('selected', 'highlight');

	return HTMLToGenerate;
}

function ChangeClass(controlID, strNewClass)
     {
//	  	 alert (controlID);
	  var objControl = document.getElementById(controlID);
      if (objControl)
      {
//	  	 alert ("hello");
   	  var arrControls = document.getElementsByTagName(objControl.tagName);  
   	  for (var i=0; i<arrControls.length; i++)
   	  {
//alert (i);
			if (arrControls[i].id == controlID){
         	      arrControls[i].className = strNewClass;
   	              document.getElementById("sidenav"+i).className = strNewClass;  
		     }
   	  }
      }
     }


/*
 *	Returns an internal menu id for a menu item/list.
 */
function getNewId()
{
	//alert("New ID generated: " + _list_id);
	return _list_id++;
}

/*
 * 	Adds an item to the menu. An item is a menu entity with no sublists. Also checks
 * 	if the item being added matches the page it is being generated from. If they match,
 *	the item visible attribute is set to true, which expands all branches to show this
 *	particular item.
 */
function addItem(str, id, bgColor) 
{
var menuLevelclass;
	//alert ("In addItem(), id: " + id);
	this.types[this.types.length] = 'item';
	//alert("Page ID: " + sPageID);

	// Check for match of page id's.
	if (sURLID.toString() == id.toString())
	{
		// Get the menu level number link.
		var	sMenuLevel = getSubString(str, "\'", "\'");
		var selectedlevelclass;

			if (sMenuLevel == 'menus_level1_item')
			{
				selectedlevelclass = 'highlight_1';
			}
			if (sMenuLevel == 'menus_level2_item')
			{
				selectedlevelclass = 'highlight_2';
			}
			if (sMenuLevel == 'menus_level3_item')
			{
				selectedlevelclass = 'highlight_3';
			}
			if (sMenuLevel == 'menus_level4_item')
			{
				selectedlevelclass = 'highlight_4';
			}
			if (sMenuLevel == 'menus_level5_item')
			{
				selectedlevelclass = 'highlight_5';
			}

		getselecteditem = getSubString(str, "\'\/", "\'");

		//alert("User given id (" +  id + ") = page id (" + sPageID + ")");
		this.visible = true;
		this.strs[this.strs.length] = '<div class="'+selectedlevelclass+'">' + str + '</div>';
//		this.strs[this.strs.length] = "<div class='selected'>" + str + "</div>";
	}
	else
	{
//		this.strs[this.strs.length] = "<div>" + str + "</div>";
		this.strs[this.strs.length] = str;
	}		
//	alert (str);
}

/*
 * 	Adds a list to the menu. An list is a menu entity with sublists under it. This 
 *	function also checks if the list being added matches the page it is being generated 
 *	from. If they match, the item visible attribute is set to true, which expands all 
 * 	branches to show this particular item list, and all the items or lists (collapsed) 
 *	under it.
 */
function addList(list, str, id, bgColor) 
{
	//alert ("In addList()");
	var nIndex = this.types.length;
	//alert (this.lists.length);
	
	list.id = getNewId();
	this.types[nIndex] = 'list';
	this.lists[nIndex] = list;
	
	/*alert ("In addList(), , id: " + id + 
		"\ninternal lists id: " + this.lists[nIndex].id + 
		"\n lists length: " + this.lists[nIndex].types.length);*/
	
	// Set this sublist's parent as the object where the addList() function
	// is called from.
	list.parentList = this;
	
	//alert ("id: " +  list.parentList.id + ", visibility: " +  list.parentList.visible);
//		alert ("id: " +  id.toString() + ", sPageId: " +  sPageID.toString());
	// Check for match of page id's.	
	if (sURLID.toString() == id.toString())
	{
//		alert ("id: " +  id.toString() + ", sPageId: " +  sPageID.toString());
		if (!list.parentList.visible)
		{
			list.parentList.visible = true;
		}
		var	sMenuLevel = getSubString(str, "\'", "\'");
		var selectedlevelclass;

			if (sMenuLevel == 'menus_level1_list')
			{
				selectedlevelclass = 'highlight_1';
			}
			if (sMenuLevel == 'menus_level2_list')
			{
				selectedlevelclass = 'highlight_2';
			}
			if (sMenuLevel == 'menus_level3_list')
			{
				selectedlevelclass = 'highlight_3';
			}
			if (sMenuLevel == 'menus_level4_list')
			{
				selectedlevelclass = 'highlight_4';
			}

		getselectedlist = getSubString(str, "\'\/", "\'");		
		this.lists[nIndex].visible = true;		
		this.strs[this.strs.length] = '<div class="'+selectedlevelclass+'">' + str + '</div>';
//		this.strs[this.strs.length] = "<b>" + str + "</b>";
		//alert("Found visible (base case), page ID is: " + sPageID +", index is: " + list.id);
	}
	else
	{
		// This section checks if any of the sublists under this list is visible, if any
		// are, set this list to be visible as it needs to expand to show the selected
		// item or list below it.
		this.strs[this.strs.length] = str;
		nCounter = 0;
		bFoundVisible = false;
		
		//alert("this.lists.length is: " + this.lists.length);
		while ((nCounter < this.lists.length) && (!bFoundVisible)) 
		{			
			
			if (this.types[nCounter] == 'list' && this.lists[nCounter].visible) 
			{
				//alert ("id: " +  this.lists[nCounter].id + ", visibility: " +  this.lists[nCounter].visible);
				bFoundVisible = true;
				this.visible = true;
				//alert("Found visible (nested case), index is: " + list.id);
			}
			
			nCounter = nCounter + 1;
		}
		
	}	
}


/*
 * Gets the subtring in between the specified start and end character delimiters, i.e.
 * getSubString(c='rap', "\'", "\'") returns "rap".
 * 
 * Used in getting the text in between <A HREF=...>Gets this text</A>
 */
function getSubString(sText, cStartChar, cEndChar)
{
	var sInputStr = sText.toString();
	var sURL = "";
        var nStartIndex = -1;
        var nEndIndex = -1;
        //var nCounter = 0;
        //var bGotStartIndex = false;
        //var bGotEndIndex = false;
        var bGotIndexes = false;
        
        nStartIndex = sInputStr.indexOf(cStartChar.toString());
        nEndIndex = sInputStr.indexOf(cEndChar.toString(), nStartIndex + 1);
        
        if ((nStartIndex != -1) || (nEndIndex != -1))
        {
        	if (nStartIndex < nEndIndex)
        	{
        		bGotIndexes = true;
        	}
        }
        
	if (bGotIndexes)
	{
	  //alert("Here");
	  sURL = sInputStr.substring(nStartIndex + 1, nEndIndex);	  
//	  alert("URL Link is: " + sURL);			  
	}
	
	return sURL;
}

/*
 * VERY CUSTOMISED function for handling the text splitting of the side menu. This
 * function expects input strings in the following format:
 * 
 * <a href=....>Some decription text - this gets changed by this function</a>
 */
function splitMenuString(sText, nLength)
{
	var nIndex = 0;
	var nStartIndex = 0;
	var sInputStr = sText.toString();
	var sTempStr = "";
	var sTempChar = "";
	var sReturnStr = "";
	var sLeadingTagText = "";
	var sTrailingTagText = "";
	
	
	/*alert("Index of <b>: " + sInputStr.indexOf("<b>") + 
	      "\nIndex of </b>: " + sInputStr.indexOf("</b>") + 
	      "\nLength string: " + sInputStr.length);*/
	
	//alert("Input Str before: " + sInputStr);
	
	if (sInputStr.indexOf("<b>") != -1)
	{
		sInputStr = sInputStr.substring(("<b>").length, sInputStr.indexOf("</b>"));
		sLeadingTagText += "<b>";
		sTrailingTagText += "</b>";
	}
		
	sLeadingTagText += sInputStr.substring(0, sInputStr.indexOf(">") + 1);
	sTrailingTagText = sInputStr.substring(sInputStr.lastIndexOf("<")) + sTrailingTagText;
	
	//Get rid of the leading and trailing tag text
	sInputStr = sInputStr.substring(sInputStr.indexOf(">") + 1, sInputStr.lastIndexOf("<"));
	
	//alert("Input Str after: " + sInputStr);
	//alert("divide op: " + (sInputStr.length)/nLength);
	
	while ((sInputStr.length)/nLength > 1)
	{
		sTempStr = sInputStr.substring(nStartIndex, nStartIndex + nLength);
		//alert("Temp string: " + sTempStr);
		
		if (sTempStr != "")
		{
			if (sTempStr.indexOf(" ") == -1)
			{
				sTempChar = sTempStr.charAt(nLength - 1);
				//alert("Temp char: " + sTempChar);
				//alert("index is: " + (nLength - 2));
				
				sReturnStr += sTempStr.substring(nStartIndex, (nLength - 1)) + 
					      " " + sTempChar;					 
			}
			else
			{
				sReturnStr += sTempStr;
			}						
		}
						
		sInputStr = sInputStr.substring(nLength);
		nStartIndex = 0;
		
		/*alert("Return string: " + sReturnStr + 
		      "\nNew input string: " + sInputStr);*/
	}
	
	//alert ("String to return: " + sLeadingTagText + sReturnStr + sInputStr + sTrailingTagText);
	return sLeadingTagText + sReturnStr + sInputStr + sTrailingTagText;
}


// Prototypes - yukky JScript stuff.
List.prototype.addItem			= addItem;
List.prototype.addList			= addList;
List.prototype.build			= build;
List.prototype._writeList		= _writeList;

List.prototype.lists			= null;	// sublists
List.prototype.types			= null;	// type
List.prototype.strs			= null;	// content
List.prototype.visible			= false;
List.prototype.id			= 0;
List.prototype.width			= 350;
List.prototype.height			= 22;
List.prototype.bgColor			= null;
List.prototype.parentList		= null;