
// a safety net for both Manager objects.  In both Managers, one element acts as the main id, and is looked for first.   Let's call this the 'primary' id. 
// for the minimizablePanel the primary id is "minimizablePanelX", and for a given TabbedPanel, the primary id is "XXXXXXTab",  where XXXXXX represents the unique ID you've chosen to identify that panel and that tab. 
// if a primary id is not found, whether cause there's a typo in it's id, or if there really isnt supposed to be one, no errors will be thrown, but nothing will be instantiated for it if it's supposed to be there.  This is the natural termination of minimizablePanelManager.attachEventHandlers.   If it doesnt find minimizablePanel7, it assumes that #6 was the last one, and so it terminates. 
// if however the primary id IS found, but then one of the supplemental id's is missing or has a typo, the attachEventHandlers function should popup one of these little alerts (see function below, checkExists()  )  . 
// this will help you track simple typos more quickly. Otherwise everything would just fail and you'd get an indecipherable and error pointing unhelpfully to a line in the object's methods somewhere.

//------------- Begin MinimizablePanelManager----------
function MinimizablePanelManager() {
	this.panelStates = new Array();	
	this.panelHandles = new Array();
	this.panelTabHandles = new Array();
	this.buttonHandles = new Array();
	this.onImages = new Array();
	this.offImages = new Array();
	this.minimumHeights = new Array();
	this.maximumHeights = new Array();
	this.whichSetHash = new Array();
	this.attachEventHandlers();
}
// this is kind of a hack on the minimizablePanelManagers intended functionality,w hich is just to open and close individual panels on their own.  Note how it just tiptoes around reusing toggleMinimizablePanel, which is still tobe considered the workhorse function. 
MinimizablePanelManager.prototype.openJustOnePanel= function(whichPanel) {
	var setNum = this.whichSetHash[whichPanel];
	for (var i=0;i<this.panelHandles.length;i++) {
		if (this.whichSetHash[i] == setNum) {				//  the panel is in the correct set. 			
			if (whichPanel == i ) {										// this is actually the panel we want to be open.
				if (this.panelStates[i] == "minimized"){// if its closed.
					this.toggleMinimizablePanel(i,false);				// open it.
				}
				// else it's already open, so we dont care. 
			}
			else {																		// this is one of the other panels in the set.
				if (this.panelStates[i] == "open") {		// if it's open.
					this.toggleMinimizablePanel(i,false);				// close it
				}
				// else it's already minimized, so we dont care. 
			}
		}
	}
}
MinimizablePanelManager.prototype.toggleMinimizablePanel= function(whichPanel,suppressRollover) {
	var workingPanel			= this.panelHandles[whichPanel] ;
	var workingPanelBar		= this.panelTabHandles[whichPanel] ;

	if (this.panelStates[whichPanel] == "minimized") {
		workingPanel.style.height = this.maximumHeights[whichPanel]+ "px";
		workingPanel.style.overflow = "visible"

		workingPanel.style.visibility = "inherit";
		
		this.panelStates[whichPanel] = "open";
		if ((!suppressRollover) &&(workingPanel.getAttribute("onimage"))) {
			workingPanelBar.style.background = "url("+workingPanel.getAttribute('onimage')+")";
			
			this.buttonHandles[whichPanel].src = this.onImages[whichPanel];
			nodeList = workingPanelBar.getElementsByTagName("td");
			for (var i=0; i<nodeList.length; i++ ) {
				nodeList[i].style.color = "#fff"
			}
		}
	}
	else {
		// zero height makes some browsers unhappy. This fakes it. 
		if (this.minimumHeights[whichPanel]==0) {
			workingPanel.style.height = "1px";
			workingPanel.style.visibility = "hidden";
		}
		else workingPanel.style.height = this.minimumHeights[whichPanel]+ "px";
		workingPanel.style.overflow = "hidden"
		this.panelStates[whichPanel] = "minimized";
		if (((!suppressRollover) && workingPanel.getAttribute("offimage"))) {
			workingPanelBar.style.background = "url("+workingPanel.getAttribute('offimage')+")";
			
			this.buttonHandles[whichPanel].src = this.offImages[whichPanel];

			nodeList = workingPanelBar.getElementsByTagName("td");
			for (var i=0; i<nodeList.length; i++ ) {
				nodeList[i].style.color = "#ddd"
			}
		}
	}
	
	if ((is.ns) && (is.v>=5)) calculateOffset();
}


