//HTTPRequestMenu class
//Dependancies: utilities.js

var requestOrigin = "";

function HTTPRequestMenu(){
	this.HTTPRequest;
	this.timeout = 0;
	//dgb change this from 10 to 16 px
	this.subMenuSpace = 16;
	
	this.onreturn;
	
	//dgb prevClick is used to reset the class on the previously clicked link
	this.prevClick = "";
	
	this.requestURL;
	this.imgURL = "images/";
	this.images = {
		"expand": "plus.gif",
		"spacer": "spacer.gif",
		"collapse": "minus.gif"
	}
	//dgb Will look for loader image in this.imgURL
	this.loaderImage = "loading_small.gif";	
	
	this._requestInProgress = false;
	this.currentMenuItem;
	this.topMenuItem;
	//dgb add a menu class name
	this.MenuClassName = "HTTPRequestMenu";
	this.firstLoad = true;
	
	this.currentHighlightItem = false;
	this.currentHighlightType = false;
}

//set passed HTTPRequestMenuItem as current item
HTTPRequestMenu.prototype.setCurrentItem = function(item){
	this.currentMenuItem = item;
}

//returns if we are already waiting on a request
HTTPRequestMenu.prototype.requestInProgress = function(item){
	return this._requestInProgress;
}

HTTPRequestMenu.prototype.loadItem = function(item,type,baseitem,basetype,dd,dd_page,dd_target){
	if (this.requestInProgress())	return false;
	this._requestInProgress = true;
	if(this.firstLoad)
	{
		// WS 20110117 dragdrop text pages
		var ddparams = "";
		try {
			if (dd != null && dd_page != null && dd_target != null) {
				ddparams = "&dd=1&dd_page=" + dd_page + "&dd_target=" + dd_target;
			}
		} catch (e) {}
		var url=utilities.appendURLQuery(this.requestURL, "item=" + item+"&type=" + type+"&baseitem=" + baseitem+"&basetype=" + basetype+"&load_base=true" + ddparams);
		this.firstLoad=false;
	} else
	{
		var url=utilities.appendURLQuery(this.requestURL, "item=" + item+"&type=" + type);
	}
	this.HTTPRequest.open(url);
}

HTTPRequestMenu.prototype.after_load = function()
{
	
}

//generate the menu
HTTPRequestMenu.prototype.generate = function(element_id, item,type){
	var self = this;
	this.HTTPRequest = new HTTPRequest();
	this.HTTPRequest.timeout = this.timeout;
	this.HTTPRequest.onupdate = function(response, error){
		self._requestInProgress = false;
		var navMenuItem = self.currentMenuItem;
		if (error){
			alert("There was a problem processing the data:\n" + error);
		}

		//if we have no element, our work is done
		if (! navMenuItem) return;
	
		//clear loading message, we assume it is the last child added
		navMenuItem.removeLoader();
		
		if (error) return false;

		items = HTTPRequestMenu.extractData(this.responseXML);
		// WS 20110117 allow for messages to be retrieved from the body tag
		self.msgs = this.responseXML.firstChild.getAttribute("msgs");
		// WS 20110812 allow for the origin of the request (either navigator or filing_cabinet)
		// to be retrieved from the body tag
		requestOrigin = this.responseXML.firstChild.getAttribute("origin");
		navMenuItem.addChildItems(items);
		navMenuItem.loaded = true;
		self.after_load();
	}
	
	element = document.getElementById(element_id);
	navMenuItem = new HTTPRequestMenuItem(item,'',false,'',false,type);
	if(this.baseID)
	{
		navMenuItem.baseID=this.baseID;
	} else
	{
		navMenuItem.baseID=item;
	}
	navMenuItem.baseType=this.baseType;
	this.setCurrentItem(navMenuItem);
	this.topMenuItem = navMenuItem;
	navMenuItem.HTTPRequestMenu = this;
	navMenuItem.generate();
	navMenuItem.subItemsInnerShell = element;
	navMenuItem.load();
}


