/* ______________________[ Plan du site ]________________________ */

/*	(c) Remy@Smart, pour Smart Agence, 2007 - Global object managing a sitemap with clicks 
	includes functions from Stuart Langridge "aqlist"s
*/

/* SiteMap manager object, JSON-style */
var siteMapManager = {
	/* some vars*/
	siteMapManagerVersion: "1.0",
	sSiteMapID: "",	//SiteMap container
	bUseToggleSwitch: false,	// use toggle switch ?
	aTargets: [],	// shown / hidden sublists
	sTreeClass: "treeview",		// default tree classes
	sNormalClass: "aq3bullet",	
	sClosedClass: "aq3closed",
	sOpenedClass: "aq3open",
	bIsOK: false,	// flag : does the sitemap container exist in the documen ? (default : false)
	// initialization function
	initialize: function(sID,bUseToggle) {
		// setting some object vars from the parameters
		this.sSiteMapID = sID;
		this.bUseToggleSwitch = bUseToggle;
		// let's make sure the element with "siteMapID" id exists in the document
		if(document.getElementById(sID)) {
			this.bIsOK = true;
			if(bUseToggle) {
				this.addToggleSwitch();
			}
			if(this.initialize.arguments.length > 2){
				this.sTreeClass = this.initialize.arguments[2];
				this.sNormalClass = this.initialize.arguments[3];
				this.sClosedClass = this.initialize.arguments[4];
				this.sOpenedClass = this.initialize.arguments[5];
			}
		}
		return this;
	},
	// (un)activate the toggle switch link
	setToggleSwitch: function(bValue) {
		this.bUseToggleSwitch = bValue;
	},
	/*
		Notice : the 3 next methods are initially derived from aqtree3clickable.js. Converts an unordered list to an explorer-style tree, with clickable icons.
		See http://www.kryogenix.org/code/browser/aqlists/ for more details.
		This is, here, an integration to our SiteMapManager JSON object
	*/
	makeTreesC: function() {
			if(this.bIsOK) {
			 // We don't actually need createElement, but we do
			// need good DOM support, so this is a good check.
				if (document.createElement){
					aUL=document.getElementById(this.sSiteMapID).getElementsByTagName("UL");
					for (index=0;index<aUL.length;index++) {
						if (aUL[index].nodeName=="UL" && aUL[index].className==this.sTreeClass) {
						this.processUL(aUL[index]);
					}
				}
			}
		}
		return this;
	},
	processUL: function(oUL) {
	    if (oUL.childNodes && oUL.childNodes.length > 0) {
			// Iterate LIs
			for (var index=0;index<oUL.childNodes.length;index++) {
				var oItem = oUL.childNodes[index];
				if (oItem.nodeName=="LI") {
					// Iterate things in this LI		
					/* Note :
					   We MUST initialize these vars to "null", otherwise a strange bug accurs : if a <li> element, not containing any <ul> sublist, follows a <li> containing a <ul>, it's treated as having a sub-list.
					   Setting these vars to "null" helps resolving the bug.
					*/
					var oLink = null;
					var oChildUL = null;
				
					for(var index2=0;index2<oItem.childNodes.length;index2++) {
						var oSubItem = oItem.childNodes[index2];
						switch (oSubItem.nodeName) {
							case "A":
								oLink = oSubItem; 
							break;
							case "UL":
								/*in case of a UL list, we store it in an associative array
								  principle :
								  aTarget[parentID] = theSubList;
								*/
								oChildUL = oSubItem;
								oChildUL.parentNode.setAttribute("id","smartMap_"+this.getRandomID("smartMap_",2));
								this.aTargets[oItem.id] = oItem.removeChild(oChildUL);
								// recursive traversing
								this.processUL(oChildUL);
							break;
						}
					}
					/*
					  if list => associate link and list and set active classes to the link's parent
					  if link and no list => add normal class to the link				
					*/
					if(oChildUL) {;
						this.associateToList(oLink);
					}
					else {
						oLink.parentNode.className=this.sNormalClass;
					}
				}
			}
		}
	},
	associateToList: function(oLink) {
		if (oLink.parentNode.className.indexOf(this.sOpenedClass)==-1){
			oLink.parentNode.className=this.sClosedClass;
			this.SmartOpenClose2(oLink.parentNode);
		}
	},
	/* ---------------------- Next functions are custom ones ---------------------- */
	// Manage (un)folding of a list
	SmartOpenClose2: function(oListItem) {
		// HTML string of the element enabling folding/unfolding
		sOpenClose='<a class="open_close" href="javascript:;" title="Afficher le sous niveau"><span class="fx">[Afficher le sous-niveau]</span>&nbsp;</a>'+' '+oListItem.innerHTML;
		oListItem.innerHTML = sOpenClose;
		if (oListItem.firstChild && oListItem.firstChild.className=="open_close") {
			oListItem.firstChild.onclick = oListItem.firstChild.onkeypress = function(event) {
				// keyboard
				var oEvent = (window.event ? window.event : event);
				var bKeyBoardUsed = (oEvent.type == "keypress" ? true : false);
				var iTouche = -1;
				
				if(bKeyBoardUsed) {
					iTouche = (window.event ? window.event.keyCode : oEvent.which);
				}
					
				// mouse used, or keyboard with "space" key ?
				if(bKeyBoardUsed == false || (bKeyBoardUsed == true && iTouche == 32)) {
					// getting the span.fx element
					oFXSpan = oListItem.firstChild.firstChild;
					if(oListItem.lastChild.nodeName == "UL") {
						// Unfolding : removing the sublist from the DOM
						oListItem.removeChild(oListItem.lastChild);
						oListItem.className = siteMapManager.sClosedClass;
						oListItem.firstChild.setAttribute('title','Afficher le sous niveau');
					}
					else {
						// Folding : inserting the related sublist as last child of its parent
						oListItem.appendChild(siteMapManager.aTargets[oListItem.id]);
						oListItem.className = siteMapManager.sOpenedClass;
						oListItem.firstChild.setAttribute('title','Masquer le sous niveau');
					}
					oFXSpan.innerHTML = (oListItem.className == siteMapManager.sOpenedClass ? "[Masquer le sous-niveau]":"[Afficher le sous-niveau]");
				}
			};
		}
	},
	/* Add a "toggle" link for all lists (not functional yet) */
	addToggleSwitch: function() {
		if(document.createElement && document.getElementById) {
			// nothing special : DOM manipulation on elements
			var oP = document.createElement("P");
			var oLink = document.createElement("A");
			var oLink_content = document.createTextNode("Show all");
			var oParent = document.getElementById("ColContenu");
			var oBefore;
			// make sure all elements do exist in the document
			if(oParent){
				oBefore = document.getElementById(this.sSiteMapID);
				// Setting Paragraph attributes
				oP.setAttribute("id","toggle");
		
				// Setting Link attributes
				oLink.href="javascript:;";
				oLink.className="toggle_unfold_all";
				// we also manage keyboard to show/hide lists (space-key used)
				oLink.onclick = oLink.onkeypress = function(event){
					// keyboard
					var oEvent = (window.event ? window.event : event);
					var bKeyBoardUsed = (oEvent.type == "keypress" ? true : false);
					var iTouche = -1;
					
					if(bKeyBoardUsed) {
						iTouche = (window.event ? window.event.keyCode : oEvent.which);
					}
					
					// mouse used, or keyboard with "space" key ?
					if(!bKeyBoardUsed || (bKeyBoardUsed && iTouche == 32)) {
						// référence au LIEN
						siteMapManager.toggleLists(this);
						switch(this.className) {
							case "toggle_unfold_all":
								this.innerHTML = "Hide all";
								this.className = "toggle_fold_all";
							break;
							case "toggle_fold_all":
								this.innerHTML = "Show all";
								this.className = "toggle_unfold_all";
							break;
						}
						
					}
				};
				// inserting the toggle element
				oLink.appendChild(oLink_content);
				oP.appendChild(oLink);
				oParent.insertBefore(oP,oBefore);
			}
		}
		return false;
	},
	toggleLists: function(oToggleSwitch) {
		if(document.createElement && document.getElementById) {
			var oPlanSite = document.getElementById(this.sSiteMapID);
			var aElements = oPlanSite.getElementsByTagName("LI");
			for(var i = 0; i < aElements.length; i++) {
				if(aElements[i].id) {
					// (re)plier (fold)
					switch(oToggleSwitch.className) {
						case "toggle_fold_all":
							if(aElements[i].lastChild.nodeName == "UL") {
								aElements[i].removeChild(aElements[i].lastChild);
								aElements[i].className = this.sClosedClass;
							}
						break;
						case "toggle_unfold_all":
							aElements[i].appendChild(this.aTargets[aElements[i].id]);
							aElements[i].className = this.sOpenedClass;
						break;
					}
				}
			}
		}
	},
	/* Returns a UNIQUE random ID. Method checks itself whether the generated ID is unique or not, and re-generate it if needed */
	getRandomID: function(sPrefix,iLength) {
		var sChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
		var sRandomID = "";
		var iLength = (iLength > 0 ? iLength : 1);
		do {
			for(var x=0;x<iLength;x++) {
				var i = Math.floor(Math.random() * 62);
				sRandomID += sChars.charAt(i);
			}
			sRandomID = sPrefix+sRandomID;
		} while (document.getElementById(sRandomID));
		return sRandomID;
	}
};