// this will attach the necessary event handlers at runtime, directly to the objects in the DOM.  The eval'ing of anonymous functions only seem strange until you learn that this is exactly what browsers do when they encounter things like onclick attributes in HTML. 
MinimizablePanelManager.prototype.attachEventHandlers = function() {
	var allDivNodeList = document.body.getElementsByTagName("div");
	var trueIndex = 0 ;
	for (var i=0; i<allDivNodeList.length ; i++) {
		// msoft jerks use className, and dont expose class as an attribute, I guess cause they wanted to corner the market on Annoying. 
		if (allDivNodeList[i].getAttribute("class") == "minimizable" || allDivNodeList[i].className == "minimizable") {
			this.whichSetHash[trueIndex] = allDivNodeList[i].getAttribute("set");
			this.panelHandles[trueIndex]    = allDivNodeList[i];
			this.panelTabHandles[trueIndex] = allDivNodeList[i].getElementsByTagName("table")[0];
			var imageHandles  = allDivNodeList[i].getElementsByTagName("img");
			for (var j=0; j<imageHandles.length; j++) {
				if (imageHandles[j].getAttribute('onimage')) {
					this.buttonHandles[trueIndex] = imageHandles[j];
					this.onImages[trueIndex] = this.buttonHandles[trueIndex].getAttribute('onimage')
					this.offImages[trueIndex] = this.buttonHandles[trueIndex].getAttribute('src')
				}
			}
			
			if (allDivNodeList[i].getAttribute("minimumheight")) this.minimumHeights[trueIndex] = allDivNodeList[i].getAttribute("minimumheight");
			else this.minimumHeights[trueIndex] = 15;
			if (allDivNodeList[i].getAttribute("maximumheight")) this.maximumHeights[trueIndex] = allDivNodeList[i].getAttribute("maximumheight");
			else this.maximumHeights[trueIndex] = 220;
			if (is.ie && is.mac) {
				eval("this.panelHandles[trueIndex].onclick  = function() {minimizablePanelManager.openJustOnePanel("+trueIndex+",false);return false;};"); 
			}
			else {
				eval("this.panelTabHandles[trueIndex].onclick  = function() {minimizablePanelManager.openJustOnePanel("+trueIndex+",false);return false;};"); 
			}
			if (allDivNodeList[i].getAttribute("expanded")=="no") {
				this.toggleMinimizablePanel(trueIndex,false);
				this.panelStates[trueIndex] = "minimized";
			}
			else {
				this.toggleMinimizablePanel(trueIndex,false);
				this.toggleMinimizablePanel(trueIndex,false);
				this.panelStates[trueIndex] = "open";
				
			}
			trueIndex++;
		}
	}
}

//-------------- END MINIMIZABLEPANELMANAGER



