function Form( htmlElement )
{				
	// Connect object to element
	this.mElement = htmlElement;
	htmlElement.form = this;

	// Initialize properties
	this.mFieldLength = 0;
	this.mFields = new Object();
	this.mFieldList = new Array();
	var fieldElements = htmlElement.elements;
	var fieldElementsLength = fieldElements.length;
	var fieldElement = null;
	var fieldName = null;
	var field = null;
	var fieldType = null;
	for( var i=0; i < fieldElementsLength; i++ )
	{
		// Check whether field already exists
		fieldElement = fieldElements[i];
		fieldName = this.GetFieldName( fieldElement );
		if ( fieldName == null ) // Skip field is fieldname is not valid
			continue;
			
		field = this.mFields[ fieldName ];
		if ( field == null )
		{
			fieldType = fieldElement.getAttribute( 'binding' );
			if ( fieldType == null )
				fieldType = fieldElement.type;
				
			// Create new Formfield object and attach it to the element
			switch( fieldType )
			{
				case 'adviesblok':
					field = new AdviesblokField( fieldElement, this );
					break;
				case 'formula':
					field = new FormulaField( fieldElement, this );
					break;
				case 'radio':
					field = new RadioField( fieldElement, this );
					break;
				case 'suggest':
					field = new SuggestField( fieldElement, this );
					break;
				case 'textarea':
					field = new TextareaField( fieldElement, this );
					break;
				default:
					field = new FormField( fieldElement, this );
					break;
			}

			this.mFields[ fieldName ] = field;
			this.mFieldList.push( field );
			this.mFieldLength++;
		}
		else if ( fieldElement.type == 'radio' || fieldElement.type == 'checkbox'  )
		{
			// Only radio and checkbox fields can have the same name
			fieldElement.field = field;
			
			// Create list of radio elements, push first element on list
			if ( field.mElements == null )
			{
				field.mElements = new Array();
				field.mElements.push( field.mElement );
			}
			field.mElements.push( fieldElement );
		}
		else
		{
			alert( 'FormFields cannot have the same name: ' + fieldElement.name );
		}
	}

	// Set condition handlers and dependencies and hide the fields
	var targetField = null;
	for( var i=0; i < this.mFieldLength; i++ )
	{	
		field = this.mFieldList[ i ];
		// Set condition dependencies
		if ( field.mConditionField !== null )
		{
			targetField = this.GetField( field.mConditionField );
			if ( targetField != null )
			{
				targetField.AddListener( field );
				field.NotifyChange( field.mConditionField, targetField.GetValue() ); 
			}
		}
		
		// Set field dependencies
		if ( field.SetDependencies )
			field.SetDependencies();
	}			
}

// Method: GetField
Form.prototype.GetField = _Form_GetField;
function _Form_GetField( fieldName )
{
	if ( IsEmpty( fieldName ) )
		return null;

	return this.mFields[ fieldName.toLowerCase() ];
}

// Method: GetField
Form.prototype.GetFieldName = _Form_GetFieldName;
function _Form_GetFieldName( fieldElement )
{
	var name = fieldElement.getAttribute( 'name' );
	
	if( name != null && name.indexOf( 'PostedField[' ) == 0 )
		return fieldElement.name.substring( fieldElement.name.indexOf( '[' ) + 1, fieldElement.name.indexOf( ']' ) ).toLowerCase();
	else
		return null;
}

// Method: FocusFirstField
Form.prototype.FocusFirstField = _Form_FocusFirstField;
function _Form_FocusFirstField( highlight )
{
	var length = this.mFieldList.length;
	var field = null;
	var focussed = false;
	for ( var i =0; i < length; i++ )
	{
		field = this.mFieldList[ i ];
		if ( field != null )
		{
			switch( field.mType )
			{
				case 'text':
				case 'textarea':
				case 'password':
					field.mElement.focus();
					field.mElement.select();
					focussed = true;
					break;			
				case 'select':
					field.mElement.focus();
					focussed = true;
					break;
			}
			
			if ( focussed )
				break;
		}
	}
}

