/**
 * This is a collection of namespaces for the JavaScript we are using in 
 * our various applications.  This is especially useful with Harris Web 
 * Templates.
 * 
 * I am converting all current scripts to namespaces in order to avoid 
 * future conflicts with Harris development.
 * 
 * Current namespaces:
 *  AYA - scripts for AYA services
 *  AYA.Harris - hacks on Harris Services
 *  AYA.Harris.WT - script specific to Webtemplates, not likely usable outside of this service
 *  DPC - Used for my specfici hacks
 * 	DPC.AJAX - cross browswer AJAX initialization scripts 
 *  DPC.Debug - debuging scripts for Web site development
 *  DPC.Call - These are the scripts used to initiate a process. 
 * 				These are the only links that should be called 
 * 				from the page.
 *  DPC.Hacks - simple reusable used code.
 *
 **/

/// Create the Namespace Manager that we'll use to
/// make creating namespaces a little easier.
if (typeof Namespace == 'undefined') var Namespace = {};
if (!Namespace.Manager) Namespace.Manager = {};

Namespace.Manager = {
	Register : function(_Name) {
        var chk = false;
        var cob = "";
        var spc = _Name.split(".");
        for(var i = 0; i<spc.length; i++) {
            if(cob!=""){cob+=".";}
            cob+=spc[i];
            chk = this.Exists(cob);
            if(!chk){this.Create(cob);}
        }
        if(chk) { throw "Namespace: " + _Name + " is already defined."; }
    },

    Create : function(_Src) {
        eval("window." + _Src + " = new Object();");
    },

    Exists : function(_Src) {
        eval("var NE = false; try{if(" + _Src + "){NE = true;}else{NE = false;}}catch(err){NE=false;}");
        return NE;
    }
};

/// Declaring the namespaces needed for our project
Namespace.Manager.Register('AYA.Harris.WT');
Namespace.Manager.Register('DPC.Hacks'); /// creates both DPC and DPC.Hacks NS's

AYA.Harris.WT.UniLinks = function(){
	
	var xmlContainer; /// Holds the xml object
	var topMenu; /// The top menu's div
	var bottomMenu; /// the bottom menu's div
	
	/** event handler for XMLHttpRequest */
	this.handleResponse=function(){
		if(DPC.Call.request.readyState == 4){
			if(DPC.Call.request.status == 200){
				xmlContainer = DPC.Call.request.responseXML;
				selectDiv();
				buildNav();
			} else {
				alert("A problem occurred with communicating between the XMLHttpRequest object and the server program.");
			}
		}
	}
	
	function evalGroup(groupType) {
		var groups = DPC.Call.groupID.split(",")
		var i = 0;
		var displayItem = false;
		while(i<groups.length && !displayItem) {
			if(groups[i]==groupType) {
				displayItem="yes";
				i++;
			} else {
				i++;
			}
		}
		return displayItem;
	}
	
	function selectDiv(){		
		/** Find the proper Div's
		 *  Sets the  variable; 
		 * This is done by:
		 * 1. Selecting the div by ID, if an ID is given
		 * 2. Running through all the Div's on the page and 
		 * selecting the one with the matching class. 
		 * 
		 * This is a dirty hack but should work.
		 **/
		if(!DPC.Call.divID) {
			var allDivElements = window.document.getElementsByTagName("div");
			for (var n=0;n<allDivElements.length;n++) {
				// var classValueIs = allDivElements[n].getAttribute('class',2);
				var classValueIs = allDivElements[n].className;
				if (classValueIs == DPC.Call.divClass) {
					topMenu = allDivElements[n];
				} else if(classValueIs == DPC.Call.divClass2) {
					bottomMenu = allDivElements[n];
				}
			}
		} else {
			alert('in else');
			topMenu = window.document.getElementById(DPC.Call.divClass);
			bottomMenu = window.document.getElementById(DPC.Call.divClass2);
		}
	}
	
	/** This will actually construct the menu and send it out to the document */
	function buildNav() {
		/// collects all the "Menu" elements in the XML file and puts them in a schema named menus
		var menus=xmlContainer.getElementsByTagName("Menu"); 
		
		/// loop through the menu elements
		for (i=0;i<menus.length;i++) { 
			
			/// This variable grabs the 'nav' attribute of the current Menu
			var menuNav = menus[i].attributes.getNamedItem("nav").nodeValue;
			var message = "";
			var menuEnd = "";
			
			/// linkEle collects the 'lineTag' elements in the menu
			linkEle=menus[i].getElementsByTagName("lineTag");
				
			/// here we loop through the 'lineTag' Child elements 
			for (z=0;z<linkEle.length;z++) {

				/// container variables used in the next loop to create the links from y
				var msgFront = "";
				var msgEnd = "";
				var groupType = linkEle[z].attributes.getNamedItem("group").nodeValue;
				var displayItem = evalGroup(groupType); /// determines if a link should be displayed
				
				if (groupType=="all"||displayItem){
					var typeLink = linkEle[z].attributes.getNamedItem("type").nodeValue;
					var linkAttr=linkEle[z].childNodes;					
					
					if(linkEle[z].getElementsByTagName("label")[0].childNodes[0]) {
						var label=linkEle[z].getElementsByTagName("label")[0].childNodes[0].nodeValue;
					} else { 
						var label="";
					}
						
					/// Loop through the link attributes
					for (t=0;t<linkAttr.length;t++){
						/// The first 'if' is for Mozzilla browswers that see space as an element
						if(linkAttr[t].childNodes[0]){
							if (linkAttr[t].nodeName=="tag") {
								msgFront = "<"+linkAttr[t].childNodes[0].nodeValue+" ";
								msgEnd = "</"+linkAttr[t].childNodes[0].nodeValue+">";
							} else if (linkAttr[t].nodeName!="label") {
								msgFront += linkAttr[t].nodeName+'="'+linkAttr[t].childNodes[0].nodeValue+'" '; 
							}
						}
					} 
					if(typeLink=="container") {
						message += msgFront+">"+label;
						menuEnd += msgEnd;
					} else {
						message += msgFront+">"+label+msgEnd;
					}
				}
			}
			/// This 'if' determines which Menu should be populated based on it's 'nav' attribute
			if(menuNav==DPC.Call.divClass){
				topMenu.innerHTML += message+menuEnd;;
			} else if(menuNav==DPC.Call.divClass2) {
				bottomMenu.innerHTML += message+menuEnd;
			} else { 
				alert("An error has occured in constructing the Menu.  Please try again later");
			}	
		}
	}	
}