//returns an image's path
HTTPRequestMenu.prototype._imgURL = function(file){
	return this.imgURL + this.images[file];
}

function get_nextsibling(n)
{
	x=n.nextSibling;
	while (x && x.nodeType!=1)
	{
	 	x=x.nextSibling;
	}
	return x;
}

function get_firstchild(n)
{
	x=n.firstChild;
	while (x && x.nodeType!=1)
	{
		x=x.nextSibling;
	}
	return x;
}
function get_text(n)
{
	var t='';
	x=n.firstChild;
	while(x)
	{
		if(x.nodeType==3)
		{
			if(t) alert(t);
			t=t+x.nodeValue;
		}
		x=x.nextSibling;
	}
	t=t.replace(/&lt;/,"<");
	t=t.replace(/&gt;/,">");
	t=t.replace(/&amp;/,"&");
	return t;
}

//extract the data into a multidimensional array of items and attributes
HTTPRequestMenu.extractData = function(data){
	if (! data) return false;

	var items;
	var item, node, text;
	var i_key=0;
	var copyOfItems;

	var body;

	body=data.firstChild;
	item=get_firstchild(body)
	
	copyOfItems = new Array();
	while(item)
	{
		copyOfItems[i_key] = new Array();
	
		node=get_firstchild(item);
		while(node)
		{
			if(node.nodeName=='id')
			{
				copyOfItems[i_key][0]=get_text(node);
			} else if(node.nodeName=='title')
			{
				copyOfItems[i_key][1]=get_text(node);
			} else if(node.nodeName=='has_sub_items')
			{
				copyOfItems[i_key][2]=get_text(node);
			} else if(node.nodeName=='image')
			{
				copyOfItems[i_key][3]=get_text(node);
			} else if(node.nodeName=='returnable')
			{
				copyOfItems[i_key][4]=get_text(node);
			} else if(node.nodeName=='level')
			{
				copyOfItems[i_key][5]=get_text(node);
			} else if(node.nodeName=='type')
			{
				copyOfItems[i_key][6]=get_text(node);
			} else if(node.nodeName=='url')
			{
				copyOfItems[i_key][7]=get_text(node);
			} else if(node.nodeName=='highlight')
			{
				copyOfItems[i_key][8]=get_text(node);
			} else if(node.nodeName=='subtype')	// WS 20110106 allow drag/drop of content pages (add subtype)
			{
				copyOfItems[i_key][9]=get_text(node);
			}
			node=get_nextsibling(node);
		}
		item=get_nextsibling(item);
		i_key++;
	}
	
	return copyOfItems;
}

HTTPRequestMenu.prototype.reload = function(item,type)
{
	this.topMenuItem.reload(item.replace(/^\s+|\s+$/g, ''),type.replace(/^\s+|\s+$/g, ''));
}

HTTPRequestMenu.prototype.reloadTopMenu = function(item,type,baseID,baseType,dd,dd_page,dd_target)
{

	//reload everything
	this.firstLoad = true;
	
	//change the baseItem and baseType if specified otherwise default to current
	if(baseID){	
		if(baseID != -1){
			this.topMenuItem.baseID = baseID.replace(/^\s+|\s+$/g, '');
		}else{
			this.topMenuItem.baseID = -1;	
		}
	}
	if(baseType){	
		this.topMenuItem.baseType = baseType.replace(/^\s+|\s+$/g, '');
	}
		
	//change the item and type if specified otherwise default to current
	if(item || type){
		this.topMenuItem.item = item.replace(/^\s+|\s+$/g, '');
		this.topMenuItem.type = type.replace(/^\s+|\s+$/g, '');
	}else if(this.currentHighlightItem){
		this.topMenuItem.item = this.currentHighlightItem;
		this.topMenuItem.type = this.currentHighlightType;
	}
	
	// WS 20110117 dragdrop text pages
	this.topMenuItem.dd = dd;
	this.topMenuItem.dd_page = dd_page;
	this.topMenuItem.dd_target = dd_target;
	
	//Reload everything from the top menu item down
	this.topMenuItem.childItems.length=0;
	this.topMenuItem.subItemsInnerShell.innerHTML='';
	this.topMenuItem.loaded=false;
	this.topMenuItem.expand();
}

