/* ------------------------------ DETECTION ------------------------------ */

function detect() {
	// simplify things
	var agent 		= navigator.userAgent.toLowerCase();
	
	// detect platform
	this.isMac		= (agent.indexOf('mac') != -1);
	this.isWin		= (agent.indexOf('win') != -1);
	this.isWin2k	= (this.isWin && (
			agent.indexOf('nt 5') != -1));
	this.isWinSP2	= (this.isWin && (
			agent.indexOf('xp') != -1 || 
			agent.indexOf('sv1') != -1));
	this.isOther	= (
			agent.indexOf('unix') != -1 || 
			agent.indexOf('sunos') != -1 || 
			agent.indexOf('bsd') != -1 ||
			agent.indexOf('x11') != -1 || 
			agent.indexOf('linux') != -1);
	
	// detect browser
	this.isSafari	= (agent.indexOf('safari') != -1);
	this.isSafari2 	= (this.isSafari && (parseFloat(agent.substring(agent.indexOf("applewebkit/")+"applewebkit/".length,agent.length).substring(0,agent.substring(agent.indexOf("applewebkit/")+"applewebkit/".length,agent.length).indexOf(' '))) >=  300));
	this.isOpera	= (agent.indexOf('opera') != -1);
	this.isNN		= (agent.indexOf('netscape') != -1);
	this.isIE		= (agent.indexOf('msie') != -1);
	this.isFirefox	= (agent.indexOf('firefox') != -1);
}
var browser = new detect();

/* ------------------------------ EVENT HOOKS ------------------------------ */

/**
* Attach event listener to page load
*
* Example:
* addLoadListener(tooltipInit);
*
* @param	functionRef		function	function reference
* @return	--				null		nothing
*/
function addLoadListener(functionRef) {
	if (typeof window.addEventListener != 'undefined') {
		window.addEventListener('load', functionRef, false);
	} else if (typeof document.addEventListener != 'undefined') {
		document.addEventListener('load', functionRef, false);
	} else if (typeof window.attachEvent != 'undefined') {
		window.attachEvent('onload', functionRef);
	} else {
		var oldFunction = window.onload;
		if (typeof window.onload != 'function') {
			window.onload = functionRef;
		} else {
			window.onload = function() {
				oldFunction();
				functionRef();
			};
		}
	}
}

/**
* Attach event listener
*
* Example:
* var a = document.getElementsByTagName('a')[0];
* attachEventListener(a, 'click', toggleMenuClick, false);
*
* @param	target			element		target element
* @param	eventType		string		event to hook
* @param	functionRef		function	function reference
* @param	capture			boolean		capture the event (so no bubbling occurs)
* @return	--				boolean		true
*/
function attachEventListener(target, eventType, functionRef, capture) {    
	if (typeof target.addEventListener != "undefined") {
		target.addEventListener(eventType, functionRef, capture);
	} else if (typeof target.attachEvent != "undefined") {
		target.attachEvent("on" + eventType, functionRef);
	} else {
		eventType = "on" + eventType;
		if (typeof target[eventType] == "function") {
			var oldListener = target[eventType];
			target[eventType] = function() {
				oldListener();
				return functionRef();
			};
		} else {
			target[eventType] = functionRef;
		}
	}	
	return true;	
}

/**
* Detach event listener
*
* @param	target			element		target element
* @param	eventType		string		event to hook
* @param	functionRef		function	function reference
* @param	capture			boolean		capture the event (so no bubbling occurs)
* @return	--				boolean		true
*/
function detachEventListener(target, eventType, functionRef, capture) {
	if (typeof target.removeEventListener != "undefined") {
		target.removeEventListener(eventType, functionRef, capture);
	} else if (typeof target.detachEvent != "undefined") {
		target.detachEvent("on" + eventType, functionRef);
	} else {
		target["on" + eventType] = null;
	}
	return true;
}

