/*
	main.js
		- Utility Functions
		- Browser Detections
		- Navigation Class
		- Text Field Blank Class	
*/

/*
	Global Varuiables
*/
var badBrowserLocation = "/BadBrowser/index.htm";
var badBrowserMessage  = "It looks like your browser isn't supported by our website,\nYou will be redirected to our 'browser support page'\nwith information on which browsers we support.";

/*  *******************************************************************************************************************
	Utility Functions
*/
function isPrototype () {
  if ( typeof(Prototype) != 'undefined' && typeof(Class) && typeof($A) != 'undefined' ) { return true; }
  else { return false; }
}
function isW3CDOM () {
  var W3CDOM = ( document.createElement && document.getElementsByTagName );
  if ( !W3CDOM ) { return false; }
  else { return true; }
}
/*
	Function: nodeDepth
		Find the depth of an html element
		
	Returns:
		depth:int
*/
function nodeDepth( elem, tag ) {
	var nested = elem.getElementsByTagName(tag);
	var allcount = 0;
	for ( var i = 0,j = nested.length; i < j; i++ ) {
		var count = 1;
		var kid = nested[i].getElementsByTagName(tag)[0];
		while ( kid!=undefined && kid!='NULL' ) {
			count++;
			kid = kid.getElementsByTagName( tag )[0];
		}
		if( count > allcount ) { allcount = count; }
	}
	return allcount;
}
/*
	Function: popUp
		Launches a popup window
	
	Arguments:
		URL - target href location to open
		pop_h (optional) - desired height of popup window
*/
function popUp( URL, pop_h ) {
  pop_w = 625;
  pop_h = pop_h ? pop_h : 485;

  day = new Date();
  id = day.getTime();
  eval("page" + id + " = window.open(URL, '" + id + "', 'toolbar=0,scrollbars=1,location=0,statusbar=0,menubar=1,resizable=1,width=" + pop_w + ",height="+ pop_h +"');");
}
/*
	Object: BrowserDetect
		Contains information about client browser
		Contains methods that compare client browser against badBrowsers array
		If client browser is a 'badBrowser' redirect
		
	Credits:
		http://www.quirksmode.org/js/detect.html
*/
//var badBrowser = false;
var badBrowserChecked = false;
var BrowserDetect = {
	init: function () {
		this.browser = this.searchString(this.dataBrowser) || "An unknown browser";
		this.version = this.searchVersion(navigator.userAgent)
			|| this.searchVersion(navigator.appVersion)
			|| "an unknown version";
		this.OS = this.searchString(this.dataOS) || "an unknown OS";
		this.compare();
	},
	searchString : function (data) {
		for (var i=0;i<data.length;i++)	{
			var dataString = data[i].string;
			var dataProp = data[i].prop;
			this.versionSearchString = data[i].versionSearch || data[i].identity;
			if (dataString) {
				if (dataString.indexOf(data[i].subString) != -1)
					return data[i].identity;
			}
			else if (dataProp)
				return data[i].identity;
		}
	},
	searchVersion : function (dataString) {
		var index = dataString.indexOf(this.versionSearchString);
		if (index == -1) return;
		return parseFloat(dataString.substring(index+this.versionSearchString.length+1));
	},
	compare : function () {
		
		//alert(BrowserDetect.OS + ', ' + BrowserDetect.browser + ", Version " + BrowserDetect.version);
		
		var badBrowser = false;
		
		for (i = 0; i < this.badBrowsers.length; i++) {
			var b = false;
			var v = false;
			var o = false;
			
			if (BrowserDetect.browser.match(this.badBrowsers[i].browser) || this.badBrowsers[i].browser == "all") {
				b = true;
			}
			if (BrowserDetect.OS.match(this.badBrowsers[i].OS) || this.badBrowsers[i].OS == "all") {
				o = true;
			}
			// test the browser version number
			reg = new RegExp(/[\<\>]=?\d/);
			
			if (reg.match(this.badBrowsers[i].version)) {
				if (eval( BrowserDetect.version + this.badBrowsers[i].version )) {
					v = true;
				}
			} else {
				if (BrowserDetect.version == this.badBrowsers[i].version || this.badBrowsers[i].version == "all") {
					v = true;
				}
			}
			if (b == true && v == true && o == true) {
				badBrowser = true;
				i = this.badBrowsers.length;
			}
		}
		
		if ( badBrowser ) { 
			this.redirect();
		}
		
	},
	redirect : function () {
		if (!window.location.href.match(badBrowserLocation.split('/')[1])) {
			alert(badBrowserMessage);
			window.location = badBrowserLocation;
		}
	},
	dataBrowser: [
		{ 	string: navigator.userAgent,	subString: "OmniWeb",	versionSearch: "OmniWeb/",	identity: "OmniWeb"		},
		{	string: navigator.vendor,		subString: "Apple",		identity: "Safari" 			},
		{	prop: window.opera,				identity: "Opera"		},
		{	string: navigator.vendor,		subString: "iCab",		identity: "iCab" 			},
		{	string: navigator.vendor,		subString: "KDE",		identity: "Konqueror" 		},
		{	string: navigator.userAgent,	subString: "Firefox",	identity: "Firefox"			},
		{	string: navigator.vendor,		subString: "Camino",	identity: "Camino"			},
			// for newer Netscapes (6+)
		{	string: navigator.userAgent,	subString: "Netscape",	identity: "Netscape"		},
		{	string: navigator.userAgent,	subString: "MSIE",		identity: "Explorer",		versionSearch: "MSIE"	},
		{	string: navigator.userAgent,	subString: "Gecko",		identity: "Mozilla",		versionSearch: "rv"		},
			// for older Netscapes (4-)
		{ 	string: navigator.userAgent,	subString: "Mozilla",	identity: "Netscape",		versionSearch: "Mozilla"}
	],
	dataOS : [
		{	string: navigator.platform,		subString: "Win",	identity: "Windows"	},
		{	string: navigator.platform,		subString: "Mac",	identity: "Mac" 	},
		{	string: navigator.platform,		subString: "Linux",	identity: "Linux"	}
	],
	badBrowsers : [
		{ 	browser: "Explorer",	version: "<6",		OS: "all"	},
		{ 	browser: "Opera",		version: "<9",		OS: "all"	},
		{ 	browser: "Netscape",	version: "<9",		OS: "all"	}
	]

};
/*  *******************************************************************************************************************
	Class: Navigation
		Used to dynamically assign and manage events for a standard <ul> structed css navigation
*/
var vbNav = '';
var debugCnt = 0;
var navtimer = '';