//HTTPRequestMenuItem class
function HTTPRequestMenuItem(item, title, hasSubItems, image, returnItem, type, url, highlight, parent, subtype){
	this.item = item;
	this.type = type;
	this.url = url;
	this.highlight = highlight;
	// WS 20110106 allow drag/drop of content pages (add subtype)
	this.subtype = subtype;
	
	//Tim: Convert all HTML characters of the form &#number; to their Unicode equivalent. This is 
	//     because createTextNode automatically converts all characters to their HTML equivalent,
	//     and thus converts &#037; to &amp;#037; etc. 
	
	//Convert to string
	var t=title+'';
	//Find all numeric HTML encodings
	var chars=t.match(/&#\d+;/g);
	if(chars != null) {
		//Loop through all matched characters
		for(var i=0; i<chars.length; i++) {
			n=chars[i].slice(2,-1);      //The character number as a string
			c=String.fromCharCode(n*1);  //The Unicode equivalent
			t = t.replace(new RegExp(chars[i],'g'), c);  //Perform the replacement
		}
	}
	//dgb add space in front of title
	this.title = t;
	this.image = image;
	this.hasSubItems = hasSubItems;
	this.returnItem = (returnItem==1);
	this.loaded = false;
	this.expanded = false;
	this.shell;
	this.subItemsInnerShell;
	this.subItemsOuterShell;
	this.icon;
	this.loader;
	this.childItems = new Array();
	this.HTTPRequestMenu = (parent ? parent.HTTPRequestMenu : null);
}

HTTPRequestMenuItem.prototype.generate = function(){
	var self = this;
	
	//outer shell
	this.shell = document.createElement("div");
	
	//add title and expand image if necessary
	var table = document.createElement("table");
	var tbody = document.createElement("tbody");
	var tr = document.createElement("tr");
	var td = document.createElement("td");
	
	//dgb no table border
	table.border = 0;
	table.cellPadding = 0;
	table.cellSpacing = 0;
	table.appendChild(tbody);
	tbody.appendChild(tr);
	tr.appendChild(td);
		
	//needed to use table instead of div to use noWrap
	td.noWrap = true;

	var img = document.createElement("img");
	//check if we have sub items
	if (this.hasSubItems){
		img.src = this.HTTPRequestMenu._imgURL("expand");
		img.style.cursor = document.all ? "hand" : "pointer";
		img.onclick = function(){
			self.expand();
		}
	}else{
		img.src = this.HTTPRequestMenu._imgURL("spacer");
		//dgb increase image width from 13 to 16
		img.width = 16;
		img.height = 1;
	}
	
	this.icon = img;
	td.appendChild(this.icon);
	
	if (this.image){
		img = document.createElement("img");
		img.src = this.image;
		//dgb add 1px above the image
		img.style.padding = "1px 0px 0px 0px";
		td.appendChild(img);
	}
	
	// WS 20110106 allow drag/drop of content pages (a tags are not draggable!)
	var a = document.createElement("span");
//	a.href = "javascript:void(0)";
	if (this.returnItem){
		a.onclick = function(){
			self.a = a;
			self._onclick();
		}
	} else
	{
		a.style.textDecoration='none';
		a.style.cursor='default';
		a.className='HTTPRequestMenuNoLink';
	}
	
	//dgb give the a refs some alt text
	a.title = this.title;
	
	//dgb add 2px before and 5px after the a ref
	a.style.padding = "0px 5px 0px 2px";
	//dgb create a bit of space before the a ref
	a.style.margin = "0px 0px 0px 2px";
	
	a.appendChild(document.createTextNode(this.title));
	//
	//dgb set the class for the first item to nav_highlight
	if(this.HTTPRequestMenu.prevClick == "" || this.highlight ){

		a.className = "nav_highlight";
		this.HTTPRequestMenu.prevClick = a;
	}
	td.appendChild(a);
	
	// WS 20110106 allow drag/drop of content pages (add subtype)
	td.setAttribute("recid", this.item);
	td.setAttribute("navtype", this.type);
	// WS 20110805 only enable drag if the item represents a rep entry
	if (this.item.match(/:\d+$/gi)) {
		td.className += " navigatorDraggable";
	}
	if (this.subtype == "D") {
		td.className += " navigatorDropable";
	} else if (this.item.match(/^D\..*?:\d+$/g)) {
		td.className += " navigatorDropable";
	} else if (this.subtype == "FF") {
		td.className += " fcNavigatorDropable";
	} else if (requestOrigin == "filing_cabinet") {
		if (this.subtype == "Cl" || this.subtype == "UA" || this.subtype == "clusterroot" || this.subtype == "publicroot") {
			td.className += " fcNavigatorDropable";
		}
	}

	this.shell.appendChild(table);
	
	//create a table with the spacer on the left and everything else on the right
	table = document.createElement("table");
	tbody = document.createElement("tbody");
	tr = document.createElement("tr");
	
	table.cellPadding = 0;
	table.cellSpacing = 0;
	table.appendChild(tbody);
	tbody.appendChild(tr);
	
	//if we aren't top level, create a cell with a spacer
	if (! this.isTopMenuItem()){
		td = document.createElement("td");
		tr.appendChild(td);
		
		img = document.createElement("img");
		img.src = this.HTTPRequestMenu._imgURL("spacer");
		img.width = this.HTTPRequestMenu.subMenuSpace;
		img.height = 1;
		td.appendChild(img);
	}

	td = document.createElement("td");
	tr.appendChild(td);
	this.shell.appendChild(table);
	
	//shell for our sub items
	this.subItemsInnerShell = td;
	this.subItemsOuterShell = table;
	
	//set current highlight item for menu
	if(this.highlight){
		this.HTTPRequestMenu.currentHighlightItem = this.item;
		this.HTTPRequestMenu.currentHighlightType = this.type;
	}
	
}

HTTPRequestMenuItem.generateError = function(errorText){
	//outer shell
	var div = document.createElement("div");
	div.appendChild(document.createTextNode(errorText));
	return div;
}

HTTPRequestMenuItem.prototype.expand = function(){
	var self = this;

	if (! this.loaded){
		//don't try to expand if we are already getting another menu
		if (this.HTTPRequestMenu.requestInProgress())
			return false;
	
		this.load();
	}
	
	this.icon.src = this.HTTPRequestMenu._imgURL("collapse");
	this.icon.height = 16;
	this.icon.onclick = function(){
		self.collapse();
	}
	this.subItemsOuterShell.style.display = "block";
	this.subItemsOuterShell.className = this.MenuClassName;
}

HTTPRequestMenuItem.prototype.collapse = function(){
	var self = this;

	this.icon.src = this.HTTPRequestMenu._imgURL("expand");
	this.icon.onclick = function(){
		self.expand();
	}
	this.subItemsOuterShell.style.display = "none";
}

HTTPRequestMenuItem.prototype.reload_now = function(){
	//Golly. It's us. Delete and reload.
	this.childItems.length=0;
	this.subItemsInnerShell.innerHTML='';
	this.loaded=false;
	
	this.expand();
}
HTTPRequestMenuItem.prototype.reload = function(item,type){
	var ix, ret;
	//We do a depth first search because in some circumstances (e.g. when baseitem is set)
	//the topmost item is just a stub, and the real one is lower down.
	for(ix in this.childItems)
	{
		ret = this.childItems[ix].reload(item,type);
		if(ret) return true;
	}
	if(this.item.replace(/^\s+|\s+$/g, '')==item && this.type.replace(/^\s+|\s+$/g, '')==type)
	{
		//Golly. It's us. Delete and reload.
		this.reload_now();
		return true;
	} else
	{
		return false;
	}
}

//load the menu's sub item
HTTPRequestMenuItem.prototype.load = function(){
	this.setAsCurrentItem(this);
	this.addLoader();
	this.HTTPRequestMenu.loadItem(this.item,this.type,this.baseID,this.baseType,this.dd,this.dd_page,this.dd_target);
}

//set as current menu item
HTTPRequestMenuItem.prototype.setAsCurrentItem = function(){
	this.HTTPRequestMenu.setCurrentItem(this);
}

//returns whether current item is top menu item
HTTPRequestMenuItem.prototype.isTopMenuItem = function(){
	return (this.HTTPRequestMenu.topMenuItem == this);
}

//add loading message
HTTPRequestMenuItem.prototype.addLoader = function(){
	this.loader = document.createElement("div");
	this.loader.className = "loader";
	this.loader.appendChild(document.createTextNode(" Loading... "));
	if(this.HTTPRequestMenu.loaderImage != ""){
		this.loaderImg = document.createElement("img");
		this.loaderImg.src = this.HTTPRequestMenu.imgURL + this.HTTPRequestMenu.loaderImage;
		this.loader.appendChild(this.loaderImg);
	}
	this.subItemsInnerShell.appendChild(this.loader);
}

//remove loading message
HTTPRequestMenuItem.prototype.removeLoader = function(){
	try {
		this.subItemsInnerShell.removeChild(this.loader);
	}
	catch(e){}
}

//remove loading message
HTTPRequestMenuItem.prototype.addChildItems = function(items, current_level){
	var div;
	var img;
	var text;
	var subItem;

	(! current_level) && (current_level = 0);

	//if this isn't the top level, expand this menu item
	if (current_level > 0){
		this.loaded = true;
		this.expand();
	}
	
	var item;
	//for(i_key in items)
	while(items && (item = items.shift())){		
		//check if we need to add sub items
		if (item[5] > current_level){
			items.unshift(item);
			items = subItem.addChildItems(items, item[5]);
			continue;
		}
		
		//check if we need to go back to parent
		if (item[5] < current_level){
			items.unshift(item);
			return items;	
		}
		
		//var item = items[i_key];
		//items[i_key] = null;
		
		if (! item[0]) continue;
		
		var newElement;
		if (item[0].substring(0,6) == "Error:"){
			var errorText;
			errorText = item[0].substring(6);
			newElement = HTTPRequestMenuItem.generateError(errorText);
		}else{
			//if we don't have an item here, it's probably an error
			//so put text as title
			if (! item[1])
				item[1] = item[0];

			// WS 20110106 allow drag/drop of content pages (add subtype)
			subItem = new HTTPRequestMenuItem(item[0], item[1], item[2], item[3], item[4], item[6], item[7], item[8], this, item[9]);
			this.childItems[this.childItems.length] = subItem;
			subItem.generate();
			//alert(subItem.subItemsInnerShell.innerHTML);
			newElement = subItem.shell;
		}
		
		this.subItemsInnerShell.appendChild(newElement);
	}
	
	return items;
}

//item link has been clicked on, quick, do something
HTTPRequestMenuItem.prototype._onclick = function(){
	if (this.HTTPRequestMenu.onreturn){
		//dgb remove class from previously clicked a ref
		if(this.HTTPRequestMenu.prevClick != ""){
			this.HTTPRequestMenu.prevClick.className = "";
		}
		//dgb set the class for the clicked a ref to nav_highlight
		this.a.className = "nav_highlight";
		this.HTTPRequestMenu.prevClick = this.a;
		this.HTTPRequestMenu.currentHighlightItem = this.item.replace("\n",'');	
		this.HTTPRequestMenu.currentHighlightType = this.type.replace("\n",'');	
		this.HTTPRequestMenu.onreturn(this.HTTPRequestMenu.currentHighlightItem, this.title, this.type, this.url);
	}
}
