
var debugDiv = null;

var request = null;
var contentDIV = null;


var hotButtonId = null;
var hotOnMouseOver = null;
var hotOnMouseOut = null;

function toggleTestimonial(objID)
{
	obj = document.getElementById(objID);
	
	if (obj)
	{
		obj.style.display = "block";
	}
	
	return false;
}

function mainNavigate(url, objID, external)
{
	if (external == null)
	{
		external = false;	
	}
	
	if (request == null)
	{
		request = new AJAXRequest();
	}
	
	if (contentDIV == null)
	{
		contentDIV = document.getElementById('mainContent');
		if (contentDIV == null)
		{
			// can't go any further, allow the browser to navigate
			return true;
		}
	}

	
	// clear out the "friend" form, if it is there
	var friendBox = document.getElementById('friend_form_response');
	if (friendBox != null)
	{
		friendBox.innerHTML = '';	
	}


	setLoadingBoxDimensions();

	// "splash" whatever was clicked on
	splash(objID, 5, 5, true, null, 7, 2);
	
	var callback = function () { doMainNavigate(url, objID, external); };
	return !fadeIn('loadingBox', callback);
}

function doMainNavigate(url, objID, external)
{
	if (external)
	{
		// just navigate to the URL
		window.location.href = url;
	}
	else
	{
		// perform the AJAX request for new page
		var callback = function(response){ onMainNavigateComplete(response, objID) }
		request.doGet(callback, url);
		
		// trigger a Google Analytics page view
		pageTracker._trackPageview(url);
	}
}

function onMainNavigateComplete(response, objID)
{
	// title
	var titleNodes = response.getElementsByTagName('title');	
	if (titleNodes[0].firstChild != null)
	{
		document.title = titleNodes[0].firstChild.nodeValue;
	}
	
	// main content
	var contentNodes = response.getElementsByTagName('body');	
	if (contentNodes[0].firstChild != null)
	{
		contentDIV.innerHTML = contentNodes[0].firstChild.nodeValue;
	}

	// extra elements
	swapElement('menu_side', response);
	swapElement('send_form', response);
	swapElement('audio', response);	
	
	
	setHotButton(objID);
	
	// hide the loading div
	fadeOut('loadingBox', null, true);
	
	setLoadingBoxDimensions();
}

function swapElement(element, response)
{
	var div = document.getElementById(element);	
	if (div != null)
	{
		var nodes = response.getElementsByTagName(element);
		if (nodes[0].firstChild != null)
		{
			div.innerHTML = nodes[0].firstChild.nodeValue;
		}
		else
		{
			div.innerHTML = '';	
		}
	}
}

function setLoadingBoxDimensions()
{
	var obj = document.getElementById('loadingBox');
	if (obj != null && contentDIV != null)
	{
		var width = contentDIV.offsetWidth + "px";
		obj.style.width = width;

		var heightComp = 0;

		// IE has a slightly different style offset than everything else
		if( navigator.appName != "Microsoft Internet Explorer")
		{
			heightComp = 15;
		}


		var height = contentDIV.offsetHeight + heightComp + "px";
		obj.style.height = height;	
	}
}


// ---- splashExit ----
// Navigate away form the page with a quick "splash" effect.
// url - The URL to navigate to when finished.
// objID - The ID of the object to "splash".
function splashExit(url, objID)
{
	var callback = function () { window.location.href = url; };
	return !splash(objID, 5, 5, true, callback, 0, 0);
}

// ---- setHotButton ----
// Sets the provided object ID as the "hot" button.
// If there is a previous "hot" button it is set to normal.
// obj - The object to set as the "hot" button.
function setHotButton(objID)
{
	// re-set the old button
	if (hotButtonId)
	{
		var obj = document.getElementById(hotButtonId);
		if (obj)
		{
			obj.onmouseover = hotOnMouseOver;
			obj.onmouseout = hotOnMouseOut;
		}
		
		fadeOut(hotButtonId);
	}
	
	// configure the current button
	obj = document.getElementById(objID);
	if (obj)
	{
		hotButtonId = objID;
		hotOnMouseOver = obj.onmouseover;
		hotOnMouseOut = obj.onmouseout;
				
		obj.onmouseover = null;
		obj.onmouseout = null;
		
		obj.opacity = 100;
		
		fadeIn(objID);
	}
}

// ---- splash ----
// Generates a "splash" effect on the provided object ID.
// objID - The ID of the object to splash.
// rate - The speed that the object grows.
// steps - The number of frames that the animation should be.
// fade - true to fade out while expanding.
// onFinish - A function to call when the animation is finished.
// specialX - How many pixels of horizontal position compensation.
// specialY - How many pixesl of vertical position compensation.
function splash(objID, rate, steps, fade, onFinish, specialX, specialY)
{
	var result = false;

	var obj = document.getElementById(objID);
	
	if (obj)
	{
		// get the current screen position
		var origPos = findPos(obj);
		
		// duplicate this object so that we can mess with it
		var objAnimID = objID + '_anim';
		var objAnim = obj.cloneNode(true);
		objAnim.id = objAnimID;
		obj.parentNode.appendChild(objAnim);
		objAnim = document.getElementById(objAnimID);

		objAnim.animSteps = steps;
		objAnim.animExpandRate = rate;
		
		if (objAnim.style.width == "")
		{
			var width = objAnim.offsetWidth + "px";
			objAnim.style.width = width;
		}
		if (objAnim.style.height == "")
		{
			var height = objAnim.offsetHeight + "px";
			objAnim.style.height = height;
		}
		if (objAnim.style.left == "")
		{
			var left = origPos[0] - specialX + "px";
			objAnim.style.left = left;
		}
		if (objAnim.style.right == "")
		{
			var top = origPos[1] - specialY + "px";	
			objAnim.style.top = top;
		}
		
		objAnim.animExpandRatio = parseInt(objAnim.style.width) / parseInt(objAnim.style.height);
		objAnim.animOnFinish = onFinish;

		objAnim.animFade = fade;
		if (fade)
		{
			objAnim.opacity = 100;
			objAnim.animFadeRate = Math.ceil(100 / steps);
			setOpacity(objAnim);
		}

		objAnim.style.visibility = "visible";
		objAnim.style.zIndex = 2;
		objAnim.style.position = "absolute";
		
		
		objAnim.onmouseover = null;
		objAnim.onmouseout = null;
		
		
		objAnim.interval = window.setInterval( function() { doSplash(objAnim) }, 30);

		result = true;
	}
	else
	{
		// couldn't do the animation, give onFinish a call anyway
		if (onFinish != null)
		{
			onFinish();
		}
		result = true;
	}
	
	return result;
}

