/**
* Global JavaScript Definitions
*
* @author				Matt Gifford
* @copyright			2010 Timeshifting Interactive Limited
* @version			2.0
*/

var viewHandler = WebPage;
var onloadHandler = 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();
	}

// Queue onload handler
if (typeof(dojo) != 'undefined') dojo.addOnLoad(onloadHandler);
else if (typeof(YAHOO) != 'undefined') YAHOO.util.Event.onDOMReady(onloadHandler);
else if (typeof(window.jQuery) != 'undefined') $(document).ready(onloadHandler);
else window.onload = onloadHandler;



/**
* Creates a new WebPage object with methods used by all pages, can be extended to add page specific methods.
*
* @author				Matt Gifford
* @copyright			2010 Timeshifting Interactive Limited
*/
function WebPage()
	{
	// Step 1. Define Properties

	var _instance = this;
	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()
		{
		// Store the page language
		this.lang = document.body.className.indexOf('en') != -1 ? 'en' : 'fr';

		// Initialize the zero copy library
		ZeroClipboard.setMoviePath('http://www.projectimgnation.com/javascript/zeroclipboard/ZeroClipboard.swf');

		// Preload UI graphics
		this.preloadCache = [];
		var images = ['global-elements-ajax-loading-001.gif','share-dialog-bg-i8a8.png','submitted-dialog-bg-i8a8.png','global-elements-icon-button-close.png','mural-canvas-view-bg.png'];
		for (var x = 0, node = null; x < images.length; x++)
			{
			node = document.createElement('img');
			node.src = '/images/' + images[x];
			this.preloadCache.push(node);
			}

		// Initialize page elements
		this.initAnchors();
		this.initInputButtons();
		}


	/**
	* Adds standard event handlers to process in-page links and offsite links
	*/
	this.initAnchors = function()
		{
		var links = document.getElementsByTagName('a');
		for (var x = 0; x < links.length; x++)
			{
			// 1. Make offsite links and pdfs open in a new tab/window
			if (/\b(offsite|pdf)\b/.exec(links[x].className))
				{
				links[x].onclick = function()
					{
					window.open(this.href,'_blank');
					return false;
					}
				}

			// 2. Set the active class on links to the current page
			if ((links[x].href == window.location.href || links[x].href == window.location.href + 'index.html') && links[x].href.indexOf('#') == -1)
				{
				if (links[x].className.indexOf('active') == -1)
					{
					links[x].className += ' active';
					}
				}
			}
		}



	/**
	* Adds rollover support to input[type=image] elements
	*/
	this.initInputButtons = function()
		{
		var rolloverCache = [];
		var inputs = document.getElementsByTagName('input');
		for (var x = 0; x < inputs.length; x++)
			{
			// Check if it's an image button with a roll over
			if (inputs[x].type == 'image' && inputs[x].className.indexOf('hasRollover') != -1)
				{
				// 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 murl page after fb login
	*/
	this.login = function()
		{
//		// Set the redirect url
//		if (this.lang == 'en')
//			{
//			var loginUrl = 'http://www.projectimgnation.com/en/mural';
//			}
//		else
//			{
//			var loginUrl = 'http://www.projectimgnation.com/fr/mural';
//			}
//
//		// Load the mural page
//		setTimeout("window.location='" + loginUrl + "';", 50);
		window.location.reload(true);
		}

	
	/**
	* Logs out the current user
	*/
	this.logout = function()
		{
		var logoutUrl = 'http://www.projectimgnation.com/logout';

		// Logout based on connect type
		if (document.body.className.indexOf('facebookUser') != -1)
			{
			FB.Connect.logoutAndRedirect(logoutUrl);
			}
		else
			{
			window.location = logoutUrl;
			}
		}


	/**
	* Shares the title
	*
	* @param		method		The share method to use
	* @return		void
	*/
	this.share = function(method)
		{
		var url = !!document.getElementById('ajaxFacebookUrl') ? document.getElementById('ajaxFacebookUrl').innerHTML : 'http://www.projectimgnation.com/';
		switch (method)
			{
			case 'facebook':
				if (confirm(this.lang == 'en' ? 'Would you like to post this item to Facebook?' : 'Souhaitez-vous afin d\'envoyer cet article à Facebook?') == true)
					{
					window.open('http://www.facebook.com/sharer.php?u=' + encodeURIComponent(url), '_blank');
					}
				break;

			case 'twitter':
				if (confirm(this.lang == 'en' ? 'Would you like to post this item to Twitter?' : 'Souhaitez-vous afin d\'envoyer cet article à Twitter?') == true)
					{
					if (this.lang == 'en')
						{
						window.open('http://twitter.com/home?status=' + encodeURIComponent('I just entered the Future Shop #projectimgnation Contest! ' + url), '_blank');
						}
					else
						{
						window.open('http://twitter.com/home?status=' + encodeURIComponent('Je viens tout juste de m\'inscrire au concours #projetimgnation de Future Shop! ' + url), '_blank');
						}
					}
				break;
			}
		}


	/**
	* Validates the params object
	*
	* @param		obj			The description object of the form to validate
	* @return		void
	*/
	this.validateForm = function(obj)
		{
		// Check the object is actually an object
		if (typeof(obj) != 'object')
			{
			return false;
			}

		// Get the form fields
		var form = dojo.byId(obj.form);
		var fields = {
			inputs: form.getElementsByTagName('input'),
			selects: form.getElementsByTagName('select'),
			textareas: form.getElementsByTagName('textarea')
			};

		// Validate the fields
		var previousFieldValue = '';
		for (var x = 0; x < obj.required.length; x++)
			{
			// Check the text input fields
			for (var y = 0; y < fields.inputs.length; y++)
				{
				// Text and password fields
				if (fields.inputs[y].name == obj.required[x].name && (fields.inputs[y].type == 'text' || fields.inputs[y].type == 'password'))
					{
					// Check it has a value
					if (fields.inputs[y].value.length < 1)
						{
						// Display an error message that the field can't be blank
						if (this.lang == 'en') alert(('Please fill out the %s field').replace('%s', obj.required[x].title));
						else alert(('S\'il vous plaît remplir le champ %s').replace('%s', obj.required[x].title));
						return false;
						}

					// Check it has a value matches previous
					if (!!obj.required[x].filter && obj.required[x].filter == 'matchPrevious')
						{
						if (fields.inputs[y].value != previousFieldValue)
							{
							// Display an error message that the field must match
							if (this.lang == 'en') alert(('The %s field does not match').replace('%s', obj.required[x].title));
							else alert(('Le champ %s ne correspond pas').replace('%s', obj.required[x].title));
							return false;
							}
						}

					// If it's a postcode, check it's valid
					if (!!obj.required[x].filter && obj.required[x].filter == 'postcodeCA')
						{
						var regex = /^[a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][- ]?[a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9]$/i;
						if (regex.test(fields.inputs[y].value) == false)
							{
							if (this.lang == 'en') alert(('Please ensure the %s field is valid. e.g. L4W 1S2').replace('%s', obj.required[x].title));
							else alert(('S\'il vous plaît assurer le champ du %s est valide. par exemple, L4W 1S2').replace('%s', obj.required[x].title));
							return false;
							}
						}

					// If it's a phone number
					if (!!obj.required[x].filter && obj.required[x].filter == 'phoneUS')
						{
						fields.inputs[y].value = fields.inputs[y].value.replace(/\D+/g, '');
						if (fields.inputs[y].value.length != 10)
							{
							if (this.lang == 'en') alert(('Please enter your %s, it should be 10 digits long.').replace('%s', obj.required[x].title));
							else alert(('S\'il vous plaît entrer votre %s, il devrait être de 10 chiffres.').replace('%s', obj.required[x].title));
							return false;
							}
						}

					// If it's an email address, check it's valid
					if (!!obj.required[x].filter && obj.required[x].filter == 'email')
						{
						var regex = /^[a-z0-9_+-.]+@[a-z0-9_-]*\.?[a-z0-9_-]*\.?[a-z0-9_-]*\.[a-z]+$/i;
						if (regex.test(fields.inputs[y].value) == false)
							{
							if (this.lang == 'en') alert(('Please ensure the %s field is a valid email address').replace('%s', obj.required[x].title));
							else alert(('S\'il vous plaît assurer le champ du %s est une adresse email valide').replace('%s', obj.required[x].title));
							return false;
							}
						}

					// If it's a multiple email address field, check the addresses are valid
					if (!!obj.required[x].filter && obj.required[x].filter == 'emailMultiple')
						{
						// Make sure the multiple addresses are comma separated
						fields.inputs[y].value = fields.inputs[y].value.replace(';', ',');

						// Validate the addresses
						var emailAddressesValid = true;
						var regex = /^[a-z0-9_+-.]+@[a-z0-9_-]*\.?[a-z0-9_-]*\.?[a-z0-9_-]*\.[a-z]+$/i;
						var addresses = fields.inputs[y].value.split(',');
						for (var z = 0; z < addresses.length; z++)
							{
							if (regex.test(dojo.trim(addresses[z])) == false)
								{
								emailAddressesValid = false;
								}
							}
						if (emailAddressesValid == false)
							{
							if (this.lang == 'en') alert(('Please ensure the email addresses in the %s field are valid').replace('%s', obj.required[x].title));
							else alert(('S\'il vous plaît assurer les adresses email dans le champ %s sont valables').replace('%s', obj.required[x].title));
							return false;
							}
						}
					}

				// Checkbox/radio fields, check it has been checked
				if (fields.inputs[y].name == obj.required[x].name && (fields.inputs[y].type == 'radio' || fields.inputs[y].type == 'checkbox') && fields.inputs[y].checked == false)
					{
					// Display an error message that the field can't be blank
					alert(obj.required[x].title);
					return false;
					}

				// Store the current field's value
				previousFieldValue = fields.inputs[y].value;
				}

			// Check the select fields
			for (var y = 0; y < fields.selects.length; y++)
				{
				// If the field name matches, check it has a selection other than the default
				if (fields.selects[y].name == obj.required[x].name && fields.selects[y].selectedIndex == 0)
					{
					// Display an error message that the field can't be left unchosen
					if (this.lang == 'en') alert(('Please select a %s').replace('%s', obj.required[x].title));
					else alert(('S\'il vous plaît sélectionnez un %s').replace('%s', obj.required[x].title));
					return false;
					}
				}

			// Check the textarea fields
			for (var y = 0; y < fields.textareas.length; y++)
				{
				// If the field name matches, check it has a value
				if (fields.textareas[y].name == obj.required[x].name && fields.textareas[y].value.length < 1)
					{
					// Display an error message that the field can't be blank
					if (this.lang == 'en') alert(('Please fill out the %s field').replace('%s', obj.required[x].title));
					else alert(('S\'il vous plaît remplir le champ %s').replace('%s', obj.required[x].title));
					return false;
					}
				}
			}

		// Form passes validation, so return true
		return true;
		}
	}



/**
* 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;
	}
