/* Elementric  ::  A modular, UX-focused web application framework by Phillip Luther
 * --------------------------------------------------------------------------------------------
 * Elementric is distributed under the terms of the GNU General Public License.
 * Copyright 2011 by Phillip Luther
 * 
 * Documentation, extensions, and download information available at elementric.org
 */

	/*
	 * @constructor
	 *
	 * @description	:
	 *	Contains various methods for form handling, validation, and processing.
	 */
dojo.declare('EL_formHandler', null, {


		/*
		 * @param	: {string} a form ID
		 * @param	: {string} an optional notification area ID
		 * @param	: {string} an optional customized "success" notification
		 *
		 * @description	:
		 *	Captures POST requests from the given form and submits them asynchrously.
		 */
	aSyncUp : function( formId, notificationId, customSuccessNotification) {

			/*
			 * @param	: {object} a form node
			 *
			 * @return	: {object} a notification node
			 *
			 * @description	:
			 *	Constructor class-private method that creates, appends and returns a notification node
			 *	from the given form ID.
			 */
		function createNotificationNode( formNode)
		{
					//first, create our notification area ID
			var 	notificationId = formNode.id + '_notificationArea',

					//and create our node
				notificationNode = dojo.create('div', {
									class	: 'notification-area hidden',
									id	: notificationId
				});

				//then, place the node immediately above our form
			dojo.place( notificationNode, formNode, 'before');
			
				//now that our node exists in the DOM, capture and return it
			return dojo.byId( notificationId);
		}

			/*
			 * @param	: {object} an array of required form fields
			 *
			 * @return	: {boolean} a "success" flag
			 *
			 * @description	:
			 *	Simple validation to ensure all required form fields have values
			 */
		function validateFormFields( requiredFields)
		{
				//default
			var validSubmission = true;

				//if there are no required fields, simply send an "all clear" flare
			if ( requiredFields.length === 0)
			{
				return true;
			}

				//cycle through each given field and ensure it contains a value
			for ( var i = requiredFields.length; i--; )
			{
				var containsHTML = (requiredFields[i].value.indexOf('<') >= 0);

				if ((requiredFields[i].value.length < 1) || containsHTML)
				{
						//if we find an empty required field or something containing HTML, flag it
					if ( validSubmission)
					{
						validSubmission = false;

							//create and place our error notification, if it hasn't been placed already
						if ( ! ( errorNode = dojo.byId( formNode.id + '_error')))
						{
							errorNode = dojo.create( 'p', {
							
								class	: 'bold',
								id	: formNode.id + '_error'
							});
						}

						if (containsHTML) {
							
							errorNode.innerHTML = 'Cool it with the HTML. It\'s not allowed in form submissions.';
						
						} else {

							errorNode.innerHTML = 'A few required fields were left blank. They are marked in red below.';
						}

						dojo.place( errorNode, formNode, 'before');
					}

						//differentiate this field with a class
					dojo.addClass( requiredFields[i].parentNode, 'invalid');
				}
			}

				//kick back whether all's well ... or not
			return validSubmission;
		}

			/*
			 * @param	: {object} a form node
			 * @param	: {object} the given form's corresponding notificaiton node
			 * @param	: {string} an optional customized "success" notification
			 *
			 * @return	: {object} an XHR config object
			 *
			 * @description	:
			 *	Builds and returns our XHR config object for asynchronous form submission.
			 */
		function buildXhrConfig( formNode, notificationNode, customSuccessNotification)
		{
					//create and store our default success/failure messages
			var notifications = {	

				success	: ( typeof( customSuccessNotification) === 'undefined')	
					
					? '<span class="heading-7">Thanks for the commentary and your thoughts.</span>'
					: customSuccessNotification,

				failure	: '<p><strong>Something went awry; try posting your thoughts again, as it was probably a fluke.</strong></p>'
			};

			var xhrConfig = {
							//the basics
						form		: formNode,
						handleAs	: 'text', 
						timeout		: 4000,

							//on success ...
						load		: function( data) {
							
								//flag and update our notification area
							notificationNode.innerHTML = notifications.success;

							dojo.addClass( notificationNode, 'success');

								//hide the form
							dojo.addClass( formNode, 'hidden');
						},

							//on failure ...
						error		: function( data) {
								
								//something's wrong; flash an error
							notificationNode.innerHTML += notifications.failure;

							dojo.addClass( notificationNode, 'failure');
						}
			}

			return xhrConfig;
		}


				//grab our form and relevant nodes from the DOM
		var 	formNode = dojo.byId( formId),
		
				//were we given an explicit notification node? if not, create one
			notificationNode = ( notificationId)	? dojo.byId( notificationId)
								: createNotificationNode( formNode);
		

			//make a connection to our form
		dojo.connect( formNode, 'onsubmit', function(e) {

				//prevent the default event
			dojo.stopEvent(e);

					//gather up any required fields
			var	requiredFields = dojo.query( '.required', formNode),

					//validate our fields
				validSubmission = validateFormFields( requiredFields),

					//placeholders for use below
				errorNode,
			 	xhrConfig,
				transmit;

				//if the form passes validation, submit it
			if ( validSubmission)
			{
				xhrConfig = buildXhrConfig( formNode, notificationNode, customSuccessNotification);

				transmit = dojo.xhrPost( xhrConfig);
			}
		});
	}
});

	//load our constructor class
var formHandler = new EL_formHandler();