// ---- doSplash ----
// Perform splash operations based off of parameters attached to the provided object.
// obj - The object to splash.
function doSplash(obj)
{
	
	var width = parseInt(obj.style.width) + Math.ceil((obj.animExpandRate * obj.animExpandRatio)) + "px";
	var height = parseInt(obj.style.height) + obj.animExpandRate + "px";
	
	var left = parseInt(obj.style.left) - Math.ceil((obj.animExpandRate * obj.animExpandRatio) / 2) + "px";
	var top = parseInt(obj.style.top) -  Math.ceil(obj.animExpandRate / 2) + "px";
	
	obj.style.width = width;
	obj.style.height = height;
	
	obj.style.left = left;
	obj.style.top = top;

	if (obj.animFade)
	{
		obj.opacity -= obj.animFadeRate;
		setOpacity(obj);
	}


	obj.animSteps--;
	if (obj.animSteps <= 0)
	{
		window.clearInterval(obj.interval);

		if (obj.animOnFinish != null)
		{
			obj.animOnFinish();	
		}
		
		obj.parentNode.removeChild(obj);
	}
}

/**
 * Fade in and object.
 * @param objId The ID of the object to fade in.
 * @param callback A function to call when finished.
 */
function fadeIn(objId, callback)
{
	var result = false;
	
    var obj = document.getElementById(objId);
	
	if (obj)
	{
		obj.style.visibility = 'visible';
		
		if (obj.interval != null)
		{
			window.clearInterval(obj.interval);
			obj.interval = null;
			if (obj.callback != null)
			{
				obj.callback();	
			}
		}
		
		obj.callback = callback;
		
		if (!obj.opacity)
		{
			obj.opacity = 0;
			setOpacity(obj);
		}

		obj.hide = false;
		
		obj.interval = window.setInterval( function() { doFade(obj, 40); }, 50);
		
		result = true;
	}
	else
	{
		if (callback != null)
		{
			callback();
		}
		
		result = true;
	}
	
	return result;
}


/**
 * Fade out an object.
 * @param objID The ID of the object to fade out.
 * @param callback A function to call when finished.
 * @param hide true to hide the object when finished.
 */
function fadeOut(objId, callback, hide)
{
	var result = false;
	
    var obj = document.getElementById(objId);
	
	if (obj)
	{
		if (obj.interval != null)
		{
			window.clearInterval(obj.interval);
			obj.interval = null;
			if (obj.callback != null)
			{
				obj.callback();	
			}			
		}
		
		obj.callback = callback;
		if (obj.hide != null)
		{
			obj.hide = hide;
		}
		else
		{
			obj.hide = false;	
		}
		
		if (obj.opacity)
		{
			obj.interval = window.setInterval( function() { doFade(obj, -20); }, 50);
		}
		
		result = true;
	}
	else
	{
		if (callback != null)
		{
			callback();
		}
		
		result = true;
	}
	
	return result;
}


/**
 * Function on an interval to perform the fade operation.
 * @param obj The object to fade.  Must have the properties: "opacity", "interval"
 * @param amount The amount to fade by.
 */
function doFade(obj, amount)
{
	obj.opacity += amount;
	
	if (obj.opacity > 100)
	{
		window.clearInterval(obj.interval);
		obj.interval = null;

		obj.opacity = 100;
	}
	else if (obj.opacity < 0)
	{
		window.clearInterval(obj.interval);
		obj.interval = null;				
		
		obj.opacity = 0;
	}
	
	if (obj.interval == null)
	{
		if (obj.callback != null)
		{
			obj.callback();	
		}
		
		if (obj.hide)
		{
			obj.style.visibility = 'hidden';
		}
		
	}
		
	setOpacity(obj);
}

/**
 * Sets the opacity of the provided DOM object.
 * @param obj The object to set the opacity of.
 */
function setOpacity(obj)
{
	var opacity = obj.opacity;
  
	// IE/Win
	obj.style.filter = "alpha(opacity:"+opacity+")";

	// prevent divide by zero errors
	opacity = (obj.opacity == 100)?99.999:obj.opacity;

	// Safari<1.2, Konqueror
	obj.style.KHTMLOpacity = opacity/100;
	
	// Older Mozilla and Firefox
	obj.style.MozOpacity = opacity/100;
	
	// Safari 1.2, newer Firefox and Mozilla, CSS3
	obj.style.opacity = opacity/100;
}


/**
 * Finds the X/Y position (top/left corner) of the provided DOM object.
 * @param obj The object to get the position of.
 * @return An array [x, y]
 */
function findPos(obj)
{
	var curleft = 0;
	var curtop = 0;
	
	if (obj.offsetParent) {
		do {
			curleft += obj.offsetLeft;
			curtop += obj.offsetTop;
		} while (obj = obj.offsetParent);
	}
	return [curleft,curtop];
}