/******************************************************************************
 The DM Object v1.6
 
 The DM Object inspired by SI Object (http://www.shauninman.com/).
 
 Stores a variety of functions localized to modules. Any module that requires
 initialization onload should have an onload handler. The DM.onload method will
 loop through all modules and run their respective onload handler. DM.onload
 can then be called in the window.onload event handler and all modules requiring
 initialization will be initialized. Does the same for onbeforeload and unload.
 
 v1.0 : Initial creation
 v1.1 : Added SideNav module
 v1.2 : Added Class, DynamicMap, EventsCalendar and FadeAnything modules
 v1.3 : Added SolutionFeatures module
 v1.4 : Added ParseLinks module
 v1.5 : Removed modules not needed for this site
 v1.6 : Added ImageFader module
 
 ******************************************************************************/

if (!DM) { var DM = new Object(); };
DM.hasRequired 	= function() {
	if (document.getElementById && document.getElementsByTagName) {
		var html = document.getElementsByTagName('html')[0];
		html.className += ((html.className=='')?'':' ')+'has-dom';
		return true;
	};
	return false;
}();
DM.onbeforeload	= function() { if (this.hasRequired) { for (var module in this) { if (this[module].onbeforeload) { this[module].onbeforeload();	};};};};
DM.onload		= function() { if (this.hasRequired) { for (var module in this) { if (this[module].onload) { this[module].onload(); };};};};
DM.onunload		= function() { if (this.hasRequired) { for (var module in this) { if (this[module].onunload) { this[module].onunload(); };};};};


/******************************************************************************
 DM.SimulateSelectors module v1.3
 
 Adds CSS :first/last-child support for IE via classnames to unordered lists.
 
 v1.0 : Initial creation
 v1.1 : Added span with 'before' class and a pipe character and space list items
        in the footer element's list. Mimmicks the li's :before selector and the
        'content' property.
 v1.2 : Added more complete support for :before/after pseudo selectors including
        getting the content property from the stylesheet.
 v1.3 : Made the regular expression to find the content of the "content" property
        lazy instead of greedy. Should prevent problems finding the real content.
 
 ******************************************************************************/
