/**
 * 
 * 
 * ---------------------------------------------------------------------------
 * 
 * Copyright (C) 2007 Omnium Research Group
 * 
 * ---------------------------------------------------------------------------
 * 
 * LICENSE:
 * 
 * This file is part of Omnium(R) Software.
 * 
 * Omnium(R) Software is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * Omnium(R) Software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with Omnium(R) Software; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 * 
 * ---------------------------------------------------------------------------
 * 
 * @author    Dan Callaghan <dan@omnium.net.au>
 * @copyright 2007 Omnium Research Group
 * @license   http://www.gnu.org/licenses/gpl.txt GNU GPL v2
 * @link      http://open.omnium.net.au Omnium Open
 **/



var omForm = {};

omForm = Class.create();
omForm.prototype = {
	initialize: function(formId, submitButtonId, uploadProgressId, activeImg, fileInputs, multipleFileInputs, focusTarget)
	{
		// Initialise the form object
		this.formObj = $(formId);
		
		// Set the IDs of the submit button and upload progress
		this.submitButton = $(submitButtonId);
		this.uploadProgress = $(uploadProgressId);
		
		// Check to see if an active image has been specified
		if (activeImg) {
			// Initialise the active background image
			this.activeImg = 'url(' + activeImg + ')';
		}
		
		// Initialise an array of any file inputs for Safari hack
		this.fileInputs = fileInputs;
		this.multipleFileInputs = multipleFileInputs;
		
		// Add a submit event listener to the form
		Event.observe(this.formObj, 'submit', this.submit.bindAsEventListener(this));
		
		if (this.activeImg) {
			
			// Traverse through the immediate descendants of the form
			formElements = this.formObj.getElementsBySelector('input', 'select', 'textarea');
			for (var f = 0; f < formElements.size(); f++) {
				// Add event listeners to the form elements
				Event.observe(formElements[f], 'focus', this.focus.bindAsEventListener(this));
				Event.observe(formElements[f], 'blur', this.blur.bindAsEventListener(this));
			};
			
		}
		
		// Add event listeners for submit button
		Event.observe(this.submitButton, 'mouseover', this.hover.bindAsEventListener(this));
		Event.observe(this.submitButton, 'mouseout', this.hover.bindAsEventListener(this));
		
		if (focusTarget) {
			if (focusTarget != 'none') {
				focusTarget = $(focusTarget);
			} else {
				focusTarget = false;
			}
		} else {
			// Find the first form element
			focusTarget = this.formObj.firstDescendant().getElementsBySelector('input', 'select', 'textarea')[0];
		}
		
		if (focusTarget) {
			focusTarget.focus();
		}
	},
	
	// Gives focus to a form element div
	focus: function(e)
	{
		// Initialise the form element object variable
		var formElementObj;
		
		// Check whether we are dealing with an event
		if (e.target) {
			formElementObj = e.target;
		} else {
			formElementObj = e;
		}
		
		// Set the current element as active
		divObj = formElementObj.up('.omFormContainer');
		divObj.setStyle({backgroundImage: this.activeImg});
		
		if (this.activeObj) {
			
			if (this.activeObj != divObj) {
				// Set the active object as inactive and set the new active object
				this.activeObj.setStyle({backgroundImage: 'none'});
			}
			
		}
		
		this.activeObj = divObj;
	},
	
	// Blurs a form element div
	blur: function(e)
	{
		divObj = e.target.up('.omFormContainer');
		divObj.setStyle({backgroundImage: 'none'});
	},
	
	// Sets the focus for a specific element
	setFocus: function(formElement)
	{
		tabElement = $(formElement).up('.tab');
		if (tabElement) {
			if (!tabElement.visible()) {
				tabElement.show();
			}
		}
		$(formElement).activate();
	},
	
	// Deals with hovering of the submit button
	hover: function(e)
	{
		if (e.type == 'mouseover') {
			e.target.setStyle({backgroundPosition: '0 -17px'});
		} else {
			e.target.setStyle({backgroundPosition: '0 0'});
		}
	},
	
	// A function which executes when the form is submitted
	submit: function(e)
	{
		
		if (this.uploadProgress) {
			// Hide the submit button and show the upload progress meter
			this.submitButton.hide();
			this.uploadProgress.show();
		}
		
		// Workaround for Safari not upload files which are hidden
		if (this.fileInputs) {
			for (var i = 0; i < this.fileInputs.length; i++) {
				if (!$(this.fileInputs[i]).visible()) {
					$(this.fileInputs[i]).setStyle({
						display: 'block',
						position: 'absolute',
						left: '-9999px'
					});
				}
				if (this.multipleFileInputs) {
					$(this.fileInputs[i]).immediateDescendants().each(
						function (fileInputObj) {
							if (!fileInputObj.visible()) {
								fileInputObj.show();
								fileInputObj.setStyle({
									display: 'block',
									position: 'absolute',
									left: '-9999px'
								});
							}
						}
					);
				}
			};
		}
		
	}
	
}