/**
* Get target object
*
* Example:
* var target = getEventTarget(event);
* while (target.nodeName.toLowerCase() != "a") { target = target.parentNode; }
*
* Example:
* var target = getEventTarget(event);
* while (target.className == null || !/(^| )hastooltip( |$)/.test(target.className)) { target = target.parentNode; }
*
* @param	event			object		event reference
* @return	--				element		target element
*/
function getEventTarget(event) {
  var targetElement = null;

  if (typeof event.target != "undefined") {
    targetElement = event.target;
  } else {
    targetElement = event.srcElement;
  }

  while (targetElement.nodeType == 3 && targetElement.parentNode != null) {
    targetElement = targetElement.parentNode;
  }

  return targetElement;
}

/* ------------------------------ DOM ------------------------------ */

/**
* Return array of element with matching attributes and values.
*
* Example:
* var tips = getElementsByAttribute("class", "hastooltip");
*
* @param	attribute		string		attribute
* @param	attributeValue	value		attribute value
* @param	target			element		target element
* @return	--				array		matched element array
*/
function getElementsByAttribute(attribute, attributeValue, target) {
	var elementArray = new Array();
	var matchedArray = new Array();
	
	if (target == null) {
		if (document.all) {
			elementArray = document.all;
		} else {
			elementArray = document.getElementsByTagName("*");
		}
	} else {
		if (target.all) {
			elementArray = target.all;
		} else {
			elementArray = target.getElementsByTagName("*");
		}
	}

	for (var i = 0; i < elementArray.length; i++) {
		if (attribute == "class") {
			var pattern = new RegExp("(^| )" + attributeValue + "( |$)");

			if (elementArray[i].className.match(pattern))
			{
				matchedArray[matchedArray.length] = elementArray[i];
			}
		} else if (attribute == "for") {
			if (elementArray[i].getAttribute("htmlFor") || elementArray[i].getAttribute("for"))
			{
				if (elementArray[i].htmlFor == attributeValue)
				{
					matchedArray[matchedArray.length] = elementArray[i];
				}
			}
		} else if (elementArray[i].getAttribute(attribute) == attributeValue) {
			matchedArray[matchedArray.length] = elementArray[i];
		}
	}

	return matchedArray;
}

/**
* Return the size of the viewport.
*
* Example:
* var viewportSize = getViewportSize();
*
* @return	--				array		the size of the viewport
*/
function getViewportSize() {
	var size = {
		'width': 0,
		'height': 0
	};

	if (typeof window.innerWidth != 'undefined') {
		size = {
			'width': window.innerWidth,
			'height': window.innerHeight
		};
	}
	else if (typeof document.documentElement != 'undefined'
			&& typeof document.documentElement.clientWidth != 'undefined'
			&& document.documentElement.clientWidth != 0) {
		size = {
			'width': document.documentElement.clientWidth,
			'height': document.documentElement.clientHeight
		};
	}
	else {
		size = {
			'width': document.getElementsByTagName('body')[0].clientWidth,
			'height': document.getElementsByTagName('body')[0].clientHeight
		};
	}

	return size;
}

/**
* Return the scrolling position of the page.
*
* Example:
* var scrollingPosition = getScrollingPosition();
*
* @return	--				array		the position of the page
*/
function getScrollingPosition() {
	//array for X and Y scroll position
	var position = {
		'x': 0,
		'y': 0
	};
	
	// if the window.pageYOffset property is supported
	if (typeof window.pageYOffset != 'undefined') {
		//store position values
		position = {
			'x': window.pageXOffset,
			'y': window.pageYOffset
		};
	}

	// if the documentElement.scrollTop property is supported
	// and the value is greater than zero
	else if (typeof document.documentElement.scrollTop != 'undefined'
		&& document.documentElement.scrollTop > 0) {
		//store position values
		position = {
			'x': document.documentElement.scrollLeft,
			'y': document.documentElement.scrollTop
		};
	}

	// if the body.scrollTop property is supported
	else if(typeof document.body.scrollTop != 'undefined') {
		//store position values
		position = {
			'x': document.body.scrollLeft,
			'y': document.body.scrollTop
		};
	}

	//return the array
	return position;
}