if (isPrototype()) {
	var Nav = Class.create();
	/*
		for every <a> mouseOVER (id="nav-1-1") 
			- loop through an array of currently open menus and close from the back to the front
			- show a corresponding sub menu (id="sub-1-1")
			
		for every <a> mouseOUT
			- start the global timer
			- hide all open menus 
			- open the default menus
	*/
	Nav.prototype = {
		_elem			:	"",
		_open_elems		:	new Array,
		_orig_top		: 	"",
		_orig_sub		: 	"",
		/*
			- sets the default top <a> and sub <ul>
			- attachs events to every <a>
		*/
		initialize: function ( elem ) {
			// main navigation <ul>
			this._elem = elem;
			
			active_elems = new Array();
			
			top_found = false;
			
			// attach events to sub menus only not top level (nav-1)
			a_elems = this._elem.getElementsByTagName('A');
			for (i = 0; i < a_elems.length; i++) {
				//if (a_elems[i].id.length > 5) {
					// add mouseover event handler
					if (a_elems[i].className.indexOf('active') != -1) {
						active_elems.push(a_elems[i]);
					}
					// add mouseover
					Event.observe(a_elems[i], 'mouseover', this.showChild.bindAsEventListener(this));
					// add mouseout
					Event.observe(a_elems[i], 'mouseout', this.startTimer.bindAsEventListener(this));
				//} else {
					if (a_elems[i].className.indexOf('active') != -1) {
						active_elems.push(a_elems[i]);
					}
				//}
			}
			
			this._orig_top 		= active_elems[0] ? active_elems[0].id : 'nav-1';
			this._orig_sub_a 	= active_elems[1] ? active_elems[1].id : false;
			this._orig_sub 		= active_elems[0] ? active_elems[0].id.replace('nav', 'sub') : 'sub-1';
			
			if (!active_elems[0]) {
				$(this._orig_top).addClassName('active');
			}
			if (!active_elems[1] && this._orig_sub_a) {
				$(this._orig_sub_a).addClassName('active');
			}
		},
		/*
			shows the next available <ul> element from the 
			triggered <a> mouseover event
			via CSS classname 'on'
		*/
		showChild : function ( event ) {
			// clear any current timer
			this.clearTimer();
			// locate the <a> element from the triggered event
			a_elem = Event.element(event);
			if (a_elem.tagName == "SPAN") { a_elem = a_elem.parentNode; }
			
			// hide open sub menus except this <a> 
			this.hideSubs( a_elem.id );
			
			// target sub menu
			target = a_elem.id.replace('nav','sub');
			// check the target isn't already in the array
			if (this._open_elems.indexOf(target) == -1 || target == this._orig_sub) {
				// check the elem exists
				if ($(target)) {
					// display the submenu
					$(a_elem.id).addClassName('active');
					$(target).style.display = 'block';
					// add the target to the array of open elements
					if (this._open_elems.indexOf(target) == -1) {
						this._open_elems.push(target);
					}
				}
			}
			// hide <select> elements
			this.hideSelects('hidden');
		},
		/*
			closes open menus
			- close all ('*') 
			or
			- all elements except the one passed
		*/
		hideSubs : function ( elem_id ) {
			if (elem_id != "*" ) {
				var safe_elems = new Array();
				for (i = (this._open_elems.length-1); i >= 0; i--) {
					target = a_elem.id.replace('nav','sub');
					
					if ( target != this._open_elems[i] && target.length <= this._open_elems[i].length ) {	  
						a_target = this._open_elems[i].replace('sub','nav');
						if ($(a_target)) {
							$(a_target).removeClassName('active');
						}
						if ($(this._open_elems[i]))
							$(this._open_elems[i]).style.display = 'none';
					} else {
						if (this._orig_sub != this._open_elems[i]) {
							safe_elems.push(this._open_elems[i]);
						}
					}
				}

				$(this._orig_top).addClassName('active');

				// clear the open elements array
				this._open_elems = [];
				
				if (this._open_elems.indexOf(this._orig_sub) == -1) {
					this._open_elems.push(this._orig_sub);
				}
				// reverse safe items to make sure the order is still from the front to the back
				safe_elems.reverse();
				// fill it with the current safe items
				this._open_elems = this._open_elems.concat(safe_elems);
			} else {
				// hide all sub menus
				for (i = (this._open_elems.length-1); i >= 0; i--) {
					//if (this._orig_sub != this._open_elems[i]) {
						a_target = this._open_elems[i].replace('sub','nav');
						if ($(a_target)) {
							$(a_target).removeClassName('active');
						}
						if ($(this._open_elems[i]))
							$(this._open_elems[i]).style.display = 'none';
					//}
				}
				// reset the open elems array
				this._open_elems = [];
				if (this._open_elems.indexOf(this._orig_sub) == -1) {
					this._open_elems.push(this._orig_sub);
				}
				//$(this._orig_sub).style.display = 'block';
				$(this._orig_top).addClassName('active');
				if (this._orig_sub_a) {
					$(this._orig_sub_a).addClassName('active');
				}
				
			}
		},
		/*
			hides all select menus within $('page-banner') and $('hhr')
			TODO: may have to expand this to hide selects within $('content-a') and $('content-b')
		*/
		hideSelects : function (action) {
			if ( action != 'visible' ){ action='hidden'; }
			if ( navigator.appName.indexOf("Microsoft") >= 0 || navigator.appName.indexOf("MSIE") >= 0 ) {
				
				arr = new Array;
				
				selects1 = $('page-banner') ? $('page-banner').getElementsByTagName('SELECT') 	: new Array();
				selects2 = $('hhr') 		? $('hhr').getElementsByTagName('SELECT') 			: new Array(); 
				selects3 = $('content-a') 	? $('content-a').getElementsByTagName('SELECT') 	: new Array(); 
				
				for (var i = 0; i < selects1.length; i++){ arr.push(selects1[i]); }
				for (var i = 0; i < selects2.length; i++){ arr.push(selects2[i]); }
				for (var i = 0; i < selects3.length; i++){ arr.push(selects3[i]); }
					
				for (var i = 0; i < arr.length; i++){
					arr[i].style.visibility = action;
				}
			}
		},
		reset : function () {
			this.clearTimer();
			this.hideSelects('visible');
			this.hideSubs("*");
		},
		startTimer : function ( ) {
			this.clearTimer();
			navtimer = setInterval( "vbNav.reset()", 750 );	
		},
		clearTimer : function ( ) {
			clearInterval( navtimer );	
		}
	}
	
	function initNav () {
		if ($('navigation')) {
			vbNav = new Nav ($('navigation'));
		}
	}
}	
/*  *******************************************************************************************************************
	Class: TextFieldBlank
		Assigns events to all text inputs to allow for clearing of content on click
*/
if (isPrototype()) {
	var TextFieldBlank = Class.create();
	/*
		a prototype for clearing textfield inputs for usability
	*/
	TextFieldBlank.prototype = {
		_elem			:	"",
		_default		:	"",
		/*
			- sets the default elem
			- sets default value
			- assigns click and blur event
		*/
		initialize : function ( elem ) {
			this._elem = elem;
			this._default = this._elem.alt;
			// add click
			Event.observe(this._elem, 'focus', this.autoblank.bindAsEventListener(this));
			// add blur
			Event.observe(this._elem, 'blur', this.refill.bindAsEventListener(this));
		},
		autoblank : function (event) {
			if (this._elem.value == this._default) {
				this._elem.value = '';
			}
		},
		refill : function () {
			if (this._elem.value == '') {
				this._elem.value = this._default;	
			}
		}
	}// end TextFieldBlank.prototype
	
	function initTextFieldBlanks () {
		inputs = document.getElementsByTagName('INPUT');
		for (i = 0; i < inputs.length; i++) {
			if (inputs[i].type == 'text' || inputs[i].type == 'password') {
				if (inputs[i].alt) {
					var tmp = new TextFieldBlank(inputs[i]);
				}
			}
		}
	}
}/*  *******************************************************************************************************************
	Class: Slider
		Makes the slider for specials left and right work
*/
var SpecialsSlider = Class.create({
	/*
		Initializes Slider
	*/
	initialize : function(content, triggerLeft, triggerRight, viewable, options) {
		
		this.options = {
			//test	:	false
		};
		Object.extend(this.options, options || { });
		
		this.content 		= $(content);
		this.leftArrow 		= $(triggerLeft);
		this.rightArrow 	= $(triggerRight);
		
		boxes = this.content.select('.special');
		this.boxTotal = boxes.length;
		this.boxWidth = boxes[1].getWidth();
		
		this.viewable = viewable;
		this.position = 0;
		this.target = 0;
		
		Event.observe(this.leftArrow, 'click', this.triggerLisenter.bindAsEventListener(this));
		Event.observe(this.rightArrow, 'click', this.triggerLisenter.bindAsEventListener(this));
		
		/*
			initially, create some padding on the left
		*/
		if (this.boxTotal > 4) {
			this.clonePadding('left');
		}
	},
	triggerLisenter : function (event) {
		event.stop();
		elem = event.element();
		direction = elem.id.split('-')[1];
		/*
			clone me some padding
		*/
		this.clonePadding(direction);
		/*
			move it along, nothing to see here
		*/
		this.move(direction);
	},
	/*
		Moves the slider in a given direction
	*/
	move : function (direction) {
		
		this.target = (direction == 'left') ? (this.target + this.boxWidth) : (this.target = this.target - this.boxWidth);
		
		new Effect.Move (this.content , { x: this.target, y: 0, mode: 'absolute', duration: .7, afterFinish: this.adjust } );
		
		(direction == 'left') ? this.position-- : this.position++;
		
	},
	adjust : function () {
		/* not used yet */
	},
	/*
		clones nodes (left or right) to create the illusion that the slider
		never ends...
	*/
	clonePadding : function (direction) {
		
		boxes = this.content.select('.special');
		
		/* left position */
		currLeft = parseFloat(this.content.getStyle('left'));
			
		/* 
			depending on the direciton... clone nodes and put them on either
			the start or the end of the stack to allow the illusion of 
			endless looping. 
			
			After placing cloned node, remove its original
			element to keep the amount of DOM elements to a minimum.
		*/
		if (direction == 'right') {
			
			special = boxes[0];
			special_clone = special.cloneNode(true);
			
			this.content.appendChild(special_clone);
			
			/* target */
			targetLeft = currLeft + this.boxWidth;
			/* set new pos */
			this.content.style.left = targetLeft+'px';
			
			special.remove();
			this.target = this.target + this.boxWidth;
			
		} else if (direction == 'left') {
			
			special = boxes[boxes.length -1];
			special_clone = special.cloneNode(true);
			
			this.content.insertBefore(special_clone, boxes[0]);
			
			/* target */
			targetLeft = currLeft - this.boxWidth;
			/* set new pos */
			this.content.style.left = targetLeft+'px';
			
			special.remove();
			this.target = this.target - this.boxWidth;
		}
		
	}
});
function initSpecialsSlider () {
	
	if ($('slider-content')) {
		var tmpslider = new SpecialsSlider('slider-content', 'slide-left', 'slide-right', 4);
	}
	
}
/*  *******************************************************************************************************************
	Function: initPopups
		Finds all elements with rel attribute 'popup' and makes them a popup object
*/
if (isPrototype()) {
	function initPopups () {
		
		popups = new Array();
		
		var a_elems = document.body.getElementsByTagName('a');
		for (var i=0; i<a_elems.length; i++) {
			if (a_elems[i].rel == "popup") {
			 	popups.push(a_elems[i]);
			}
		}
		
		for (i = 0; i < popups.length; i++) {
			
			var width  = popups[i].className.match(/w-(\d+)/) ? popups[i].className.match(/w-(\d+)/)[1] : '610';
			var height = popups[i].className.match(/h-(\d+)/) ? popups[i].className.match(/h-(\d+)/)[1] : '430';
			
			var d = new Date();
			var t = d.getTime();
			var name   = popups[i].id ? popups[i].id : t;
			
			var tmp = new Popup({ 
				trigger		: popups[i],
				url 		: popups[i].href, 
				name 		: 'popup'+name, 
				resizable 	: 1, 
				scrollbars 	: 1,
				width 		: width, 
				height 		: height 
			});
		}
	}
}
/*  *******************************************************************************************************************
	Window Loaded Observers
		Assign events once the window has loaded to trigger setup of objects
*/
if ( isW3CDOM && isPrototype() ) {
  	/* happens from top down */
	BrowserDetect.init();
  	Event.observe(window, 'load', initNav, false);
	Event.observe(window, 'load', initTextFieldBlanks, false);
	Event.observe(window, 'load', initPopups, false);
	Event.observe(window, 'load', initSpecialsSlider, false);
}