omForm.ErrorChecker = Class.create();
omForm.ErrorChecker.prototype = {
	initialize: function(errorArray, messageArray, errorSrc, errorBubble)
	{
		
		// Initialise the array of element id with an error
		this.errorArray = errorArray;
		
		// Initialise the corresponding messages
		this.messageArray = messageArray;
		
		// Initialise the error icon image source
		this.errorSrc = errorSrc;
		
		if (errorBubble) {
			// Initialise the error bubble image source
			this.errorBubble = 'url(' + errorBubble + ')';
		}
		
		this.createMessages();
	},
	
	createMessages: function()
	{
		// Initialise an error icon for later use
		var eIconObj = new Element('img', { src: this.errorSrc, className: 'errorIcon' });
		
		// Traverse through the error elements
		for (var i = 0, eLen = this.errorArray.length; i < eLen; ++i) {
			
			// Extend our current error object
			var e = $(this.errorArray[i]);
			
			// Check for associated subtab
			var subtabObj = e.up('.subtabs');
			
			// Check for associated tab
			var tabObj = e.up('.tab');
			
			// Initialise the class name
			var errorClass = 'formError';
			
			// Check for narrow class name
			if (e.hasClassName('narrow')) {
				errorClass += ' narrow';
			}
			
			if (subtabObj) {
				// Find the file number
				var fileNum = 'File ' + e.up('.imageContainer').id.split("_")[1] + ': ';
				
				// Build the error message for our subtab
				var eIcon = eIconObj.cloneNode(true);
				var eMessage = new Element('p', { className: errorClass });
				
				// Create the message element. Consists of Icon + Message inside of a paragraph element
				var E = eSubMessage.insert(eIcon).insert(fileNum + this.messageArray[i]);
				
				subtabObj.insertBefore(E, subtabObj.firstDescendant());
			}
			
			// Build the error message for our tab
			var eIcon = eIconObj.cloneNode(true);
			var eMessage = new Element('p', { className: errorClass });
			
			// Create the message element. Consists of Icon + Message inside of a paragraph element
			var E = eMessage.insert(eIcon).insert(this.messageArray[i]);
			
			if (this.errorBubble) {
				// Set the current element as active
				divObj = e.up('.omFormContainer').setStyle({ backgroundImage: this.errorBubble });
			}
			
			// Get our container object and insert the new error message element (E) into our current error element (e)
			containerObj = e.parentNode;
			containerObj.insertBefore(E, e);
			
		}
		
	}
}

// Gets the associated timezones when a user's location is changed
function getTimezones(locationSelect, timezoneSelect, current, ajaxFile)
{
	var location = locationSelect.options[locationSelect.options.selectedIndex].value;
	var params = 'location=' + encodeURIComponent(location);
	params += '&current=' + encodeURIComponent(current);
	
	new Ajax.Updater(
		timezoneSelect,
		ajaxFile,
		{ parameters:params }
	);
}