/**
* Return the size and position of an element.
*
* Example:
* var coords = getCoordinates(subnav_div);
* subnav_div.style.marginTop = (coords['height'] * -1.0) + "px";
* subnav_div.style['display'] = 'none';
*
* @param	element			element		target element
* @return	--				object		the elements coordinates
*/
function getCoordinates(element){
	var obj = {
		'width': element.offsetWidth,
		'height': element.offsetHeight,
		'left': element.offsetLeft,
		'top': element.offsetTop
	};
	obj.right = obj.left + obj.width;
	obj.bottom = obj.top + obj.height;
	
	var position = getPosition(element)
	obj.x = position.x;
	obj.y = position.y;
	
	return obj;
}


/**
* Return the position of an element.
*
* Example:
* var coords = getPosition(subnav_div);
*
* @param	element			element		target element
* @return	--				object		the elements position
*/
function getPosition(element) {
	var x = 0;
	var y = 0;
	
	while (element != null) {
		x += element.offsetLeft;
		y += element.offsetTop;
		element = element.offsetParent;
	}
	
	var obj = {
		'x': x,
		'y': y
	};
	
	return obj;
}


/**
* Set the opacity of an element.
*
* Example:
* setOpacity(tip, 0);
*
* @param	element			element		target element
* @param	opacity			number		opacity (0 to 1)
* @return	--				null		nothing
*/
function setOpacity(element, opacity){
	if (opacity == 0) {
		if (element.style.visibility != "hidden") element.style.visibility = "hidden";
	} else {
		if (element.style.visibility != "visible") element.style.visibility = "visible";
	}
	// if (!this.currentStyle || !this.currentStyle.hasLayout) this.style.zoom = 1;
	if (browser.isIE) {
		element.style.filter = "alpha(opacity=" + opacity*100 + ")";
	}
	element.style.opacity = element.opacity = opacity;
	// element.style.KHTMLOpacity, element.style.MozOpacity
}

/* ------------------------------ TOOL TIP ------------------------------ */

function tooltipInit() {
	var tips = getElementsByAttribute("class", "hastooltip");

	for (var i = 0; i < tips.length; i++) {
		attachEventListener(tips[i], "mouseover", showTip, false);
		attachEventListener(tips[i], "mouseout", hideTip, false);
	}

	return true;
}

function calendarInit() {
	var previous_month = getElementsByAttribute("class", "previous_month");
	var next_month = getElementsByAttribute("class", "next_month");
	
	// previous_month = http://foe.dev.fahlgreninteractive.com/getEventCaledar.aspx?date=6/23/2007%2010:46:31%20AM - 1
	// next_month = http://foe.dev.fahlgreninteractive.com/getEventCaledar.aspx?date=8/23/2007%2010:46:31%20AM - 1
	
	/*
	var str = "";
	str += "previous_month = " + previous_month + " - " + previous_month.length + "\n";
	str += "next_month = " + next_month + " - " + next_month.length + "\n";
	// alert(str);
	*/
	
	if (previous_month.length == 1) {
		var el = previous_month[0];
		attachEventListener(el, "click", calendarPreviousMonth, false);
		var url = unescape(el.getAttribute("href"));
		var searchStr = "?date=";
		var index = url.indexOf(searchStr);
		var date = url.slice(index + searchStr.length);		
		el.setAttribute("date", date);
		el.setAttribute("href", "#fix");
		
	}
	if (next_month.length == 1) {
		var el = next_month[0];
		attachEventListener(el, "click", calendarNextMonth, false);
		var url = unescape(el.getAttribute("href"));
		var searchStr = "?date=";
		var index = url.indexOf(searchStr);
		var date = url.slice(index + searchStr.length);		
		el.setAttribute("date", date);
		el.setAttribute("href", "#fix");
	}

	return true;
}

/* ------------------------------ SELECT ELEMENT BUG FIX -------------------- */

function fixSelect(state) {
    // IE 6 BUG FIX
    // Hide/Show Aerie Locator select element to keep from overlaying calendar tool tips
    var theMonth = document.getElementById("calendar_Month");
    theMonth.style.visibility = state;
    var theYear = document.getElementById("calendar_Year");
    theYear.style.visibility = state;
    var theLocation = document.getElementById("widget_aerielocator_meetingstate");
    if (theLocation != null){
    theLocation.style.visibility = state;
    }
}

