/**
* Global JavaScript Definitions
*
* @version			1.6
*/

dojo.require('dojo.cookie');
dojo.require("dojo.io.iframe");

var viewHandler = WebPage;

// Execute on load handler
window.onload = function()
	{
	if (viewHandler !== WebPage)
		{
		// Extend the base page class and create the xhtml object
		viewHandler.inheritsFrom( WebPage );
		xhtml = new viewHandler();
		}
	else
		{
		// Create a generic page xhtml object
		xhtml = new WebPage();
		}

	// Main page initialization
	xhtml.init();
	}


/**
* Creates a new WebPage object with methods used by all pages, can be extended to add page specific methods.
*
*/
function WebPage()
	{
	// Step 1. Define Properties

	var _instance = this;
	this.initialized = false;
	this.debug = false;
	this.emptyFunction = function() {};
	this.log = function(msg) { if (typeof(console) != 'undefined') { console.log(msg); } };



	// Step 2. Define Public Methods

	/**
	* Sets up the initial page state and event handlers
	*/
	this.init = function()
		{
		this.initAnchors();
		this.initInputButtons();

		// Set class as initialized
		this.initialized = true;
		}


	/**
	* Adds standard event handlers to process in-page links and offsite links
	*/
	this.initAnchors = function()
		{
		var links = dojo.query('a.offsite');
		for (var x = 0; x < links.length; x++)
			{
			links[x].onclick = function()
				{
				window.open(this.href,'_blank');
				return false;
				}
			}
		}


	/**
	* Adds rollover support to input[type=image] elements
	*/
	this.initInputButtons = function()
		{
		var rolloverCache = [];
		var inputs = dojo.query('input.hasRollover');
		for (var x = 0; x < inputs.length; x++)
			{
			// 1. Add event handlers to swap the images
			inputs[x].onmouseover = function()
				{
				this.src = this.src.replace(/\.(gif|jpg|png)/, '-over.$1');
				}
			inputs[x].onmouseout = function()
				{
				this.src = this.src.replace(/-over\.(gif|jpg|png)/, '.$1');
				}

			// 2. Pre-cache the rollover image
			var newImage = new Image();
			newImage.src = inputs[x].src.replace(/\.(gif|jpg|png)/i, '-over.$1');
			rolloverCache[rolloverCache.length] = newImage;
			}
		}

	/**
	* Loads the url and injects the content into the specific container
	*
	* @param		url				The url to load
	* @param		container		The id of the container node to inject the loaded document into
	* @param		preventCache	Indicates whether server cached should be defeated
	*/
	this.ajaxLoad = function(url, container, preventCache )
		{
		if ( typeof preventCache == 'undefined' || preventCache == null )
			preventCache = false;

		if ( url.indexOf( "?" ) < 0 )
		{
			url = url + "?";
		}
		else
		{
			url = url + "&";
		}
		url = url + "isAjax=1";
		dojo.xhrGet(
			{
			url: url,
			preventCache: preventCache,
			handleAs: "text",
				load: function(data)
					{
						xhtml.handleAjaxLoad( data, container );
					},
				error: function( error, ioArgs )
					{
						xhtml.handleAjaxError( error, ioArgs, container );
					}
				}
			);
		}
	this.handleAjaxLoad = function( data, container )
	{
		var trimmedData = trim( data );
		if ( trimmedData.indexOf( "Redirect:" ) == 0 )
		{
			trimmedData = trimmedData.substring( trimmedData.indexOf( ":" ) + 1 );
			window.location.href = trimmedData;
		}
		else
		{
			document.getElementById(container).innerHTML = data;
		}
	}
	this.handleAjaxError = function( error, ioArgs, container )
	{
		if (ioArgs.xhr && (ioArgs.xhr.status == 301 || ioArgs.xhr.status == 302)) // shouldn't happen for ajax requests
		{
			//var redirUrl = ioArgs.xhr.getResponseHeader('Location');
			window.location.href = "";
		}
		else
		{
			document.getElementById(container).innerHTML = "An unexpected error occurred: " + error;
		}
	}
	/**
	* Submits the form and injects the returned content into the specific container
	*
	* @param		formId			The id of the form to submit
	* @param		container		The id of the container node to inject the loaded document into
	*/
	this.ajaxSubmit = function( formId, container )
	{
		var theForm = dojo.byId( formId );
		xhtml.fixupFormAction( theForm )
		dojo.xhrPost(
			{
			  form: theForm,
			  handleAs: "text",
			  load: function(data){
//				 dojo.byId(container).innerHTML = data;
				xhtml.handleAjaxLoad( data, container );
			  },
			  error: function(error,ioArgs){
//				 dojo.byId(container).innerHTML = "An unexpected error occurred: " + error;
				 xhtml.handleAjaxError( error, ioArgs, container );
			  }
			}
		);
	}
	/**
	* Submits the form and injects the returned content into the specific container
	*
	* @param		formId			The id of the form to submit
	* @param		container		The id of the container node to inject the loaded document into
	*/
	this.ajaxSubmitWithFile = function( formId, container )
	{
		var theForm = dojo.byId( formId );
		xhtml.fixupFormAction( theForm )
		dojo.io.iframe.send( 
		{
			form: theForm,
			handleAs: "text",
			load: function(data){
//				dojo.byId(container).innerHTML = data;
				xhtml.handleAjaxLoad( data, container );
			},
			error: function(error,ioArgs){
//				dojo.byId(container).innerHTML = "An unexpected error occurred: " + error;
				xhtml.handleAjaxError( error, ioArgs, container );
			}
		}
		);
	}
	this.fixupFormAction = function( theForm )
	{
		if ( theForm.action.indexOf( "isAjax" ) < 0 ) // add isAjax parm
		{
			if ( theForm.action.indexOf( "?" ) < 0 )
			{
				theForm.action = theForm.action + "?";
			}
			else
			{
				theForm.action = theForm.action + "&";
			}
			theForm.action = theForm.action + "&isAjax=1";
		}
	}

	/**
	* Hides the site notice bar
	*/
	this.hideSiteNotice = function()
		{
		dojo.fadeOut(
				{
				node: 'globalSiteNotice',
				onEnd: function()
					{
					// Remove the notice
					dojo.destroy('globalSiteNotice');

					// Set a cookie so we know not to redisplay it
					dojo.cookie('sitenotice', 'false', {expires: 365});
					}
				}
			).play();
		}



	/**
	* Scrolls the members bar profiles
	*
	* @param		direction			The direction to scroll
	*/
	this.sectionMembersBar = function(direction)
		{
		// Initialize the scrolling
		if (!xhtml.membersBarSettings)
			{
			xhtml.membersBarSettings = {
				locked: false,
				itemWidth: 178,
				maximum: 0,
				count: dojo.query('#membersBarArtboard div.profileItem').length
				}
			if (5 < xhtml.membersBarSettings.count)
				{
				xhtml.membersBarSettings.maximum = (xhtml.membersBarSettings.count - 5) * xhtml.membersBarSettings.itemWidth * -1;
				dojo.query('#sectionMembersBar a.buttonNext').className = 'buttonNext';
				}
			document.getElementById('membersBarArtboard').style.left = '0px';
			}


		// Check we can scroll
		if (xhtml.membersBarSettings.maximum == 0 || xhtml.membersBarSettings.locked == true)
			{
			return;
			}

		// Calculate new scroll position
		var position = parseInt(document.getElementById('membersBarArtboard').style.left);
		switch (direction)
			{
			case 'left':
				position += (xhtml.membersBarSettings.itemWidth * 4);
				break;

			case 'right':
				position -= (xhtml.membersBarSettings.itemWidth * 4);
				break;
			}

		// Bound the new position
		if (position < xhtml.membersBarSettings.maximum)
			{
			position = xhtml.membersBarSettings.maximum;
			}
		if (0 < position)
			{
			position = 0;
			}

		// Update the buttons
		document.getElementById('membersBarPrev').className = 'buttonPrev';
		document.getElementById('membersBarNext').className = 'buttonNext';
		if (position == xhtml.membersBarSettings.maximum)
			{
			document.getElementById('membersBarNext').className = 'buttonNext buttonNextDisabled';
			}
		if (position == 0)
			{
			document.getElementById('membersBarPrev').className = 'buttonPrev buttonPrevDisabled';
			}

		// Scroll to the new position
		xhtml.membersBarSettings.locked = true;
		dojo.animateProperty(
				{
				node: 'membersBarArtboard',
				duration: 500,
				properties:
					{
					left: position
					},
				onEnd: function()
					{
					xhtml.membersBarSettings.locked = false;
					}
				}
			).play();
		}


	/**
	* Toggles the state of a faq node
	*
	* @param		obj		The list item to toggle
	*/
	this.sectionFaq = function(obj)
		{
		if (obj.parentNode.parentNode.className == 'expanded')
			{
			obj.parentNode.parentNode.className = 'collapsed';
			}
		else
			{
			obj.parentNode.parentNode.className = 'expanded';
			}
		}


	/**
	* Toggles a settings block
	*
	* @param			obj			The anchor clicked on
	* @param			reset			Whether to reset the form
	*/
	this.sectionSettingsItem = function(obj, reset)
		{
		// Get the settingsItem node
		var settingsItem = obj.parentNode;
		while (settingsItem.parentNode && settingsItem.className.indexOf('settingsItem') == -1)
			{
			settingsItem = settingsItem.parentNode;
			if (settingsItem.className.indexOf('settingsList') != -1)
				{
				break;
				}
			}

		// Toggle the settingsItem's state
		if (settingsItem.className.indexOf('collapsed') != -1)
			{
			settingsItem.className = settingsItem.className.replace('collapsed', 'expanded');

			// Collpase all other settings items in the list
			var divs = settingsItem.parentNode.getElementsByTagName('div');
			for (var x = 0; x < divs.length; x++)
				{
				if (divs[x].className.indexOf('settingsItem') != -1 && divs[x] !== settingsItem)
					{
					divs[x].className = divs[x].className.replace('expanded', 'collapsed');
					}
				}
			}
		else
			{
			settingsItem.className = settingsItem.className.replace('expanded', 'collapsed');
			}

		// Reset the form, if a reset was specificed
		if (reset && 0 < settingsItem.getElementsByTagName('form').length)
			{
			settingsItem.getElementsByTagName('form')[0].reset();
			}
		}
	}



/**
* Inherts a prototype from the specified class, updates the constructor reference
*
* @param		parent		The parent class or object
* @return		The inherted object
*/
Function.prototype.inheritsFrom = function( baseClass )
	{
	// Inherit the base class
	this.prototype = new baseClass;
	this.prototype.constructor = this;

	// Add access to the base's methods
	this.prototype.base = {};
	for (method in this.prototype)
		{
		// hasOwnProperty test is a workaround for "for..in" bug, see: http://yuiblog.com/blog/2006/09/26/for-in-intrigue/
		if (typeof this.prototype[method] === 'function' && this.prototype.hasOwnProperty(method) && this.prototype[method] !== this.prototype.constructor)
			{
			this.prototype.base[method] = this.prototype[method];
			}
		}
	return this;
	}