/**
 * LICENSE
 *
 * This source file is subject to the EWS Software License that is bundled
 * with this package in the file LICENSE.txt.
 * If you did not receive a copy of the license please send us an email
 * so we can send you a copy immediately.
 * Permission to copy and distribute verbatim copies of this source
 * are not granted.
 *
 * @copyright 	Copyright (c) 2008-2009 entrance web studio
 * @license	EWS Software License
 */

// FORM PROTOTYPES

/**
 * Shows or hides the non-required fields from the form.
 *
 * @param Boolean show
 */
HTMLFormElement.prototype.showOrHideNonRequiredFields = function ( hide ) {
	var elems = this.getElements ();
	var n = elems.length;
		
	for ( var i = 0; i < n; i++ ) {
		var elem = elems [ i ];
		
		if ( elem.type == "submit" || elem.type == "button" || elem.type == "hidden" ) {
			return;
		}
		
		if ( elem.readAttribute ( "required" ) == null && hide ) { 
			elem.parentNode.hide ();
		}
		else if ( elem.readAttribute ( "required" ) == null && !hide ) {
			elem.parentNode.show ();
		}
		else {
			continue;
		}
	}
};


/**
 * Reads an newly introduced attribute for form elements. If the required attribute is set the form element
 * must be filled in otherwise the validation fails.
 *
 * @param HTMLFormElement elem
 * @return void
 */	
HTMLFormElement.prototype.validateElement = function ( elem ) {
	// if disabled ignore
	if ( elem.disabled )
		return null;
		
	// check required attribute
	// backward compatibility required:true
	if ( elem.readAttribute ( "required" ) == "required" || elem.readAttribute ( "required" ) == "true" ) {
		// input is invalid
		if ( elem.value == "" ) {
			// add invalid class attribute
			elem.addClassName ( "invalid" );
				
			return elem;
		}
	}
	
	return null;
};


/**
 * Validates the form.
 *
 * @return boolean success
 */	
HTMLFormElement.prototype.validate = function () {
	// reset invalidElements stack
	var invalidElements = new Array ();
		
	var e = this.getElements ();
	var i = 0;
	
	// executes a validation function on all form elements.
	while ( i < e.length ) {
		var r = this.validateElement ( e [ i ] );
		
		if ( r != null )
			invalidElements.push ( r );
			
		i++;
	}
		
	if ( invalidElements.length > 0 ) {
		// first invalid element receives focus
		invalidElements [ 0 ].focus ();
		
		return false;
	}
	
	return true;
};


// INPUT PROTOTYPES

/**
 * Compares the input field value with an other input field value. If the values are the same true will be returned
 * otherwise false.
 *
 * The method takes either a HTMLInputElement or a string value as parameter.
 *
 * @param HTMLInputElement input | String value
 * @return void
 */
HTMLInputElement.prototype.compare = function ( v ) {
	var value = null;
	
	if ( v instanceof HTMLInputElement ) {
		value = v.value;
	}
	else
		value = String ( v );
	
	if ( ! value )
		return false;
	
	// compare values
	if ( value == this.value )
		return true;
	else
		return false;
}

/*
HTMLInputElement.prototype.restrict = function ( event ) {
	var key = event.keyCode;
	if (!e) var e = window.event
	if (e.keyCode) code = e.keyCode;
	else if (e.which) code = e.which;
	var character = String.fromCharCode(code);

// if they pressed esc... remove focus from field...
 if (code==27) { this.blur(); return false; }

 // ignore if they are press other keys
 // strange because code: 39 is the down key AND ' key...
 // and DEL also equals .
 if (!e.ctrlKey && code!=9 && code!=8 && code!=36 && code!=37 && code!=38 && (code!=39 || (code==39 && character=="'")) && code!=40) {
 if (character.match(restrictionType)) {
 return true;
 } else {
 return false;
 }

 } 
*/	


// SELECT PROTOTYPES

/**
 * Remove all selected options.
 *
 * @return void
 */
HTMLSelectElement.prototype.deselectAll = function ( v ) {
	for ( var i = 0; i < this.options.length; i++ ) {
		if ( this.options [ i ].selected == true )
			this.options [ i ].selected = false;
	}
}


/**
 * Get selected options.
 *
 * @return Array selectedOptions
 */
HTMLSelectElement.prototype.getSelectedOptions = function () {
	var s = new Array;
	
	if ( this.length <= 0 )
		return s;
		
	for ( var o in this.options )	{
		if ( o.selected )
			s.push ( o );
	}
	
	return s;
}


/**
 * Pruefbuch Form object.
 *
 * Provides utilities for the form handling.
 *
 * Dependencies:
 * Prototype 1.6
 * lib.form.Form
 * lib.form.Input
 *
 * @package utils
 * @author Christoph Lukas Lindtner
 */