//-----------------------------------------------------------------------------------------------------
// Class: formfield
function FormField( htmlElement, formObject )
{
	// Initialize element
	if ( htmlElement != null )
		this.Initialize( htmlElement, formObject );
}

// Method: Initialize
FormField.prototype.Initialize = _FormField_Initialize;
function _FormField_Initialize( htmlElement, formObject )
{
	// Initialize properties
	this.mForm = formObject;
	this.mElement = htmlElement;

	var fieldType = htmlElement.getAttribute( 'binding' );
	if ( fieldType == null )
		fieldType = htmlElement.type;
	this.mType = fieldType;
	
	// Set reference in htmlElement to this field
	htmlElement.field = this;
	
	// Set name, label, etc
	var attributes = htmlElement.attributes;
	this.mName = this.mForm.GetFieldName( htmlElement );
	this.mId = attributes.getNamedItem( 'id' ).value; 
	this.mId = this.mId.substring( this.mId.indexOf( '[' ) + 1, this.mId.indexOf( ']' ) ); // extract id from FormField[id]

	if ( attributes.getNamedItem( 'label' ) )
		this.mLabel = attributes.getNamedItem( 'label' ).value;
	
	// Check required
	this.mRequired = false;	
	if ( IsTrue( attributes.getNamedItem( 'required' ) ) )
		this.mRequired = true;
		
	// Set enabled property
	this.mIsEnabled = true;

	// Check conditions
	if ( attributes.getNamedItem( 'condition' ) != null )
	{
		var condition = attributes.getNamedItem( 'condition' ).value;
		if ( ! IsEmpty( condition ) )
		{
			var equalPos = condition.indexOf( '=' );
			if ( equalPos > -1 )
			{
				var conditions = ParseQueryString( condition );
				for( var key in conditions )
				{
					if ( key == null )
						break;
					
					if ( conditions[ key ] == null )
						break;
					
					this.mConditionValues = conditions[ key ].split( '|' );
					this.mConditionField = key.toLowerCase();		 
				}
			}
		}
	}
}

// Method: AddListener 
FormField.prototype.AddListener = _FormField_AddListener;
function _FormField_AddListener( element ) 
{
	if ( this.mListeners == null )
		this.mListeners = new Array();

	this.mListeners.push( element );
}

// Method: Display
FormField.prototype.DisplayField = _FormField_DisplayField;
function _FormField_DisplayField()
{
	var htmlElement = document.getElementById( 'FieldContainer-' + this.mId );
	if ( htmlElement )
	{
		// Make lighter in backoffice mode
		if ( top.name != 'LynkxCanvas' )
			htmlElement.style.display = '';
		else
			htmlElement.disabled = false;
			
		this.mElement.disabled = false;
	}
}

// Method: GetValue
FormField.prototype.GetValue = _FormField_GetValue;
function _FormField_GetValue()
{
	return this.mElement.value;
}

// Method: Handle change Event
// If field is conditional, check condition values
FormField.prototype.NotifyChange = _FormField_NotifyChange;
function _FormField_NotifyChange( fieldName, fieldValue )
{
	// Check fieldName
	if ( this.mConditionField != fieldName )
		return;
		
	// Check condition values
	if ( this.mConditionValues == null )
		return;
	
	var boolConditionMet = false;
	if ( this.mConditionValues[ 0 ] == "not_empty" )
	{
		boolConditionMet = ! IsEmpty( fieldValue );
	}
	else
	{
		var length = this.mConditionValues.length;

		for( var i=0; i < length; i++ )
		{
			if ( this.mConditionValues[ i ] == fieldValue )
			{
				boolConditionMet = true;
				break;
			}
		}
	}
	
	// if no conditionvalue is found, disabled field
	if ( boolConditionMet )
	{
		this.mIsEnabled = true;
		this.DisplayField();
	}
	else
	{
		this.mIsEnabled = false;
		this.HideField();
	}
}

// Method: Hide
FormField.prototype.HideField = _FormField_HideField;
function _FormField_HideField()
{
	var htmlElement = document.getElementById( 'FieldContainer-' + this.mId );
	if ( htmlElement )
	{
		// Make lighter in backoffice mode
		if ( top.name != 'LynkxCanvas' )
			htmlElement.style.display = 'none';
		else
			htmlElement.disabled = true;
			
		this.mElement.disabled = true;
	}
}