DPC.AJAX = function() {
	
	/** This is our compatibility checker for XML request
 	* 
 	* This is also a priveledged method, meaning it can be called from
	* outside this namespace and can read the private classes and 
	* methods of this namespace.
	* 
 	* Wrapper function for constructing a request object.
 	* Parameters:
 	*	reqType: the HTTP request type, suc as GET or POST.
 	*	url: the URL of the server program.
 	*	asynch: wheter to send the request ashnchronously or not.
 	**/ 	
	this.httpRequest = function(reqType,url,asynch,respHandle) {
		///Mozilla-based browsers
		if(window.XMLHttpRequest){
			DPC.Call.request = new XMLHttpRequest();
		} else if (window.ActiveXObject) {
			/// IE browsers
			DPC.Call.request = new ActiveXObject("Msxml2.XMLHTTP");
			if (! DPC.Call.request) {
				DPC.Call.request = new ActiveXObject("Microsoft.XMLHTTP");
			}
		}
		///the request could still be null if neither ActiveXObject initialization succeeded
		if(DPC.Call.request) {
			if(reqType.toLowerCase() != "post"){
				initReq(reqType,url,asynch,respHandle);
			} else {
				///the POSTed data
				var args = arguments[4];
				if(args != null && args.length > 0){
					initReq(reqType,url,asynch,respHandle,args);
				}
			}
		} else {
			alert("Your browser does not permit the use of all of this Website's features");
		}
	}
	
	/** Initialize a request object that is already constructed 
	 * This is a private function and can only be called from within
	 * this namespace
	 **/ 
	function initReq(reqType,url,bool,respHandle,args) {
		try {
			/// Specify the function that will handle the HTTP reponse 
			DPC.Call.request.onreadystatechange=respHandle;
			DPC.Call.request.open(reqType,url,bool);
			
			if(reqType.toLowerCase() != "post"){
				DPC.Call.request.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8");
				DPC.Call.request.send(args);
			} else {
				DPC.Call.request.send(null);
			}
		} catch (errv) {
			alert("The application cannot contact the server at the moment. Please try again in a view seconds."+"Error detail: "+errv.message);
		}
	}

}

DPC.Debug = {
 
 /** 
  * monitorMsgs funcntion will insert messages into the HTML page to help 
  * debug and track the javascript code. I use it primarily to track
  * where I am in the JS file.
  * 
  * newMsg = the message you would like printed
  * requires a div in the html page with id="catchMsgs"
  * <div id="catchMsgs"></div>
  * 
  * DPC.Debug.monitorMsgs("insert messages here");
  *
  */
  monitorMsgs:function(newMsg) {
 	window.document.getElementById("catchMsgs").innerHTML+=newMsg+"<br />";
  }

};

