/*
AJFORM - World's Easiest JavaScript AJAX ToolKit
http://projects.aphexcreations.net/ajform/

Brendon Crawford <info at projects dot aphexcreations dotnet>
Jim Manico <jim at manico dotnet>

## v1.4.5 UPDATED 2007-05-30 ##
## DEPENDS ON PROTOTYPE.JS ##

## BSD LICENSE ##

	Copyright (c) 2005, 2006, 2007 Brendon Crawford
	All rights reserved.

	Redistribution and use in source and binary forms, with or without
	modification, are permitted provided that the following conditions
	are met:
	1. Redistributions of source code must retain the above copyright
	   notice, this list of conditions and the following disclaimer.
	2. Redistributions in binary form must reproduce the above copyright
	   notice, this list of conditions and the following disclaimer in the
	   documentation and/or other materials provided with the distribution.
	3. The name of the author may not be used to endorse or promote products
	   derived from this software without specific prior written permission.

	THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
	IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
	OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
	IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
	INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
	NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
	DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
	THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
	(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
	THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

AJForm = new Object;
	AJForm.VERSION = "1.4.5";
	AJForm.STATUS = {
		'SUCCESS' : 0 ,
		'HTTP_OBJECT_FAILED' : 1 ,
		'FILE_UPLOAD_FAILED' : 2 ,
		'SERVER_ERROR' : 3
	};
	
	/*
		"this" WILL BE A FORM OBJECT
	*/
	AJForm.activateForm = function() {
	 preRetVal = true;
		if( this.ajform.preCallback != null ) {
		 preRetVal = this.ajform.preCallback( this );
		}
		//if the preProcess function returrns false, then we will not send data to the server
		if( preRetVal ) {
		 //form.submit() is mapped to AJForm.submitForm
		 postRetVal = this.ajform_submit();
		 return postRetVal;
		}
		else {
		 return false;
		}
	}
	
	/*
		FORM SUBMISSION:
			submitForm()
		SCRIPTED SUBMISSION:
			form.submitForm( [callbackFunction]] )
			
		ITS IS USEFUL TO KNOW THAT THERE ARE 3 MAJOR PITFALLS THAT CAN BE ENCOUNTERED
		IN BOTH IE AND MOZILLA WHEN DEALING WITH XMLHTTPREQUEST:
			1) DO NOT ATTEMPT TO REUSE THE XMLHTTP OBJECT AFTER A REQUEST. IT MUST BE DESTROYED AND
				A NEW ONE MUST BE CREATED WHEN DOING A NEW REQUEST
			2) USE ASYNCRONOUS DATA WHENEVER POSSIBLE
			3) WHEN USING ASYCRONOUS DATA, ALWAYS SET THE "onreadystatechange" PROPERTY AFTER CALLING
				THE "open()" METHOD.
			4) THE "setRequestHeader" METHOD MUST BE CALLED AFTER THE "onreadystatechange" PROPERTY IS SET 
				AND AFTER THE "open()" METHOD IS CALLED.
	*/
	AJForm.submitForm = function(){
		//if a second argument was specified
		if( arguments.length ) {
		 userFunc =  eval( arguments[0] );
		}
		//if a callback was specified in the form
		else if( this.ajform.postCallback != null ) {
		 userFunc = this.ajform.postCallback;
		}
		//If not a valid callback or no callback at all, then return
		if( (typeof userFunc).toLowerCase() != "function" ) {
		 return true;
		}
		//no action specified
		if( (file = this.getAttribute('action')) == null ) {
		 file = new String( window.location );
		}
	
	 dataStr = "";
	 //construct values
	 childList = this.getElementsByTagName('*');
		for( var e = 0; e < childList.length; e++ ) {
		 thisInput = childList[e];
			//preliminary check : input
			if( thisInput.nodeName.toLowerCase() == 'input' ) {
			 thisElmType = thisInput.getAttribute('type');
			 thisElmType = ( thisElmType == null ) ? 'text' : thisElmType.toLowerCase();
			}
			//preliminary check : button
			else if( thisInput.nodeName.toLowerCase() == 'button' ) {
			 thisElmType = 'button';
			}
			//preliminary check : textarea
			else if( thisInput.nodeName.toLowerCase() == 'textarea' ) {
			 thisElmType = 'textarea';
			}
			//preliminary check : select
			else if( thisInput.nodeName.toLowerCase() == 'select' ) {
			 thisElmType = 'select';
			}
			//preliminary check : unknown
			else {
			 continue;
			}
			//preliminary check : any element - no name
			if( thisInput.name == '' || thisInput.name == 'undefined' ) {
			 continue;
			}
			/********************************
	
				FILE (NOT SUPPORTED)
	
			********************************/
			if( thisElmType == "file" ) {
			 userFuncVal = userFunc( null , AJForm.STATUS['FILE_UPLOAD_FAILED'] , "Unable to handle file uploads." );
			 return userFuncVal;
			}
			/********************************
			
				CHECKBOX, RADIO
			
			********************************/
			else if( thisElmType == "checkbox" || thisElmType == "radio" ) {
				if( !thisInput.checked ) {
				 continue;
				}
			}
			/********************************
			
				SUBMIT IMAGE
			
			********************************/
			else if( thisElmType == "image" || thisElmType == "submit" ) {
				//only include images|submits which were submitted
				if( thisInput != this.ajform.submitter.elm ) {
				 continue;
				}
				//server side image map coordinates
				if( thisElmType == "image" ) {
				 imgConName = thisInput.name;
				 imgConNameX = imgConName + ".x";
				 imgConNameY = imgConName + ".y";
				 imgConValX = new String(this.ajform.submitter.x);
				 imgConValY = new String(this.ajform.submitter.y);
				 dataStr += AJForm.makeArgument(imgConNameX , imgConValX);
				 dataStr += AJForm.makeArgument(imgConNameY , imgConValY);
				}
			}
	
			/********************************
			
				SELECT LIST
				Concept provided by Jim Manico <jim at manico dotnet>
			
			********************************/
			if (thisElmType == 'select') {
				for( var s = 0; s < thisInput.length; s++ ) {
				 thisOption = thisInput.options[s];
					if( thisOption.selected ) {
					 dataStr += AJForm.makeArgument( thisInput.name , thisOption.value);
					}
				}
			}
			/********************************
			
				ALL OTHER ELEMENT TYPES
			
			********************************/
			else {
			 dataStr += AJForm.makeArgument( thisInput.name , thisInput.value);
			}
		}
	
		//set proper request type
	 requestType = this.getAttribute('method');
		if( !requestType || requestType.toLowerCase() != "post" ) {
		 requestType = "get";
		}
		
	/*
		MOZILLA HAS A BUG WHICH WILL THROW AN UNKNOWN ERROR
		IF AN ASYNCORNOUS REQUEST IS ABORTED USING THE abort() METHOD, THE ONREADYSTATECHANGE
		WILL STILL BE CALLED BUT THE responseText, status, and statusText
		PROPERTIES WILL THROW ERRORS. SO TO FIX THIS, WE NEED TO CHECK IF THE REQUEST WAS ABORTED.
	*/
	 new Ajax.Request( file ,
		{
			method : requestType ,
			parameters : dataStr ,
			requestHeaders : { 'X-AJForm-Version' : AJForm.VERSION } ,
			onComplete : 
				function( transport ) {
					if(!transport.aborted) {
					 ret_responseText = transport.responseText;
					 ret_status = transport.status;
					 ret_statusText = transport.statusText;
	
						//get server message
						if( !ret_statusText || !ret_status ) {
						 thisStatusText = "HTTP Code " + ret_status + "\nNo server message available."
						}
						else {
						 thisStatusText = "HTTP Code " + ret_status + "\nServer responded, '" + ret_statusText + "'";
						}
						// only if "OK"
						if(ret_status == 200) {
						 thisStatus = AJForm.STATUS['SUCCESS'];
						 thisMessage =  "Operation completed successfully.\n" + thisStatusText;
						}
						else {
						 thisStatus = AJForm.STATUS['SERVER_ERROR'];
						 thisMessage = "A server error ocurred.\n" + thisStatusText;
						}
					 userFunc( ret_responseText , thisStatus , thisMessage );
					}
	
				}
		}
	 );
	 
	 return false;
	}
	
	AJForm.kill = function( thisDoc ) {
	 thisDoc.aborted = true;
	 thisDoc.abort();
	}
	
	AJForm.makeArgument = function( name, val ) {
		if( !name || name == "") {
		 return "";
		}
	 thisArg = "&" + encodeURIComponent(name) + "=" + encodeURIComponent(val);
	 return thisArg;
	}
	
	AJForm.register = function( thisForm ) {
	 submitStr = AJForm.getAttributeText( thisForm.onsubmit );
		//if an onsubmit attribute exists
		if( submitStr == null ) {
		 return false;
		}
	 submitActionList = submitStr.split( ";" );
	 pre_callback = null;
	 post_callback = null;
		for( s = 0; s < submitActionList.length; s++ ) {
		 arg_post = submitActionList[s].match( /(ajform:)?\s*([A-Za-z0-9\._\$]+)\s*\(.*?\)/ );
			if( RegExp.$1 ) {
			 post_callback = RegExp.$2;
			}
			else if( RegExp.$2 ) {
			 pre_callback = RegExp.$2;
			}
		}
	
		//if this is a specified AJFORM handler
		if( post_callback != null ) {
		 thisForm.ajform = new Object;
		 thisForm.ajform.preCallback = eval(pre_callback);
		 thisForm.ajform.postCallback = eval(post_callback);
		 thisForm.onsubmit = AJForm.activateForm;
		 thisForm.ajform.submitter = new Object;
		 thisForm.ajform.submitter.elm = null;
		 thisForm.ajform.submitter.x = 0;
		 thisForm.ajform.submitter.y = 0;
		 thisForm.ajform_submit = AJForm.submitForm;
	
		 //prepare the submit buttons
		 inputList = thisForm.getElementsByTagName('input');
			for( y = 0; y < inputList.length; y++ ) {
			 thisInput = inputList[y];
			 thisInputType = thisInput.getAttribute( 'type' );
				if( thisInputType == null ) {
				 return false;
				}
				if( thisInputType == 'submit' || thisInputType == 'image' ) {
				 Event.observe( thisInput , 'click' , AJForm.setSubmitStatus );
				}
			}
		}
	 return true;
	}
	
	AJForm.init = function() {
	 //do some compatibility checks
		for( var i = 0; i < document.forms.length; i++ ) {
		 AJForm.register( document.forms[i] );
		}
	}
	
	AJForm.getAttributeText = function( thisAttribute ) {
		if( thisAttribute == 'undefined' || thisAttribute == null ) {
		 return null;
		}
		if( (typeof thisAttribute).toLowerCase() == 'function' ) {
		 attStr = new String(thisAttribute);
		 attStr.match( /{\s*([\s\S]+?)\s*}/ );
		 attText = RegExp.$1;
		}
		else {
		 attText = thisAttribute;
		}
	 return attText;
	}
	
	AJForm.setSubmitStatus = function(e) {
	 thisElm = Event.element(e);
	 xDiff = Event.pointerX(e) - Position.cumulativeOffset(thisElm)[0];
	 yDiff = Event.pointerY(e) - Position.cumulativeOffset(thisElm)[1];
	 thisElm.form.ajform.submitter.elm = thisElm;
	 thisElm.form.ajform.submitter.x = xDiff;
	 thisElm.form.ajform.submitter.y = yDiff;
	}

//SET THE LISTENER TO INITIALIZE THE ACTIONS
Event.observe( window , 'load' , AJForm.init );


 