// Method: get value on radio
FormField.prototype.SetDependency = _FormField_SetDependency;
function _FormField_SetDependency( fieldName )
{
	// Name check
	if ( IsEmpty ( fieldName ) )
		return;

	// Initialize publishers dictionary
	if ( this.mPublishers == null )
		this.mPublishers = new Object();
	
	// Only add dependency once
	fieldName = fieldName.toLowerCase();
	var targetField = this.mForm.GetField( fieldName );
	if ( this.mPublishers[ fieldName ] == null &&  targetField != null )
	{
		targetField.AddListener( this );
		this.mPublishers[ fieldName ] = targetField;
	}
}

// Method: OnChange Event
FormField.prototype.OnChange = _FormField_OnChange;
function _FormField_OnChange()
{
	if( this.mListeners == null )
		return;
		
	var length = this.mListeners.length;
	for ( var i=0; i < length; i++ )
	{
		this.mListeners[ i ].NotifyChange( this.mName, this.GetValue() );		
	}	
}

// Method: GetValue
FormField.prototype.SetValue = _FormField_SetValue;
function _FormField_SetValue( value )
{
	this.mElement.value = value;
}

// Specific FormFields --------------------------------------------------------

//-----------------------------------------------------------------

// Class: AdviesblokField 
function AdviesblokField( htmlElement, formObject )
{
	// Initialize field
	this.Initialize( htmlElement, formObject );
		
	// Initiaze properties
	this.mAdviesblokFields = new Object();
	this.mAdviesConditionField = htmlElement.getAttribute( 'adviesConditionField' ).toLowerCase();
	this.mTextElement = document.getElementById( 'FormField[' +this.mId + ']-text' );
		
	var adviesCondition = null;
	for( var i = 1; i < 11; i++ )
	{
		adviesCondition = htmlElement.getAttribute( 'condition' + i );
		if ( ! IsEmpty( adviesCondition ) )
			this.mAdviesblokFields[ adviesCondition ] = htmlElement.getAttribute( 'advies' + i );
	}
}

// Extend: Field
AdviesblokField.prototype = new FormField();
AdviesblokField.prototype.constructor = AdviesblokField;

// Method: GetNumberValueOf fieldName
AdviesblokField.prototype.SetDependencies = _AdviesblokField_SetDependencies;
function _AdviesblokField_SetDependencies()
{
	if ( this.mAdviesConditionField != '' )
		this.SetDependency( this.mAdviesConditionField );
}

// Method: GetNumberValueOf fieldName
AdviesblokField.prototype.GetNumberValueOf = _FormulaField_GetNumberValueOf;

// Method: GetNumberValueOf fieldName
AdviesblokField.prototype.GetValueOf = _FormulaField_GetValueOf;

// Method: Handle change Event
// If field is conditional, check condition values
AdviesblokField.prototype.NotifyChange = _AdviesblokField_NotifyChange;
AdviesblokField.prototype._base_NotifyChange = _FormField_NotifyChange;
function _AdviesblokField_NotifyChange( fieldName, fieldValue )
{
	// Execute base handle change
	this._base_NotifyChange( fieldName, fieldValue );
	if ( this.mAdviesConditionField != fieldName )
		return;
	
	var result = false;
	for( var condition in this.mAdviesblokFields )
	{
		if ( fieldValue == condition )
		{
			this.SetValue( this.mAdviesblokFields[ condition ] );
			return;
		}
		else if ( condition.substr(0,1) == '>' || condition.substr(0,1) == '<' || condition.substr(0,1) == '!' )
		{
			eval( 'result = ( ' + fieldValue + ' ' + condition + ' );' );
			if ( result == true )
			{
				this.SetValue( this.mAdviesblokFields[ condition ] );
				return;				
			}
		}
		else
		{
			var pos = condition.indexOf( '-' );
			if ( pos > 0 )
			{
				eval( 'result = ( ' + fieldValue + '>=' + condition.substr( 0, pos ) + ' && ' + fieldValue + ' <= ' + condition.substr( pos + 1 ) + ' );' );
				if ( result == true )
				{
					this.SetValue( this.mAdviesblokFields[ condition ] );
					return;				
				}
			}
		}
	}

	this.SetValue( '' );
}