/* ------------------------------ MOUSE EVENTS ------------------------------ */

function showTip(event) {

    // IE 6 BUG FIX
    fixSelect('hidden');

	// Get target element
	if (typeof event == "undefined") {
		event = window.event;
	}
	
	var target = getEventTarget(event);
	while (target.className == null || !/(^| )hastooltip( |$)/.test(target.className)) {
		target = target.parentNode;
	}

	// Create tooltip HTML
	var tip = document.createElement("div");
	var content = target.getAttribute("title");
	
	// if (content == null) {
		var arr = getElementsByAttribute("class", "tooltipdata", target.parentNode);
		if (arr.length > 0) {
			content = arr[0].cloneNode(true);
		}
	// }
	
	if (content == null) {
		return;
	}
	
	target.tooltip = tip;
	
	if (typeof content == "string") {
		target.setAttribute("title", "");
	}
	
	if (target.getAttribute("id") != "") {
		tip.setAttribute("id", target.getAttribute("id") + "tooltip");
	}
	tip.className = "tooltip_down";
	
	// Toolip top
	var tipTop = document.createElement("div");
	tipTop.className = "top";
	tip.appendChild(tipTop);
	
	// Toolip fill
	var tipFill = document.createElement("div");
	tipFill.className = "fill";
	if (typeof content == "string") {
		tipFill.appendChild(document.createTextNode(content));
	} else {
		tipFill.appendChild(content);
	}
	tip.appendChild(tipFill);
	
	// Toolip bottom
	var tipBottom = document.createElement("div");
	tipBottom.className = "bottom";
	tip.appendChild(tipBottom);
	
	// Initial position
	var scrollingPosition = getScrollingPosition();
	/*
	var cursorPosition = { 'x': 0, 'y': 0 }
	if (typeof event.pageX != "undefined" && typeof event.x != "undefined") {
		cursorPosition['x'] = event.pageX;
		cursorPosition['y'] = event.pageY;
	} else {
		cursorPosition['x'] = event.clientX + scrollingPosition['x'];
		cursorPosition['y'] = event.clientY + scrollingPosition['y'];
	}
	*/
	
	tip.style.position = "absolute";
	tip.style.left = "0px";
	tip.style.top = "0px";
	tip.style.visibility = "hidden";
	
	// Attach tooltip to DOM
	var tipDiv = document.getElementsByTagName("body")[0].appendChild(tip);
	
	// Reposition
	var tipCoords = getCoordinates(tip);
	var viewportSize = getViewportSize();
	
	cursorPosition = getCoordinates(target);
	
	// Top
	var halign = "center";
	var valign = "top";
	var x = (cursorPosition['x'] + cursorPosition['width'] * .5) - tipCoords['width'] * .5; // "px";
	var y = (cursorPosition['y']) - tipCoords['height'] - 0; // "px";
	
	/*
	// Left and right bounds
	if (cursorPosition['x'] - scrollingPosition['x'] + (tipCoords['width'] * .5) > viewportSize['width'] - 25) {
		halign = "left";
		x = scrollingPosition['x'] + viewportSize['width'] - 25 - tipCoords['width'];
	} else if (cursorPosition['x'] - scrollingPosition['x'] - (tipCoords['width'] * .5) < 10) {
		halign = "right";
		x = scrollingPosition['x'] + 10;
	} else {
		halign = "center";
		x = cursorPosition['x'] - tipCoords['width'] * .5;
	}
	
	// Top and bottom bounds
	if (cursorPosition['y'] - scrollingPosition['y'] - tipCoords['height'] < 10) {
		valign = "bottom";
		y = cursorPosition['y'] + 20;
		tip.className = "tooltip_up";
	} else {
		valign = "top";
		y = cursorPosition['y'] - tipCoords['height'] - 10;
	}
	*/
	
	tip.style.left = x + "px";
	if (valign == "top") {
		var ystart = y - 50;
	} else {
		var ystart = y + 50;
	}	
	tip.style.top = ystart + "px";
	
	doSlide(tip,'top',ystart,y,30,20);
	
	setOpacity(tip, 0);
	tip.style.visibility = "visible";

	return true;
}

