/* 

BoxController

Note: Requires boxSettings.js also be included



Revisions

2003-09-13: Jeff edited. Added expand all of type.

2003-09-15: Jeff added cookie code.



Boxes are the bordered divs with a header and body, and a expand/collapse button.

Box types:

partialMap, subTopic, callouts, comments, taskInformation, legend.



If you collapse a subTopic box on one page, you collapse all subTopic boxes that and other pages. Same with expanding.

Note: There can be more than one box of each type on the page.



In HTML, the structure expected is:



div.{boxType}Area (useful for CSS selector of different types of boxes, e.g. div.{boxType}Area div.box)

	div class="collapsiblebox" id="{boxType}{index}" (1+) 

		div.header onclick = "boxController.expandOrCollapse(this,'{boxType}')" (0-1) 

			span.title

			span.commands  ? (mike)

				span.command  ? (mike)

					img.expandOrCollapseButton src="{buttonsPath}{collapseButtonUrl} or {expandButtonUrl}"

		div.body

			(varies)

	

	Note: Visibility of div.body (i.e. style="display:block" or style="display:none") is overwritten by code.

	Note: Button graphics as well.									

	

 */



function init() {

	boxController = new BoxController("Res/images/", "box_collapse_button.gif","box_expand_button.gif", true);

	boxController.init();

}



// BoxController class



function BoxController (buttonsPath, collapseButtonFilename,expandButtonFilename, changeAllOfType) {

	this.objectClass = "BoxController";

	this.buttonsPath = buttonsPath;

	this.collapseButtonUrl = buttonsPath + collapseButtonFilename;

	this.expandButtonUrl = buttonsPath + expandButtonFilename;

	this.changeAllOfType = changeAllOfType; // if true, all boxes of a type are expanded or collapsed together, not just clicked one

	this.boxTypes = null;

}





BoxController.prototype.init = function() {

	// initialize boxTypes

	this.boxTypes = INITIAL_BOX_SETTINGS; // defaults loaded from boxSettings.js



	// check if cookie has stored states

	var cookieString = this.getCookieString();

	if (cookieString!=null) {

		// for each boxType, get stored value from cookie

		for (var i=0; i < this.boxTypes.length; i++) {

			var boxType = this.boxTypes[i];

			var value = getValueFromCookieString ( cookieString, boxType.name );

			if (value!=null) {

				boxType.state = value=="true" ? true : false;

			}

		}

	}

	

	

	// for each boxType, change state of all boxes of that type

	for (var i=0; i < this.boxTypes.length; i++) {

		this.changeStateOfAllBoxesOfType( this.boxTypes[i].name, this.boxTypes[i].state );

	}

}



BoxController.prototype.dumpBoxTypes = function() {

	var s = "BoxTypes\n";

	for (var i=0; i < this.boxTypes.length; i++) {

		s += this.boxTypes[i].name + "," + this.boxTypes[i].state+ "\n";

	}

	return s;

}

	

BoxController.prototype.saveStateToCookie = function() {

	// stores state of controller in cookie

	var cookieString = "";



	// for each box type...

	for (var i=0; i < this.boxTypes.length; i++ ) {

		var boxType = this.boxTypes[i];

		if (cookieString!="") cookieString += "&";

		cookieString += boxType.name + ":" + escape(boxType.state); 

	}



	// Cookie properties (if needed)

	// Currently assumes that all html pages are in the same directory together, otherwise cookie's path property would need to be set

	// Currently that cookie should expire when user closes the browser (expires property)

	// save cookie; will be only accessible to this html page

	var cookieName = this.objectClass;

	document.cookie = cookieName + "=" + cookieString; 

}



BoxController.prototype.getCookieString = function() {

	// checks saved state of controller from cookie; returns string of values or null if desired cookie does not exist

	var cookieName = this.objectClass;

	var allCookies = document.cookie;

	if (allCookies=="") return null;

	

	// extract the named cookie we want

	var start = allCookies.indexOf(cookieName + "=");

	if (start == -1) return null;

	

	start += cookieName.length + 1;  // skip over name and = sign

	var end = allCookies.indexOf(";", start);

	if (end==-1) end = allCookies.length;

	var cookieString = allCookies.substring(start,end);

	return cookieString;

}



BoxController.prototype.changeStateOfAllBoxesOfType = function( boxType, newState ) {

	// changes all boxes on the page of boxType to newState ("expand" or "collapse") 

	// loop through all boxes of boxType

	var boxIndex = 0;

	while (document.getElementById (boxType + boxIndex) ) {

		// change state

		this.changeStateOfBoxOnPage ( document.getElementById (boxType + boxIndex), newState );

		boxIndex++;

	}

	// store new state in array

	for (var i=0; i < this.boxTypes.length; i++ ) {

		var boxTypeItem = this.boxTypes[i];

		if (boxTypeItem.name == boxType) {

			boxTypeItem.state = newState;

			break;

		}

	}

}



BoxController.prototype.expandOrCollapse = function( headerElement, boxType ) {

	// Note: Having one routine for both expand and collapse let's the function that html calls be the same

	// Uses img's src attribute to determine which command is being called

	// First get the button element; may be the elementActivated or within the elementActivated (like an anchor element)

	var buttonElement = getFirstDescendentOrSelfOfClass ( headerElement, "expandOrCollapseButton");

	if (!buttonElement) return;

		

	var currentImageUrl = buttonElement.src;

	if (!currentImageUrl) return;



	// if src value contains url of collapse button, this is, presumably a collapse command

	var newState = false;

	if (currentImageUrl.lastIndexOf(this.collapseButtonUrl)==-1) newState = true;

	

	// change state of all boxes of this type ...

	if (this.changeAllOfType) {

		this.changeStateOfAllBoxesOfType (boxType,newState);

		this.saveStateToCookie();

	}

	// or just this one box

	else {

		var boxElement = headerElement.parentNode;

		if (boxElement) this.changeStateOfBoxOnPage(boxElement,newState);

	}

	

}



BoxController.prototype.changeStateOfBoxOnPage = function( boxElement, makeOpen) {

	// change UI of box on the html page

	

	// get button element

	var buttonElement = getFirstDescendentOrSelfOfClass( boxElement, "expandOrCollapseButton");

	if (!buttonElement) return false; // if not found, give up

	// get body element

	var bodyElement = getFirstDescendentOrSelfOfClass( boxElement, "body");

	if (!bodyElement) return false; // if not found, give up

	

	// expand or collapse body element

	showOrHideElement(bodyElement,makeOpen);

	

	// update img to be an appropriate button

	if (buttonElement.src) {

		// if opening, make it the collapse button; if not opening, make it the expand button

		buttonElement.src = makeOpen ? this.collapseButtonUrl : this.expandButtonUrl;

	}

}