// Method: GetValue
AdviesblokField.prototype.SetValue = _AdviesblokField_SetValue;
function _AdviesblokField_SetValue( value )
{
	this.mElement.value = value;
	this.mTextElement.innerHTML = value;
	this.OnChange();
}

/*----------------------------------------------------------------------------*/

// Class: CheckboxField 
function CheckboxField( htmlElement, formObject )
{
	this.Initialize( htmlElement, formObject );
}

// Extend: Field
CheckboxField.prototype = new FormField();
CheckboxField.prototype.constructor = CheckboxField;

// Method: get checkbox value
CheckboxField.prototype.GetValue = _CheckboxField_GetValue;
function _CheckboxField_GetValue()
{
	// Get value
	if ( this.checked == true )
		return '1';
	else
		return '0';
}

// Method: GetValue
CheckboxField.prototype.SetValue = _CheckboxField_SetValue;
function _CheckboxField_SetValue( value )
{
	this.checked = IsTrue( value );
}

//-----------------------------------------------------------------

// Class: FormulaField 
function FormulaField( htmlElement, formObject )
{
	// Initialize field
	this.Initialize( htmlElement, formObject );
		
	// Initialize properties
	this.mFormula = htmlElement.getAttribute( 'formula' );
	this.mNumberFormat = htmlElement.getAttribute( 'numberFormat' );
	var entries = htmlElement.getAttribute( 'entries' );
	if ( ! IsEmpty( entries ) )
		this.mEntries = UnpackCSV( entries );
	
}

// Extend: Field
FormulaField.prototype = new FormField();
FormulaField.prototype.constructor = FormulaField;