DPC.Call = {
	request:null,
	divClass:'lmenu_col',
	divClass2:'lmenu_col2',
	divID:null,
	groupID:null,
	
	InitNav:function(group,_URL,divID) {
		var myNavRequest = new DPC.AJAX;
		var ayaHarris = new AYA.Harris.WT.UniLinks;
		this.divID = divID;
		this.groupID = group;
		myNavRequest.httpRequest("GET",_URL,true,ayaHarris.handleResponse);
	}
};

DPC.Hacks.ExMenu = {
	/**
	 * These functions will expand the Div's related to the Local Chapters for SIGS.  
	 * These functions should be able to expand any div 
	 * given the proper coding: 
	 * divToEffect needs to be the element ID that you want to expand or collapse, 
	 * currently all class information for the div will be reset.
	 **/

	expandDiv: function(divToEffect){
		var divToExpand = document.getElementById(divToEffect);
		divToExpand.setAttribute("class","showAll");
		divToExpand.setAttribute("className","showAll");
	},
		
	collapseDiv: function(divToEffect){
		var divToCollapse = document.getElementById(divToEffect);
		divToCollapse.setAttribute("class","hideAll");
		divToCollapse.setAttribute("className","hideAll");
	},
		
	/**
	 * this is a test function to ensure the 'lastSibling' DOM works properly in FF
	 * check if the last sibling node is an element node 
	 **/
	check_lastSibling: function(nodeTest, funcToCall) {
		var x=nodeTest
		while (x.nodeType!=1) {
			x=x.previousSibling;
		}
		if (funcToCall=="1"){
			this.expandDiv(x.id);
		} else {
			this.collapseDiv(x.id)
		}
	},

	getElementPosition: function(theElement){
		var posX = 0;
		var posY = 0;	  
		while(theElement != null){
			posX += theElement.offsetLeft;
			posY += theElement.offsetTop;
			theElement = theElement.offsetParent;
		}
	   return {x:posX,y:posY};
	},

	setPosition: function(divToEffect,parElem) {
		var setDivPos = document.getElementById(divToEffect);
		var parDiv = document.getElementById(parElem);
		var pos = this.getElementPosition(parDiv);
		setDivPos.style.top = pos.y+"px";
		setDivPos.style.left =parDiv.offsetWidth + "px"; 
		this.expandDiv(divToEffect);
	}
}

/* --------------- Remove after complete upgrade ------------------ */


/* -----------------------BEGIN EXPANDING DIVS -----------------------------*/

/**
 * These functions will expand the Div's related to the Local Chapters for SIGS.  
 * These functions should be able to expand any div 
 * given the proper coding: 
 * divToEffect needs to be the element ID that you want to expand or collapse, 
 * currently all class information for the div will be reset.
 **/

function expandDiv(divToEffect){
	var divToExpand = document.getElementById(divToEffect);

	divToExpand.setAttribute("class","showAll");
	divToExpand.setAttribute("className","showAll");
	}

function collapseDiv(divToEffect){
	var divToCollapse = document.getElementById(divToEffect);
	
	divToCollapse.setAttribute("class","hideAll");
	divToCollapse.setAttribute("className","hideAll");
	}
	
/**
 * this is a test function to ensure the 'lastSibling' DOM works properly in FF
 * check if the last sibling node is an element node 
 **/

function check_lastSibling(nodeTest, funcToCall) {
	var x=nodeTest
	while (x.nodeType!=1) {
		x=x.previousSibling;
	}

	if (funcToCall=="1"){
		expandDiv(x.id);
	} else {
		collapseDiv(x.id)
	}
}

function getElementPosition(theElement){

  var posX = 0;
  var posY = 0;
              
  while(theElement != null){
    posX += theElement.offsetLeft;
    posY += theElement.offsetTop;
    theElement = theElement.offsetParent;
  }
       		      
   return {x:posX,y:posY};

}

function setPosition(divToEffect,parElem) {
	var setDivPos = document.getElementById(divToEffect);
	var parDiv = document.getElementById(parElem);
	var pos = getElementPosition(parDiv);
	
	setDivPos.style.top = pos.y+"px";
	setDivPos.style.left =parDiv.offsetWidth + "px"; 

	expandDiv(divToEffect);
}

/* ------------------------ END EXPANDING DIVS -------------------------*/