//------------------ Begin TabbedPanelSetManager  ----
function TabbedPanelSetManager(setNumber,numberOfPanels) {
	this.panelNames = new Array();
	this.activePanel = -1;
	for (var i=0; i < numberOfPanels; i++) {
		this.panelNames[i] = "Set"+setNumber+"P"+i;
		if (document.getElementById(this.panelNames[i]+"Panel").getAttribute("active")=="1") this.activePanel =i;
		
	}
	this.setNumber= setNumber;
	this.panelOnBgImageLeft = new Image();
	this.panelOffBgImageLeft = new Image();
	this.panelOverBgImageLeft =  new Image();
	this.panelOnBgImageLeft.src			= "images/tab_on_left.gif";
	this.panelOffBgImageLeft.src		= "images/tab_off_left.gif";
	this.panelOverBgImageLeft.src		= "images/tab_over_left.gif";
	
	this.attachEventHandlers();
	if (this.activePanel >-1) {
		this.activateTabbedPanel(this.activePanel);
	}
}
TabbedPanelSetManager.prototype.resetPanelPosition = function(which) {
	var ePanel = document.getElementById(this.panelNames[which]+"Panel");
	if (ePanel.getAttribute("nested")==1) {
		if ((is.ie) && (is.mac)) {
			ePanel.style.top  = (panelOffsetY -35 )+ "px";
		}
		else {
			ePanel.style.top  = (panelOffsetY -44 )+ "px";
		}
	}
	else {  // not nested
		if ((is.ie) && (is.mac)) {
			ePanel.style.top  = (panelOffsetY +26) + "px";
		}
		else {
			ePanel.style.top  = (panelOffsetY + 16) + "px";
		}
	}
}



// the workhorse function to display a new panel, and hide the others.  Hiding  is done by moving offscreen.  
TabbedPanelSetManager.prototype.activateTabbedPanel = function(which) {
	for (var i=0; (document.getElementById(this.panelNames[i]+"Tab")); i++) {
		var eTabLeftPiece = document.getElementById(this.panelNames[i]+"TabLeftPiece");
		var eTab = document.getElementById(this.panelNames[i]+"Tab");
		var eLink = document.getElementById(this.panelNames[i]+"TabLink");
		
		var ePanel = document.getElementById(this.panelNames[i]+"Panel");
		this.activePanel = which;
		if (i==which) {
			eTabLeftPiece.style.background = "url("+this.panelOnBgImageLeft.src+")";
			eLink.style.color = "#fff";
			
			if (ePanel.getAttribute("nested")) {
				ePanel.style.visibility = "inherit";
			}
			else {
				ePanel.style.visibility = "visible";
			}
		}
		else {
			eTabLeftPiece.style.background = "url("+this.panelOffBgImageLeft.src+")";
			eLink.style.color = "#ccc";
			ePanel.style.visibility=  "hidden";
		}
	}
	return false;
}

TabbedPanelSetManager.prototype.rolloverTab = function(whichTab,whichState) {
	var eTabLeftPiece = document.getElementById(this.panelNames[whichTab]+"TabLeftPiece");
	if (this.activePanel!=whichTab) {  // automatically ban rollovers on the active panel images.
		if (whichState=="on") {
			eTabLeftPiece.style.background = "url("+this.panelOverBgImageLeft.src+")";
		}
		else {
			eTabLeftPiece.style.background = "url("+this.panelOffBgImageLeft.src+")";
		}
	}
}

// this will attach any necessary event handlers to the links and divs for the Tabbed Panels.
TabbedPanelSetManager.prototype.attachEventHandlers = function() {
	for (var i=0; (document.getElementById(this.panelNames[i]+"Tab")); i++) {
		checkExists(this.panelNames[i]+"Tab");
		checkExists(this.panelNames[i]+"Panel");
		checkExists(this.panelNames[i]+"TabLeftPiece");
		var panelTabDiv  = document.getElementById(this.panelNames[i]+"Tab");
		var panelTabLink  = document.getElementById(this.panelNames[i]+"TabLink");
		var panel = document.getElementById(this.panelNames[i]+"Panel");
		eval("panelTabDiv.onclick  = function() {TabManagers["+this.setNumber+"].activateTabbedPanel("+i+");pushStateToHash();return false;}");
		
		eval("panelTabDiv.onmouseover  = function() {TabManagers["+this.setNumber+"].rolloverTab("+i+",'on');}");
		eval("panelTabDiv.onmouseout  = function() {TabManagers["+this.setNumber+"].rolloverTab("+i+",'off');}");
		eval("panelTabLink.onfocus  = function() {this.blur();}");
	}
}
//------------------ End TabbedPanelSetManager  ----