// Method: GetNumberValueOf fieldName
FormulaField.prototype.SetDependencies = _FormulaField_SetDependencies;
function _FormulaField_SetDependencies( fieldName )
{
	if ( ! IsEmpty( this.mFormula ) )
	{
		// eval formula to get find the used fields
		try 
		{
			eval( this.mFormula.replace( /veld\(/g, 'this.SetDependency(' ) );
		}
		catch( e )
		{
			if ( top.user && top.user.mName == 'System' )
				alert( 'Er zit een fout bij veld [' +  this.mName + '] in deze formule: ' + this.mFormula );
		}
	}
}

// Method: GetNumberValueOf fieldName
FormulaField.prototype.GetNumberValueOf = _FormulaField_GetNumberValueOf
function _FormulaField_GetNumberValueOf( fieldName )
{
	var value = this.GetValueOf( fieldName );
	
	// Make english notation
	if ( ! IsEmpty( value ) )
		value =  parseFloat( value.replace( /\./g , '' ).replace( /\,/g, '.' ) );

	if ( IsEmpty( value ) || isNaN( value ) )
		value = 0;
	
	return value;
}

// Method: GetNumberValueOf fieldName
FormulaField.prototype.GetValueOf = _FormulaField_GetValueOf;
function _FormulaField_GetValueOf( fieldName )
{
	var targetField = this.mForm.GetField( fieldName );
	if ( targetField == null )
	{
		alert( 'Veld ' + fieldName + ' bestaat niet' );
		return null;
	}

	return targetField.GetValue();
}


// Method: Handle change Event
// If field is conditional, check condition values
FormulaField.prototype.NotifyChange = _FormulaField_NotifyChange;
FormulaField.prototype._base_NotifyChange = _FormField_NotifyChange;
function _FormulaField_NotifyChange( fieldName, fieldValue )
{
	// Execute base handle change
	this._base_NotifyChange( fieldName, fieldValue );

	if ( this.mPublishers && this.mPublishers[ fieldName ] != null )
	{
	
		var result = eval( this.mFormula.replace( /veld\(/g, 'this.GetNumberValueOf(' ).replace( /text\(/g, 'this.GetValueOf(' ) );
		
		// Format result
		switch( this.mNumberFormat )
		{
			case 'rounded':
				result = Math.round( result );
				break;
			case 'currencyNL':
				result = FormatCurrency( result, 'NL' );
				break;
			case 'currencyEN':
				result = FormatCurrency( result, 'EN' );
				break;
			case 'NL':
				result = result.toString().replace( /\./g, ',' );
				break;
			case 'EN':
			default:
				// do nothing
				break;				
		}

		this.SetValue( result );
	}
}

// Method: GetValue
FormulaField.prototype.SetValue = _FormulaField_SetValue;
function _FormulaField_SetValue( value )
{
	if ( value != null && value.toString() == 'NaN' )
		value = '';
	this.mElement.value = value;
	this.OnChange();
}

//-----------------------------------------------------------------------------------------------------
// Class: RadioField 
function RadioField( htmlElement, formObject )
{
	this.Initialize( htmlElement, formObject );
}

// Extend: Field
RadioField.prototype = new FormField();
RadioField.prototype.constructor = RadioField;

// Method: get value on radio
RadioField.prototype.GetValue = _RadioField_GetValue;
function _RadioField_GetValue()
{
   // Initialize found
   var found = false;
   
   // Get html element, get number of options
   var radioOptions = this.mElements;
   var length = radioOptions.length;

   // Loop over all select options
   var i;
   for ( i = 0; i < length; i++ ) 
   {
      if ( radioOptions[ i ].checked == true ) 
      {
         return radioOptions[ i ].value;
      }
   }
   
   // Else return empty string, because initialValue is also an empty string, if not set.
   return "";
}

// Method: get value on radio
RadioField.prototype.SetValue = _RadioField_SetValue;
function _RadioField_SetValue( value )
{
   // Initialize found
   var found = false;
   
   // Get html element, get number of options
   var radioOptions = this.mElements;
   var length = radioOptions.length;

   // Loop over all select options
   var i;
   for ( i = 0; i < length; i++ ) 
   {
      if ( radioOptions[ i ].value == value ) 
      {
         radioOptions[ i ].checked = true;
         break;
      }
   }   
}

//-----------------------------------------------------------------------------------------------------
// Class: SuggestField 
function SuggestField( htmlElement, formObject )
{
	this.Initialize( htmlElement, formObject );
	this.mAutoCompleteElement = document.getElementById( 'FormField[' + this.mId + ']-autocomplete' );
	this.mDataUrl = 'http://localhost/nujij2/typesInfeite/tags.lynkx'; //this.mElement.getAttribute( 'dataUrl' );
	this.mElement.onkeydown = function( evt ) { eval( 'this.field.OnKeyDown( evt );' ); };
   this.mElement.onkeyup = function( evt ) { eval( 'this.field.OnKeyUp( evt );' ); };
   this.mSelectedItem = 0;
   this.mLoopStarted = false;
   
   this.mSuggestionValues = [];
}

// Extend: Field
SuggestField.prototype = new FormField();
SuggestField.prototype.constructor = SuggestField;

var KEYUP = 38;
var KEYDOWN = 40;
var KEYENTER = 13;
var KEYTAB = 9;
var THROTTLE_PERIOD = 1000;

// Callback method called by async request, this object is the xmlHttp object
// the field object is always 'this.callbackObject'
SuggestField.prototype.AsyncCallback = _SuggestField_AsyncCallback;
function _SuggestField_AsyncCallback()
{
	if ( this.readyState != 4 )
		return;
	
	// only if "OK"
	if ( this.status != 200 )
	{
		 alert( this.statusText );
		 return;
	}
	
	var field = this.callbackObject;
	
	// Fill autocomplete
	if( this.responseText == "" )
		field.HideAutoComplete();
	else {
		field.ShowAutoComplete();
		try 
		{
			field.mResultsObj = eval('(' + this.responseText + ')');
			field.FormatHtml();
		}
		catch(e)
		{
			var msg = (typeof e == "string") ? e : ((e.message) ? e.message : "Unknown Error");
			alert(msg);
		}
	}
	
	field.mLoopStarted = false;
}

// Format html
SuggestField.prototype.FormatHtml = _SuggestField_FormatHtml;
function _SuggestField_FormatHtml()
{        
	var output = this.mAutoCompleteElement;

	while( output.childNodes.length > 0 )
		output.removeChild( output.childNodes[0] );

	this.mSuggestionValues = [];
	for ( var i=0; i < this.mResultsObj.length ;i++ )
	{
		if ( this.mResultsObj[i][0] )
		{
			this.mSuggestionValues.push( this.mResultsObj[i][0] );

			var x1 = document.createElement("div");
			var x1 = document.createElement("div");
			if ( i == this.mSelectedItem )
				x1.className = "srs";
			else
				x1.className = "sr";

			var onMouseFn = "document.getElementById( 'FormField[" + this.mId + "]' ).field.HighlightItem( " + i + " );return false;";
			x1.onmousemove = new Function(onMouseFn);
			var onClickFn = "document.getElementById( 'FormField[" + this.mId + "]' ).field.SetValue(); document.getElementById( 'FormField[" + this.mId + "]' ).field.HideAutoComplete();return true;";
			x1.onmousedown = new Function(onClickFn);

			var x2 = document.createElement("span");
			x2.className = "srt";
			x2.appendChild( document.createTextNode(this.mResultsObj[i][0]) );

			var x3 = document.createElement("span");
			x3.className = "src";
			x3.appendChild( document.createTextNode(this.mResultsObj[i][1] + ", " + this.mResultsObj[i][2]) );

			x1.appendChild(x2);
			x1.appendChild(x3);

			output.appendChild(x1);		
		}
	}
	this.RequestSuggestions();
}

// Method: get value on radio
SuggestField.prototype.OnKeyDown = _SuggestField_OnKeyDown;
function _SuggestField_OnKeyDown( evt )
{
	// don't do anything if the div is hidden
	var div = this.mAutoCompleteElement;
	if ( div.style.display == "none" )
		return true;

	// make sure we have a valid event variable
	if( !evt && window.event )
		evt = window.event;
	
	var key = evt.keyCode;

	// if this key isn't one of the ones we care about, just return
	if ( ( key != KEYUP ) && ( key != KEYDOWN )  && ( key != KEYENTER ) )
		return true;
	
	if ( key == KEYUP )
	{
		if (( this.mSelectedItem ) >= 1 ) 
		{
			 this.mSelectedItem = this.mSelectedItem - 1;
			 this.SetValue();
			 this.FormatHtml();
		}
	}

	if ( key == KEYDOWN ) 
	{
		if ( this.mResultsObj != null && this.mSelectedItem < this.mResultsObj.length - 1 ) 
		{
			 this.mSelectedItem = this.mSelectedItem + 1;
			 this.SetValue();
			 this.FormatHtml();
		}
	}

	if ( key == KEYENTER )
	{
		this.SetValue();
		this.SelectRange(99,99);
		this.HideAutoComplete();
		return false;
	}

	return true;
}

// Method: get value on radio
SuggestField.prototype.OnKeyUp = _SuggestField_OnKeyUp;
function _SuggestField_OnKeyUp( evt )
{
	if ( this.mLoopStarted == false )
		this.RequestLoop();

	// make sure we have a valid event variable
	if( !evt && window.event )
		evt = window.event;

	var key = evt.keyCode;

	if ( key < 32 || ( key >= 33 && key <= 46 ) || ( key >= 112 && key <= 123 ) )
	{
		//ignore
	} 
	else
	{
		//request suggestions from the suggestion provider
		// Backspace key(8), Delete key (48)
		if (key != 8 && key != 48) 
			 this.RequestSuggestions();
	}
	return true;   
}

// Method: check input
SuggestField.prototype.RequestLoop = _SuggestField_RequestLoop;
function _SuggestField_RequestLoop() 
{
	this.mLoopStarted = true;	
	var keyword = this.GetLastTypedValue().toLowerCase();
	if ( ( keyword != this.mLatestServerQuery ) && ( keyword != '' ) ) 
	{
		this.mLatestServerQuery = keyword;
		this.GetData( keyword );
	}
	if ( keyword == '' ) 
	{
		this.HideAutoComplete();
		this.mSuggestionValues = [];
		this.mLatestServerQuery = null;
		this.mSelectedItem = 0;
	}
	
	//setTimeout( "document.getElementById( 'FormField[" + this.mId + "]' ).field.RequestLoop();", THROTTLE_PERIOD );
}

SuggestField.prototype.RequestSuggestions = _SuggestField_RequestSuggestions;
function _SuggestField_RequestSuggestions()
{
	var sTextboxValue = this.GetLastTypedValue().toLowerCase();
	var aSuggestions = [];
	var suggestionValues = this.mSuggestionValues;
	
	if ( suggestionValues.length > 0 )
	{
		//search for matching states
		for ( var i=0; i < suggestionValues.length; i++ )
		{
			if ( suggestionValues[i].toLowerCase().indexOf(sTextboxValue) == 0 )
			  aSuggestions.push( suggestionValues[i] );
		}

		//make sure there's at least one suggestion
		if (aSuggestions.length > 0)
		{
			var sSuggestion = aSuggestions[0];
			var textbox = this.mElement;

			//check for support of typeahead functionality
			if ( textbox.createTextRange || textbox.setSelectionRange )
			{
				var iLen = this.GetLastTypedValue().length;
				textbox.value = sSuggestion;
				this.SelectRange( iLen, sSuggestion.length );
			}	
		}
	}
 }

// Method: get last typed input
SuggestField.prototype.GetLastTypedValue = _SuggestField_GetLastTypedValue;
function _SuggestField_GetLastTypedValue() 
{
	var selectedTextLength = 0;
	var inputField = this.mElement;
	if( inputField.createTextRange )
	{
		var inputValue = document.selection.createRange().duplicate();
		selectedTextLength = inputValue.text.length;
	}
	else if( inputField.setSelectionRange )
		selectedTextLength = inputField.selectionEnd - inputField.selectionStart;
  
	return inputField.value.substring( 0, inputField.value.length - selectedTextLength );
}

// Method: get last typed input
SuggestField.prototype.GetData = _SuggestField_GetData;
function _SuggestField_GetData( keyword ) 
{
	HttpChannel.AsyncRequest( this.mDataUrl + '?q=' + keyword, this );
}

SuggestField.prototype.SelectRange = _SuggestField_SelectRange;
function _SuggestField_SelectRange( iStart, iLength )
{
	var textbox = this.mElement;
	
	//use text ranges for Internet Explorer
	if ( textbox.createTextRange )
	{
		var oRange = textbox.createTextRange();
		oRange.moveStart("character", iStart);
		oRange.moveEnd("character", iLength - textbox.value.length);
		oRange.select();
		
	} //use setSelectionRange() for Mozilla
	else if ( textbox.setSelectionRange )
		textbox.setSelectionRange(iStart, iLength);

	//set focus back to the textbox
	textbox.focus();
}

SuggestField.prototype.HighlightItem = _SuggestField_HighlightItem;
function _SuggestField_HighlightItem( item, number )
{
	this.mSelectedItem = number;
	this.FormatHtml();
}
    
SuggestField.prototype.SetValue = _SuggestField_SetValue;
function _SuggestField_SetValue()
{
	if (this.mResultsObj != null && this.mSelectedItem != null )
	{
			var result = this.mResultsObj[this.mSelectedItem][0];
			this.mLatestServerQuery = result.toLowerCase();
			this.mElement.value = result;
			this.SelectRange(99,99);
	}
}
    
SuggestField.prototype.ShowAutoComplete = _SuggestField_ShowAutoComplete;
function _SuggestField_ShowAutoComplete()
{
	this.mAutoCompleteElement.style.display="block";
}

SuggestField.prototype.HideAutoComplete = _SuggestField_HideAutoComplete;
function _SuggestField_HideAutoComplete()
{
	this.mAutoCompleteElement.style.display="none";
}

//-----------------------------------------------------------------------------------------------------
// Class: TextareaField 
function TextareaField( htmlElement, formObject )
{
	this.Initialize( htmlElement, formObject );
}

// Extend: Field
TextareaField.prototype = new FormField();
TextareaField.prototype.constructor = TextareaField;

// Method: get value on radio
TextareaField.prototype.GetValue = _TextareaField_GetValue;
function _TextareaField_GetValue()
{
   return this.mElement.innerHTML;   
}

// Method: get value on radio
TextareaField.prototype.SetValue = _TextareaField_SetValue;
function _TextareaField_SetValue( value )
{
	this.mElement.innerHTML = value;
}

// Helper functions -----------------------------------------------------------

function FormatCurrency( number )
{
	if ( isNaN( number ) )
		return number;
		
	// Format with 2 decimals
	number = Math.round( number * 100 )/100;
	var numberString = number.toString();
	switch( numberString.indexOf( '.' )  )
	{
		case -1:
			numberString += '.00';
			break;
		case ( numberString.length - 2 ):
			numberString += '0';
			break;
	}
	
	numberString = numberString.replace( '.', ',' );

	// Format with thousands separator
	if ( number >= 1000 )
	{
		var startPos = numberString.indexOf( ',' ) - 3;
		var newNumberString = numberString.substr( numberString.length - 6 );
		while( startPos > 3 )
		{
			newNumberString = numberString.substr( startPos - 3, 3 ) + '.' + newNumberString;
			startPos -= 3;	
		}
		numberString = numberString.substr( 0, startPos ) + '.' + newNumberString;
	}

	return numberString;
}

// Is Empty Check
function IsEmpty( input ) 
{
	return ( input == null || input == '' );
}

// Check if value represents true
function IsTrue( value )
{
	// Set value to lowercase
	if ( typeof( value ) == 'string' )
	{
		value = value.toLowerCase();
	}
	
	// Set value
	return ( value == true 
			|| value == '1' 
			|| value == 'true' 
			|| value == 'yes'
			|| value == 'on' );
} 

// Return the query string as an assosiative array
function ParseQueryString( queryString )
{
	// Initialize variables
	var parameters = new Array();

	// Null check
	if ( queryString == null )
		return parameters;
		
	// strip ? from querystring
	var pos = queryString.indexOf('?');
	if ( pos > -1 )
		queryString = queryString.substr(pos+1);
	
	// Replace + by spaces ( decodeURI does not do that )	
	queryString = queryString.replace( /\+/g, ' ' );

	// Get parameters
	var keyValuePairs = queryString.split( '&' );
	var equalPos = -1;
	var parameter;
	for ( var i in keyValuePairs )
	{
	   // Split on =
	   parameter = keyValuePairs[ i ];
	   equalPos = parameter.indexOf( '=' );
	   if ( equalPos > -1 )
	   	parameters[ decodeURIComponent( parameter.substr( 0, equalPos ) ) ] = decodeURIComponent( parameter.substr( equalPos + 1 ) );
	}
	
	// Return parameters
	return parameters;
}

// Function: trim
function Trim( value )
{
	// Remove all leading and trailing white space
	return TrimRight( TrimLeft( value ) );
}

// Trim leading and trailing comma's
trimCommasRegExp = new RegExp( "^,*|,*$"  ,"gm" );
function TrimCommas( string )
{
   return string.replace( trimCommasRegExp, '' );
}

// Function: left trim
function TrimLeft( value )
{
	// Remove all leading white space
	return value.rereplace( "^\\s+", "" );
}

// Function: right trim
function TrimRight( value )
{
	// Remove all trailing white space
	return value.rereplace( "\\s+$", "" );
}

// UnpackCSV
function UnpackCSV ( csv ) {
   
   // initializing variables
   var i = 0;
   var data = new Array();
   var heading = new Array();
   if ( csv.charAt(csv.length-1) != ';') csv = csv + ';';

   while ((x = csv.indexOf(';'))>-1) {
      
      var row = csv.substr(0,x) + ',';
      var csv = csv.substr(x+1);
      var j = 0;
      data[i] = new Array();
      while ((y = row.indexOf(','))>-1) {

         var cell = row.substr(0,y);
         var row = row.substr(y+1);
         j++;
         if ( i == 0 ) {
            heading[j] = unescape(cell);
         } else {
            data[i][heading[j]] = unescape(cell);
         }
      }
      i++;
   }
   return data; 
}
