/**
 *  Create an expandable view of a Millipore taxonomy tree.  
 *
 *  TaxonomyTab is implemented using prototype extensions so each instance of TaxonomyTab can
 *  have unique global variables for currently selected panels and such.
 *  
 *  channel = may be "home", "catalogue", or "capability" depending on which channel it is called from
 */ 
function TaxonomyTree(tabId, parentDivId, ajaxLoadingPanelId, channel, finalize, params) {
	this.parentDivId = parentDivId;
	this.loadingPanelId = ajaxLoadingPanelId;
	this.channelTree = channel;
	this.finalize = finalize;
	this.params = params;
	this.loaded = false;
	this.currentTaxonomy = "";

	display(this.loadingPanelId,true);

	// parameter to disable server-side cache
	this.serverCacheParam = "";
	var href = window.location.href.toString();
	if (href.indexOf("cache=false") >= 0) {
		this.serverCacheParam = "&cache=false";
	}

	var url="/fast/taxonomy_tab.do?tab=" + tabId + this.serverCacheParam + "&channel=" + this.channelTree + "&preventCache=" + parseInt(Math.random()*1000000); //  Math.random disables client side caching
	this.loadContents(url, parentDivId, true, finalize, params);
}

//  Load sub-level content for the selected TaxonomyPanel unless it was already loaded
TaxonomyTree.prototype.loadSubContents = function(taxonomyPanelId, finalize, params) 
{
	// Get ID at offset of 15 for length of "taxonomyPanel_"
	var taxonomy = taxonomyPanelId.substring(14,taxonomyPanelId.length); 
	var taxonomyContents = $("taxonomyContent_" + taxonomy);
	if (this.curTaxonomyPanelTab)
	{
		this.curTaxonomyPanelTab.className="taxonomyPanelTab";
		this.curTaxonomyPanelTab = $("taxonomyTab_"+taxonomy);
		this.curTaxonomyPanelTab.className="taxonomyPanelTabFocused";
	}

	if (taxonomyContents && (taxonomyContents.innerHTML == "undefined" || taxonomyContents.innerHTML == ""))
	{
		//  Load panel for the first time
		display(this.loadingPanelId,true);

		//  Load taxonomy content into the taxonomyContents <div>	

		url="/fast/taxonomy_tab.do?taxonomy=" + taxonomy + this.serverCacheParam + "&channel=" + this.channelTree + "&preventCache=" + parseInt(Math.random()*1000000); //  Math.random disables client side caching
		this.loadContents(url, "taxonomyContent_"+taxonomy, false, finalize, params); 
	} else { 
		// Contents already loaded so close panel if currently open.
		//taxonomyContents.style.display = (taxonomyContents.style.display == 'block') ? 'none':'block';
		var contentsHeight = taxonomyContents.style.height.replace(/[^\-0-9]/g,'');
		if (taxonomyContents.style.display == '' || taxonomyContents.style.display == 'block') {
			taxonomyContents.style.display = 'none';
			curTaxonomyPanelTab.className="taxonomyPanelTab";
		} else { //open the panel again
			//findAndCloseAllPanels(document.getElementById("rootTaxonomy"), "div", "taxonomyPanelContent");
			taxonomyContents.style.display = 'block';
		}
	}
}

TaxonomyTree.prototype.loadContents = function(url, parentId, isRoot, finalize, params) 
{
	var parentTree = this;
	new Ajax.Request(url, {  
		onSuccess: function(httpResponse) {
			display(parentTree.loadingPanelId,false);	
			$(parentId).innerHTML= httpResponse.responseText;
		
			// Only have one root taxonomy so use first <div> in array
			var taxonomy = getAllElementsByTagAndClass($(parentId),"div","rootTaxonomy")[0];
			if (!isRoot) {
				//  Reset class to reflect that this is a child taxonomy
				taxonomy.className="subTaxonomy";
			} //else className="rootTaxonomy" by default
			parentTree.loadTaxonomy(taxonomy);
			finalize(params);
			parentTree.loaded = true;
		},
		onFailure: function(httpResponse) {
			display(parentTree.loadingPanelId,false);
		},
		parameters :  ""
	});
}

TaxonomyTree.prototype.loadTaxonomy = function(taxonomyDiv) {
	var taxonomyPanels = getElementChildren(taxonomyDiv);
	for (var i = 0; i < taxonomyPanels.length; i++) {
		var taxonomyId = taxonomyPanels[i].id;  // need separate reference to id so the following virtual function can reference it properly
		var taxonomyPanelElements = getElementChildren(taxonomyPanels[i]);
		var taxonomyPanelTab = taxonomyPanelElements[0];
		this.addLoadSubListener(taxonomyPanelTab, taxonomyId);
	}
}

//  Placed into separate method so we don't lose the correct id reference as would if called directly from the for loop
TaxonomyTree.prototype.addLoadSubListener = function(taxonomyPanelTab, taxonomyId) {
	var parentTree = this; 
	var handler = function(e) {return parentTree.loadSubContents(taxonomyId, parentTree.finalize, parentTree.params); };

	try {
		if (taxonomyPanelTab.addEventListener)
			taxonomyPanelTab.addEventListener("click", handler, false);
		else if (taxonomyPanelTab.attachEvent)
	        // IE
			taxonomyPanelTab.attachEvent("onclick", handler);
	} catch (e) {}
}

TaxonomyTree.prototype.getParentDivId = function()
{
	return this.parentDivId;
}

TaxonomyTree.prototype.isLoaded = function()
{
	return this.loaded;
}

TaxonomyTree.prototype.setCurrentTaxonomy = function(currentTaxonomy)
{
	this.currentTaxonomy = currentTaxonomy;
}

TaxonomyTree.prototype.getCurrentTaxonomy = function()
{
	return this.currentTaxonomy;
}

function display(elementId,isVisible) {
	var element = $(elementId);	
	if (isVisible)
		element.style.display="block";
	else
		element.style.display="none";
}

//  Get just the children at the first level of this elements children.
//  Can't use getElementsByTagName() as it returns children in full DOM tree below the parent
function getElementChildren(element){
	var children = [];
	var child = element.firstChild;
	while (child)
	{
		if (child.nodeType == 1 /* Node.ELEMENT_NODE */)
			children.push(child);
		child = child.nextSibling;
	}
	return children;
}

// Get all children of a given object that have both the tag and class name given
function getAllElementsByTagAndClass(parentObj, tagName, className) {
	allTags=parentObj.getElementsByTagName(tagName);
	
	regExpClass=new RegExp('\\b'+className+'\\b', "gi");
	
	result=new Array();
	for (i=0; i<allTags.length; i++) {
		if (typeof allTags[i].className != "undefined") {
			if (allTags[i].className!=null) {
				if (allTags[i].className.search(regExpClass)!=-1) {
					result[result.length]=allTags[i];
				}
			}
		}
	}
	
	return result;
}


// Get all children of a given object that have both the tag and class name given
function findAndCloseAllPanels(parentObj, tagName, className) {

	allTags=parentObj.getElementsByTagName(tagName);
	
	regExpClass=new RegExp('\\b'+className+'\\b', "gi");
	
	alert(allTags.length);
	
	// result=new Array();
	for (i=0; i<allTags.length; i++) {
		if (typeof allTags[i].className != "undefined") {
			if (allTags[i].className!=null) {
				if (allTags[i].className.search(regExpClass)!=-1) {
					//result[result.length]=allTags[i];
					// alert(allTags[i].className);
					allTags[i].style.display = 'none';
				}
			}
		}
	}
	
	// return result;
}