function VarsObj() {}

function formObj( formName )
{
	var obj = $L.object( this );

	/*  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
	 *  public member variables
	 */

	obj.formName = formName;
	obj.form = document.forms[obj.formName];
	obj.field = '';
	obj.fieldVal = '';
	obj.jqf = null;


	/*  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
	 *  private member variables
	 */

	obj._button = $jq("form[name='"+ obj.formName +"'] input[type='submit']");


	/*  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
	 *  public member functions
	 */

	/*  form is submitted
	 */
	obj.submit = function()
	{
		obj._hideMessages();
		obj._clearAlerts();

		this.fieldsVals = obj._getFieldsVals();
		if( this.fieldsVals ) {
			this.sender = new obj._ajaxObj(obj.formName, this.fieldsVals);
			this.sender.request();
			return false;
		} else {
			return false;
		}
	}

	/*  does string match email format?
	 */
	obj.emailFormatOk = function()
	{
		var emailFormat = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
		if( obj.fieldVal.match(emailFormat) ) {
			return true;
		} else {
			return false;
		}
	}

	/*  does string match phone number format?
	 */
	obj.phoneFormatOk = function()
	{
		var phoneFormat = /^(\+\d)*\s*((\(\d{3}\)|\d{3})\s*)*[\s\-]{0,1}\d{3}(-{0,1}|\s{0,1})\d{2}(-{0,1}|\s{0,1})\d{2,6}(.)*?$/;
		obj.fieldVal = obj.fieldVal.replace(/\./g, "-");
		if( obj.fieldVal.match(phoneFormat) ) {
			return true;
		} else {
			return false;
		}
	}

	/*  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
	 *  private member functions
	 */

	/*  get form data as json
	 */
	obj._getFieldsVals = function()
	{
		obj.fieldsVals = new VarsObj();
		obj._disable();

		for( i=0; i<obj.form.length; i++ ) {
			obj.field = obj.form[i];
			obj.fieldVal = obj._getFieldVal();

			if( !obj._reqOK() ) {
				obj._missingReqVal();
				return false;

			} else if( obj.fieldVal.length > 0 && (
				( $jq(obj.jqf).hasClass('email') && !obj.emailFormatOk() ) ||
				( $jq(obj.jqf).hasClass('phone') && !obj.phoneFormatOk() )
			)) {
				obj._enable();
				obj._fieldMsg( obj.field.name, obj.jqf.attr('formatMsg') );
				obj.field.select();
				return false;

			} else if( obj.jqf.hasClass('send') ) {
				obj.fieldsVals[obj.field.name] = obj.fieldVal;  //escape(value) ?
			}
		}
		return obj.fieldsVals;
	}

	/*  get form field value
	 */
	obj._getFieldVal = function()
	{
		obj.jqf = $jq( obj.field );
		obj.field.name = obj.jqf.attr('name');
		obj.field.title = (obj.jqf.attr('title'))? obj.jqf.attr('title') : '';

		if( obj.jqf.is('input') ) {
			switch( obj.jqf.attr('type') ) {
				default:
				case 'text':
				case 'hidden':
				case 'password':
					return obj.jqf.val();
				break;
	
				case 'radio':
					radioVal = $jq('form[name="'+ obj.formName +'"] [name="'+ obj.field.name +'"]:checked').val();
					if( radioVal==undefined ) { return ''; }
					else { return radioVal; }
				break;
	
				case 'checkbox':
					if( obj.jqf.attr('checked') != true ) {
						return 0;
					} else {
						return true;
					}
				break;
			}
		} else if ( obj.jqf.is('select') || obj.jqf.is('textarea') ) {
			return obj.jqf.val();
		}
		return false;
	}

	/*  is form field required & filled?
	 */
	obj._reqOK = function()
	{
		if( obj.jqf.hasClass('req')==1 && ( obj.fieldVal=='' || obj.fieldVal==false || ( obj.jqf.type=='checkbox' && !$jq(obj.jqf).attr('checked') ) ) ) {
			return false;
		} else {
			return true;
		}
	}

	/*  what to do if a required value is missing
	 */
	obj._missingReqVal = function()
	{
		obj._enable();
		obj._fieldMsg( obj.field.name, obj.field.title );
		return false;
	}

	/*  enable the form
	 */
	obj._enable = function()
	{
		$jq("form[name='"+obj.formName+"'] *").attr('disabled',false);
		obj._buttonActivate();
	}

	/*  disable the form
	 */
	obj._disable = function()
	{
		$jq("form[name='"+obj.formName+"'] *").attr('disabled',true);
		obj._buttonDeactivate();
	}

	/*  activate the form submission button
	 */
	obj._buttonActivate = function()
	{
		obj._button.bind('click', function() {
			obj.submit();
			return false;
		});
		obj._button.css('cursor','pointer');
	}

	/*  deactivate the form submission button
	 */
	obj._buttonDeactivate = function()
	{
		obj._button.unbind('click');
		obj._button.css('cursor','wait');
		return false;
	}

	/*  show a message pertaining to a field
	 */
	obj._fieldMsg = function( fieldName, msg )
	{
		var jqField = $jq('form[name="'+obj.formName+'"] *[name="'+fieldName+'"]');
		//var domField = obj.form.elements[fieldName];
	
		if( msg==null ) {
			msg = jqField.attr('title');
		}
		obj._createMsgSpot( fieldName );
		obj._showMsg( fieldName+'Msg', msg );

		if( jqField.is('input') || jqField.is('textarea') ) {
			jqField.focus();
			jqField.addClass('alert')
		}

		return false;
	}

	/*  show a message related to the form
	 */
	obj._showMsg = function( id, msg )
	{
		var msgBox = $jq('#'+id);
		if( msg!= '') { msgBox.html( msg ); }

		msgBox.css('display','block');
		msgBox.animate( { opacity:1 }, 750 );

		return false;
	};

	/*  create a div to hold/show a message
	 */
	obj._createMsgSpot = function( fieldName )
	{
		if( $jq('div#'+fieldName+'Msg.formMsg').length==0 ) {

			this.parent = $jq('form[name="'+obj.formName+'"] *[name="'+fieldName+'"]').parent();
			this.parent.append('<div id="'+fieldName+'Msg" class="formMsg">&#133;<\/div>');
		}
		return $jq('div#'+fieldName+'Msg');
	}

	/*  hide submission messages
	 */
	obj._hideMessages = function()
	{
		$jq('form[name="'+obj.formName+'"] div.formMsg').each( function() {
			if( !$jq(this).hasClass('keep') ) {
				$jq(this).remove();
			}
		});
		return false;
	}

	/*  clear alert classes from inputs and textareas
	 */
	obj._clearAlerts = function()
	{
		$jq('form[name="'+obj.formName+'"] input.alert').each( function() {
			$jq(this).removeClass('alert');
		});
		$jq('form[name="'+obj.formName+'"] textarea.alert').each( function() {
			$jq(this).removeClass('alert');
		});
		return false;
	}

	/*  what to do with the data returned
	 */
	obj.handleResponse = function( response )
	{
		if( response.result=='success' ) {
			obj._handleSuccess( response );
		} else {
			obj._handleFailure( response );
		}
	}

	obj._handleSuccess = function( response )
	{
		obj._fieldMsg('submit');
		obj._button.css('display','none');
		obj._disable();
		return false;
	}

	obj._handleFailure = function( response )
	{
		obj._fieldMsg('submit', response.error);
		obj._enable();
		return false;
	}

	/*  send form data and receive action response thru ajax
	 */
	obj._ajaxObj = function( formName, formData )
	{
		var jax = this;
		jax.formName = formName;
		jax.formData = formData;

		jax.processError = "We could not process your data submission.\n";
		jax.processError+= "Would you like to email us with your details?";
		jax.processError+= "\n ";
		
		jax.incompleteError = "One or more of the required fields are incomplete.<br/>";
		jax.incompleteError+= "Please check your values above.";
		
		jax.url = $jq("form[name='"+jax.formName+"']").attr('action');
		jax.method = $jq("form[name='"+jax.formName+"']").attr('method');
		if( !jax.method ) { jax.method = 'get'; }
	
		jax.request = function() {
			$jq.ajax({
				url:		jax.url,
				type:		jax.method,
				global:		false,
				dataType:	'json',
				cache:		false,
				timeout:	1000*25,
				data:		jax.formData,
				error: function( request, status, error )
				{
					var doit = confirm( jax.processError );
					if( doit ) {
						//window.location = "mailto:info@lulu.com";
					} else {
						alert("Please try your submission again.");
					}

					if( window.location.href.search(/www.lulu.com/i)==-1 ) {
						alert("this:\n\n"+ this.toSource() );
					}
					return false;
				},
				success: function( response ) {
					obj.handleResponse( response );
					return false;
				}
			});
		}
		return jax;
	}


	return obj;
}