DM.SimulateSelectors = {
	onbeforeload		: function() {
		if (document.all) {
			var lists = document.getElementsByTagName('ul');
			
			for (var i=0; list=lists[i]; i++) {
				for (j=0; listItem=list.childNodes[j]; j++) {
					if (listItem.nodeName != 'LI') { continue; };
					if (j==0) { listItem.className += ((listItem.className=='')?'':' ')+'first'; };
					if (j==list.childNodes.length-1) { listItem.className += ((listItem.className=='')?'':' ')+'last'; };
				};
			};
			
			
			if (document.styleSheets) {
				var sheets = document.styleSheets, sl = sheets.length;
				
				for (var i=0; i<sl; i++) {
					var sheet = sheets[i];
					var rules = (currentSheet = sheet).rules, rl = rules.length;
					
					for (var j=0; j<rl; j++) {
						var rule = rules[j];
						var select = rule.selectorText, style = rule.style.cssText.replace(/; /g, ';\n') + ';', styleArr = style.split('\n'), sal = styleArr.length;
						
						if (style.indexOf('content:')!=-1 && select.indexOf('.clearfix')==-1) {
							for (var k=0; k<sal; k++) {
								if (styleArr[k].indexOf('content:')!=-1) {
									var content = styleArr[k].replace(/content: "([^"]+?)";/, '$1');
									var affected = select.replace(/:(hover|active|unknown).*$/, '');
									var elements = this.getElementsBySelect(affected);
									
									for (var l=0; element=elements[l]; l++) {
										var b = document.createElement('span');
										b.className	= (select.indexOf('#footer')!=-1)?'before':'after';
										b.innerHTML	= content;
										if (b.className=='before') {
											element.insertBefore(b, element.firstChild);
										} else {
											element.appendChild(b);
										};
									};
								};
							};
						};
					};
				};
			};
		};
	},
	getElementsBySelect	: function (rule) {
		var parts, nodes = [document];
		parts = rule.split(' ');
		
		for (var i=0; i<parts.length; i++) {
			nodes = this.getSelectedNodes(parts[i], nodes);
		};
		
		return nodes;
	},
	getSelectedNodes	: function (select, elements) {
		var result, node, nodes = [];
		var identify = (/\#([a-z0-9_-]+)/i).exec(select);
		
		if (identify) {
			var element = document.getElementById(identify[1]);
			return element? [element]:nodes;
		};
		
		var classname = (/\.([a-z0-9_-]+)/i).exec(select);
		var tagName = select.replace(/(\.|\#|\:)[a-z0-9_-]+/i, '');
		var classReg = classname? new RegExp('\\b' + classname[1] + '\\b'):false;
		
		for (var i=0; i<elements.length; i++) {
			result = tagName? elements[i].all.tags(tagName):elements[i].all;
			for (var j=0; j<result.length; j++) {
				node = result[j];
				if (classReg && !classReg.test(node.className)) { continue; };
				nodes[nodes.length] = node;
			};
		};
		
		return nodes;
	}
};
	
	
/******************************************************************************
 DM.PrintWindow module v1.0
 
 ******************************************************************************/
DM.PrintWindow = function() {
	window.print?window.print():alert('Your browser doesn\'t support this funtion. Please select \'File > Print\' from your browser\'s menu to print this page.');
};
	
	
/******************************************************************************
 DM.Class module v1.0
 
 Provides helper functions for adding/removing/testing for classes.
 
 ******************************************************************************/
DM.Class = {
	add		: function (obj,cName) { this.kill(obj,cName); return obj && (obj.className+=(obj.className.length>0?' ':'')+cName); },
	kill	: function (obj,cName) { return obj && (obj.className=obj.className.replace(new RegExp("^"+cName+"\\b\\s*|\\s*\\b"+cName+"\\b",'g'),'')); },
	has		: function (obj,cName) { return (!obj || !obj.className)?false:(new RegExp("\\b"+cName+"\\b")).test(obj.className) }
};


/******************************************************************************
 DM.ImageFader module v1.0
 
 Cycles through image sets based on their rel attrributes using a fade
 transition.
 
 v1.0 : Initial creation
 
 ******************************************************************************/
DM.ImageFader = {
	imgs			: [],
	interval		: 2000,
	stepsize		: .05,
	current			: 0,
	crossfade		: function () {
		var cOpacity = DM.ImageFader.imgs[DM.ImageFader.current].xOpacity;
		var nIndex = DM.ImageFader.imgs[DM.ImageFader.current+1] ? DM.ImageFader.current + 1 : 0;
		var nOpacity = DM.ImageFader.imgs[nIndex].xOpacity;
		
		cOpacity-=DM.ImageFader.stepsize; 
		nOpacity+=DM.ImageFader.stepsize;
		
		if (DM.ImageFader.imgs[DM.ImageFader.current+1]) {
			DM.ImageFader.imgs[DM.ImageFader.current].style.position = 'absolute';
			DM.ImageFader.imgs[nIndex].style.position = 'relative';
		};
		DM.ImageFader.imgs[nIndex].style.display = 'block';
		DM.ImageFader.imgs[DM.ImageFader.current].xOpacity = cOpacity;
		DM.ImageFader.imgs[nIndex].xOpacity = nOpacity;
		
		DM.ImageFader.setopacity(DM.ImageFader.imgs[DM.ImageFader.current]); 
		DM.ImageFader.setopacity(DM.ImageFader.imgs[nIndex]);
		
		if (cOpacity<=0) {
			DM.ImageFader.imgs[DM.ImageFader.current].style.display = 'none';
			if (!DM.ImageFader.imgs[DM.ImageFader.current+1]) {
				DM.ImageFader.imgs[DM.ImageFader.current].style.position = 'absolute';
				DM.ImageFader.imgs[nIndex].style.position = 'relative';
			};
			DM.ImageFader.current = nIndex;
			setTimeout(DM.ImageFader.crossfade, DM.ImageFader.interval);
		} else {
			setTimeout(DM.ImageFader.crossfade, 50);
		};
		
	},
	setopacity		: function (obj) {
		if (obj.xOpacity>.99) {
			obj.xOpacity = .99;
			return;
		};
		obj.style.opacity = obj.xOpacity;
		obj.style.MozOpacity = obj.xOpacity;
		obj.style.filter = 'alpha(opacity=' + (obj.xOpacity*100) + ')';
	},
	onbeforeload	: function () {
		if (!document.getElementsByTagName) { return; };
		
		for (i=0; img=document.getElementsByTagName('img')[i]; i++) {
			if (!DM.Class.has(img, 'imagefader')) { continue };
			this.imgs[this.imgs.length] = img;
		};
		
		for (i=0; i<this.imgs.length; i++) {
			this.imgs[i].xOpacity = 0;
			this.imgs[i].style.position = 'absolute';
			this.imgs[i].style.display = 'none';
		};
		
		if (this.imgs.length>0) {
			this.imgs[0].style.position = 'relative';
			this.imgs[0].style.display = 'block';
			this.imgs[0].xOpacity = .99;
			if (this.imgs.length>1) { setTimeout(DM.ImageFader.crossfade, DM.ImageFader.interval); };
		};
	}
};



/******************************************************************************
 window.onload/onunload()
 
 This should only ever require DM.onload()/onunload() which in turn initialises
 all modules that require it.
 
 ******************************************************************************/
window.onload	= function() { DM.onload(); };
window.onunload	= function() { DM.onunload(); };