var CSFormUtils = 
{
	/* ------------------------------------------------------------------------------------------------------------ *
	 *							 																				     																										*
	 * Class methods																								     																						*
	 *																											     																										*
	 * ------------------------------------------------------------------------------------------------------------ */
	
	/**
	 * @public
	 */
	    
	/**
	 * Checks the values of to input fields.
	 *
	 * If the compared values are identically a positive indicator image will be displayed otherwise a negative.
	 *
	 * By default the id of the positive image is imgSuccess and the negative one is imgError
	 *
	 * @return void
	 */
	compareInputFields : function ( field1 , field2 , images ) {
		if ( ! ( field1 instanceof HTMLInputElement ) && ! ( field2 instanceof HTMLInputElement ) )
			return;
			
		var result = field1.compare ( field2 );
		
		// error images
		if ( images != undefined ) {
			var e = images.error;
			var s = images.success;
			
			if ( ! e && ! s )
				return;
			
			if ( result === true ) {
				// hide error image
				e.hide ();
				
				// display success image
				s.show ();
			}
			else {
				// show error image
				e.show ();
				
				// hide success image
				s.hide ();
			}
		}
		else
			return result;
	} ,
	
	
	/**
	 * Verifys a given email address.
	 *
	 * In an additional property array a success and an error image can be specified. According to the verification either the success or the error image
	 * will be displayed.
	 *
	 * @param Event | HTMLInputElement email
	 * @param Object properties
	 * @return void
	 */
	verifyEmail : function ( elem , errorClass ) {
		var result = false;
	
		// type cast
		if ( elem instanceof Event )
			elem = Event.element ( elem );
		
		if ( ! ( elem instanceof HTMLInputElement ) )
			throw new TypeError ( "Invalid type specified!" );
	
		var reg = new RegExp ( "^([a-zA-Z0-9\-\.\_]+)(\@)([a-zA-Z0-9\-\.]+)(\.)([a-zA-Z]{2,4})$" );
		result = reg.test ( elem.value );
		
		// if no property object with success and error image are provided return the result
		if ( ! errorClass )
			return result;
		
		if ( ! result )
			elem.addClassName ( errorClass );
		else
			elem.removeClassName ( errorClass );
		
		return result;
	} ,
	
	
	/**
	 * Verifys a given email address.
	 *
	 * In an additional property array a success and an error image can be specified. According to the verification either the success or the error image
	 * will be displayed.
	 *
	 * @param Event | HTMLInputElement email
	 * @param Object properties
	 * @return void
	 */
	validateEmail : function ( email ) {
		var result = false;
	
		var reg = new RegExp ( "^([a-zA-Z0-9\-\.\_]+)(\@)([a-zA-Z0-9\-\.]+)(\.)([a-zA-Z]{2,4})$" );
		result = reg.test ( email.value );
		
		return result;		
	} ,
	
	
	/**
 	 * Checks the chars left for an input or a textfield.
 	 *
 	 * @param Event | HTMLTextAreaElement event
 	 * @return void
 	 */
	checkCharsLeft : function ( event ) {
		// type check
		var input = null;
		if ( event instanceof Event && event.currentTarget instanceof HTMLTextAreaElement )
			input = event.currentTarget;
		else if ( event instanceof HTMLTextAreaElement )
			input = event;
			
		if ( ! ( input instanceof HTMLTextAreaElement ) )
			throw new ReferenceError ( "Expecting HTMLTextAreaElement to check chars left" );
			
		var msg = input.value;
		var chars = parseInt ( input.readAttribute ( "maxchars" ) );
		var container = $ ( input.readAttribute ( "container" ) );
		
		if ( ! container )
			throw new Error ( "Could not find a container to display remaining chars" );
		
		// if the message exceeds the maximum count of chars cut it
		if ( msg.length > chars ) 
			content.value = msg.substring ( 0 , chars );
		
		if ( container instanceof HTMLInputElement )
			container.value = ( chars - msg.length );
		else if ( ( container instanceof HTMLDivElement ) || ( container instanceof HTMLSpanElement ) )
			container.innerHTML = ( chars - msg.length );
		else
			return;
	} ,
	
	
	/**
	 * Validates a form.
	 *
	 * @param HTMLFormElement form
	 * @return void
	 */
	validateForm : function ( form ) {
		if ( ! ( form instanceof HTMLFormElement ) )
			return false;
		
		var result = form.validate ();
		
		var invalidElems = form.invalidElements;
		
		for ( var i = 0; i < invalidElems; i++ ) {
			var elem = invalidElems[ i ];
			elem.addClassName ( "invalid" );
		}
		
		return result;
	} ,
	
	
	/**
	 * Removes all selections of option fields in a select tag.
	 *
	 * @param HTMLSelectElement select
	 * @return void
	 */
	removeSelection : function ( select ) {
		if ( ! ( select instanceof HTMLSelectElement ) )
			return;
		
		for ( var i = 0; i < select.length; i++ ) {
			var o = select.options [ i ];
			
			if ( o.selected == true )
				o.selected = false;
		}
	}
}