function hideTip(event) {

    // IE 6 BUG FIX
    fixSelect('visible');

	if (typeof event == "undefined") {
		event = window.event;
	}

	var target = getEventTarget(event);

	while (target.className == null || !target.className.match(/(^| )hastooltip( |$)/)) {
		target = target.parentNode;
	}

	if (target.tooltip != null) {
		var arr = getElementsByAttribute("class", "tooltipdata", target.tooltip);
		
		if (arr.length > 0) {
			// Don't reset title...
		} else {
			target.setAttribute("title", target.tooltip.childNodes[1].childNodes[0].nodeValue);		
		}
		target.tooltip.parentNode.removeChild(target.tooltip);
	}

	return false;
}

function calendarPreviousMonth(event) {
	// Get target element
	if (typeof event == "undefined") {
		event = window.event;
	}
	
	var target = getEventTarget(event);
	while (target.className == null || !/(^| )previous_month( |$)/.test(target.className)) {
		target = target.parentNode;
	}

	// Create tooltip HTML
	getEventCalendar(target.getAttribute("date"));
	
	return false;
}

function calendarNextMonth(event) {
	// Get target element
	if (typeof event == "undefined") {
		event = window.event;
	}
	
	var target = getEventTarget(event);
	while (target.className == null || !/(^| )next_month( |$)/.test(target.className)) {
		target = target.parentNode;
	}

	// Create tooltip HTML
	getEventCalendar(target.getAttribute("date"));
	
	return false;
}

/* ------------------------------ CLICK EVENTS ------------------------------ */

/* ------------------------------ ANIMATION ------------------------------ */

// SMOOTH
function easeInOut(t, b, c, d) {
	// t = time
	// d = duration
	// c = change
	// b = begin
	if ((t/=d/2) < 1) {
		return c/2 * t * t + b;
	} else {
		return -c/2 * ((--t)*(t-2) - 1) + b;
	}
}

// BOUNCE
function easeOut(t, b, c, d) {
	if ((t/=d) < (1/2.75)) {
		return c*(7.5625*t*t) + b;
	} else if (t < (2/2.75)) {
		return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
	} else if (t < (2.5/2.75)) {
		return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
	} else {
		return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
	}
}
/*
function easeIn (t, b, c, d) {
	return c - easeOut (d-t, 0, c, d) + b;
}
function easeInOut (t, b, c, d) {
	if (t < d/2) return easeIn (t*2, 0, c, d) * .5 + b;
	else return easeOut (t*2-d, 0, c, d) * .5 + c*.5 + b;
}
*/

function doSlide(element,attribute,startValue,endValue,steps,intervals) {
	// doScrollDiv(categoriesnew,categoriesnew.scrollLeft,(targetLevel-3) * 194,10,35);
	
	if (element.valueChangeInterval) {
		window.clearInterval(element.valueChangeInterval);
	}
	
	var actStep = 0;
	element.valueChangeInterval = window.setInterval(
		function() {
			element.currentValue = easeOut(actStep,startValue,endValue-startValue,steps);
			element.style[attribute] = element.currentValue + "px";
			if (actStep<15) {
				var alpha = easeInOut(actStep,0,1,15);
			} else {
				alpha = 1;
			}
			setOpacity(element, alpha);
			actStep++;
			if (actStep > steps) {
				window.clearInterval(element.valueChangeInterval);
				//if (element.toggle == "hidden" ) { element.style['display'] = 'none'; }
			}
		} 
		,intervals)
}

function doFade(element,attribute,startValue,endValue,steps,intervals) {
	
	if (element.valueChangeInterval) {
		window.clearInterval(element.valueChangeInterval);
	}
	
	var actStep = 0;
	element.valueChangeInterval = window.setInterval(
		function() {
			element.currentValue = easeInOut(actStep,startValue,endValue-startValue,steps);
			element.style[attribute] = element.currentValue;
			actStep++;
			if (actStep > steps) {
				window.clearInterval(element.valueChangeInterval);
			}
		} 
		,intervals)
}

/* ------------------------------ INIT ------------------------------ */

addLoadListener(tooltipInit);
addLoadListener(calendarInit);
