var Fse; if (!Fse) Fse = {};

if( !Fse.FormManager ) Fse.FormManager = {};

if( !Fse.FormManager._defaultInvalidFormatMessages ) {

    var defaultMessages = [];;

    defaultMessages["url"] = "Please enter a valid URL in the standard form\ni.e. http://www.fsenablers.com";
    defaultMessages["url2"] = "Please enter a valid URL in the standard form\ni.e. www.fsenablers.com";
    defaultMessages["integer"] = "Please enter a numeric value without decimal points\ni.e.4256";
    defaultMessages["date"] = "Please enter a valid date using the MM/DD/YYYY form\n i.e. Enter June 1st 2007 as 06/01/2007.";
    defaultMessages["decimal"] = "Please enter a numeric.\ni.e. 4680.27";
    defaultMessages["email"] = "Please enter a properly formatted email address.\ni.e. contactname@companyname.com"
    defaultMessages["email-list"] = "Please enter one or more properly formatted email addresses separated by commas.\ni.e. contact1@companyname.com,contact2@companyname.com"
    defaultMessages["gs1_gtin_8"] = "Please enter a valid 8 digit GTIN value";
    defaultMessages["gs1_gtin_12"] = "Please enter a valid 12 digit GTIN value";
    defaultMessages["gs1_gtin_13"] = "Please enter a valid 13 digit GTIN value";
    defaultMessages["gs1_gtin_14"] = "Please enter a valid 14 digit GTIN value";
    defaultMessages["gs1_gln"] = "Please enter a valid 13 digit GLN value";
    defaultMessages["time"] = "Please enter a time in the form HH:MM AM or PM;"

    Fse.FormManager._defaultInvalidFormatMessages = defaultMessages;
    
};

Fse.FormManager.ValidationResult = function( oField, iValidationStatus ) {
    this.field = oField;
    this.validationStatus = iValidationStatus;
};

Fse.FormManager.ValidationStatus = {};
Fse.FormManager.ValidationStatus.OK = 0;
Fse.FormManager.ValidationStatus.REQUIRED = 1;
Fse.FormManager.ValidationStatus.INVALID = 2;

// Fse.FormManager._reEmail = /^(?:\w+\.?)*\w+@(?:\w+\.)+\w+$/; // doesn't allow dashes in email address
Fse.FormManager._reEmail = /^(?:[\w-#]+\.?)*[\w-]+@(?:[\w-]+\.)+\w+$/; // allows dashes in email address 
Fse.FormManager._reDecimal = /^-?\$?(,?\d?)+\.?\d*$/;
Fse.FormManager._reInteger = /^-?\$?(,?\d?)+$/;
Fse.FormManager._reEmptyString = /^[ \t\n\x0B\f\r]*$/;
Fse.FormManager._reStringMeat = /(^[ \t\n\x0B\f\r]*)(.+[^ \t\b\x0B\f\r])([ \t\n\x0B\f\r]*$)/;
Fse.FormManager._reDate = /(0[1-9]|1[0-2])\/(0[1-9]|[12][0-9]|3[01])\/(19|20\d\d)/;
Fse.FormManager._reURL = /^https?:\/\/([-\w\.]+)+(:\d+)?(:\w+)?(@\d+)?(@\w+)?([-\w\.]+)(\/([\w\/_\.]*(\?\S+)?)?)?/;
Fse.FormManager._reURL = /^https?:\/\/([-\w\.]+)+(:\d+)?(:\w+)?(@\d+)?(@\w+)?([-\w\.]+)(\/([\w\/_\.]*(\?\S+)?)?)?/;
Fse.FormManager._reURL2 = /^([-\w\.]+)+(:\d+)?(:\w+)?(@\d+)?(@\w+)?([-\w\.]+)(\/([\w\/_\.]*(\?\S+)?)?)?/;

Fse.FormManager._reN8 = /^\d\d\d\d\d\d\d\d$/;
Fse.FormManager._reN12 = /^\d\d\d\d\d\d\d\d\d\d\d\d$/;
Fse.FormManager._reN13 = /^\d\d\d\d\d\d\d\d\d\d\d\d\d$/;
Fse.FormManager._reN14 = /^\d\d\d\d\d\d\d\d\d\d\d\d\d\d$/;
Fse.FormManager._reTime = /^\s*(1|01|2|02|3|03|4|04|5|05|6|06|7|07|8|08|9|09|10|11|12):[012345][0123456789]\s*(AM?|PM?)\s*$/i;

Fse.FormManager.submit = function( oForm, bPerformSubmit ) {

    if( bPerformSubmit == undefined ) {
        bPerformSubmit = false;
    }

    Fse.FormManager.resetValidationAlert( oForm );
    
    var aPreValidated = Fse.FormManager.onPreValidate( oForm );
    
	var bSubmit = true;
	var aResults = new Array();
	var aGroupFields = new Array();
	var iProcessedCount = 0;
	var iSkippedCount = 0;
	for( var fieldIdx = 0; fieldIdx < oForm.elements.length; fieldIdx++ ) {
		if( oForm.elements[fieldIdx].nodeType == 1 ) {
		    if( aPreValidated[ oForm.elements[fieldIdx].name] ) {
		        // skip validation on any preValidated fields
		        iSkippedCount++;
		        continue;
		    }
		    if( oForm.elements[fieldIdx].type == "hidden" ) {
		    	// skip validation on any hidden fields
		        iSkippedCount++;
		    	continue;
		    }
		    if( oForm.elements[fieldIdx].disabled ) {
                // skip validation on any disabled fields
		        iSkippedCount++;
                continue;		        
		    }
			iProcessedCount++;
					    
		    var iValidationStatus = Fse.FormManager.ValidationStatus.OK;
		    if( oForm.elements[fieldIdx].type != "radio" ) {
                var oMessageElement = Fse.FormManager.getMessageElement( oForm.elements[fieldIdx] );
                if( oMessageElement ) {
                    oMessageElement.innerHTML = "";
                }
                var oLabelElement = Fse.FormManager.getLabelElement(  oForm.elements[fieldIdx] );
                if( oLabelElement ) {
                    oLabelElement.style.color = "";
                }
		        if( oForm.elements[fieldIdx].type == "text" ) {
		            // eliminate bogus whitespace
                    var aResult = oForm.elements[fieldIdx].value.match( Fse.FormManager._reStringMeat );
                    if( aResult ) {
                        oForm.elements[fieldIdx].value = aResult[2];
                    }
		        }
    		    iValidationStatus = Fse.FormManager.checkField( oForm.elements[fieldIdx] );
    		    aResults.push( new Fse.FormManager.ValidationResult( oForm.elements[fieldIdx], iValidationStatus));
    			if( iValidationStatus != Fse.FormManager.ValidationStatus.OK ) {
	       			bSubmit = false;
    			}
		    } else {
		        
		        if( aGroupFields[oForm.elements[fieldIdx].name] == undefined ) {
                    var oMessageElement = Fse.FormManager.getMessageElement( oForm.elements[fieldIdx] );
                    if( oMessageElement ) {
                        oMessageElement.innerHTML = "";
                    }
    		        var oGroupField = Fse.FormManager.getGroupField( oForm.elements[fieldIdx] );
    		        aGroupFields[oGroupField.name]=oGroupField;
    		        iValidationStatus = Fse.FormManager.checkGroupField( oGroupField );
        		    aResults.push( new Fse.FormManager.ValidationResult( oForm.elements[fieldIdx], iValidationStatus));
        			if( iValidationStatus != Fse.FormManager.ValidationStatus.OK ) {
    	       			bSubmit = false;
        			}
		        }
		    }
		}
	}

	if( ! bSubmit ) {
	    for( var idx in aResults ) {
            if( aResults[idx].validationStatus != Fse.FormManager.ValidationStatus.OK )	{
                var sMessage = "Validation Error";
                var oMessageElement = Fse.FormManager.getMessageElement( aResults[idx].field );
                var oLabelElement = Fse.FormManager.getLabelElement( aResults[idx].field );
                var oLabelElementClass = Fse.FormManager.getFseAttribute( oForm, "notifyclass" );
                switch( aResults[idx].validationStatus ) {
                    case Fse.FormManager.ValidationStatus.REQUIRED : {
                        sMessage = Fse.FormManager.getFseAttribute( aResults[idx].field, "message" );
                        if( sMessage == undefined ) {

                            var sFormat = Fse.FormManager.getFseAttribute( aResults[idx].field, "format" );
                            if( sFormat ) {
                                sMessage = Fse.FormManager._defaultInvalidFormatMessages[sFormat];
                                if( sMessage ){
                                    sMessage = "Required field missing.\n"+sMessage;
                                }
                            }
                            if( sMessage == undefined ) {
                                sMessage = "Required field missing";
                            }
                        }
                    }
                    break;
                    
                    case Fse.FormManager.ValidationStatus.INVALID : {
                        sMessage = Fse.FormManager.getFseAttribute( aResults[idx].field, "message" );
                        if( sMessage == undefined ) {
                            
                            var sFormat = Fse.FormManager.getFseAttribute( aResults[idx].field, "format" );
                            if( sFormat ) {
                                sMessage = Fse.FormManager._defaultInvalidFormatMessages[sFormat];
                            }
							
                            if( sMessage == undefined ) {
	                            if( aResults[idx].field.type != 'textarea') {
	                                sMessage = "Invalid format";
	                            }else{
									Fse.FormManager.updateCharsLeft(aResults[idx].field);
									sMessage = "Maximum field length exceeded";
								}
                            }
                        }
                    }
                    break;
                }
                if( oLabelElement ) {
				  if(oLabelElementClass){
				    Spry.Utils.addClassName( oLabelElement, oLabelElementClass );
				  }else{
					 oLabelElement.style.color="red";
				  }
                }
                if( oMessageElement ) {
                    oMessageElement.innerHTML = sMessage;                    
                } else {
                    Fse.FormManager.validationAlert( oForm, sMessage );
                }
                Fse.FormManager._setFocus( aResults[idx].field );
                if( aResults[idx].field.type == "text" ) {
                    
                }
                var myVar = 1;
                break;                
            }
	    }
	}
	
	if( bSubmit ) {
	    bSubmit = Fse.FormManager.onPostValidate( oForm );
	}

	if( bSubmit ) {
		// cleanse numeric (fse:format = integer or fse:format = decimal) data
		for( var fIdx = 0; fIdx < oForm.elements.length; fIdx++ ) {
			var oField = oForm.elements[fIdx];
			var sFormat = Fse.FormManager.getFseAttribute( oField, "format" );
			if( oField.type == "text" && ( sFormat == "integer" || sFormat == "decimal" ) && oField.value ) {
				oField.value = Fse.FormManager.cleanseNumericValue( oField.value );
			}
		}
	}
	
	if( bSubmit && bPerformSubmit ) {
		
		if( Fse.Ajax && Fse.Ajax.showWait ) {
			
			var nWaitDelay = oForm.getAttribute( "fse:waitdelay" );
			var sWaitMessage = oForm.getAttribute( "fse:waitmessage" );
			if( sWaitMessage ) {
				var _delay = 750;
				if( nWaitDelay && nWaitDelay > 0 ) {
					_delay = nWaitDelay;
				}
				Fse.Ajax.showWait( _delay, sWaitMessage );				
			}
			
		}
		
	    oForm.submit();
	}
	return bSubmit;
};

Fse.FormManager.onPreValidate = function( oForm ) {
    var onPreValidateHandler = Fse.FormManager.getFseAttribute( oForm, "onprevalidate" );
    if( onPreValidateHandler ) {
        return Fse.FormManager._getHandler(onPreValidateHandler)(oForm);
    } else {
        return new Array();
    }
};

Fse.FormManager.onPostValidate = function( oForm ) {
	
	var bValid = true;
    var onPostValidateHandler = Fse.FormManager.getFseAttribute( oForm, "onpostvalidate" );
    if( onPostValidateHandler ) {
        bValid = Fse.FormManager._getHandler(onPostValidateHandler)(oForm);
    }
	
	var fnPreSubmitTest = function( e ) {
		var sRel = e.getAttribute( "rel" );
		if( sRel == "presubmit" ) {
			var sHref = e.getAttribute( "href" );
			if( sHref && sHref.indexOf( "javascript:" )== 0 ) {
				return true;
			} else {
				return false;
			}
		} else {
			return false;
		}
	};
	
	if( bValid ) {
		var aPreSubmitHandlers = YAHOO.util.Dom.getElementsBy( fnPreSubmitTest, "link", oForm );
		for( var x = 0; bValid && x < aPreSubmitHandlers.length; x++ ) {
			try {
				var sHandlerJs = aPreSubmitHandlers[x].getAttribute( "href" ).substring( "javascript:".length );
				bValid = eval( sHandlerJs );
			} catch ( ex ) {
				bValid = false;
			}
		}
	}
	
	return bValid;
};

Fse.FormManager._getHandler = function( sHandlerName ) {
    // parse handler name to handle namespaces
    var aParts = sHandlerName.split( "." );
    var fnHandler = window;
    for( var px = 0; px < aParts.length; px++ ) {
        fnHandler = fnHandler[aParts[px]];     
    }
    return fnHandler;   
};


Fse.FormManager.getMessageElement = function( oField ) {

    var oMessageElement;    
    var sElementId = Fse.FormManager.getFseAttribute( oField, "messageelementid" );
    if( sElementId != undefined ) {
        oMessageElement = document.getElementById( sElementId );
    } else {
        oMessageElement = document.getElementById( oField.name + "_message" );
    }
    return oMessageElement;
};

Fse.FormManager.getLabelElement = function( oField ) {

    var oLabelElement;    
    var sElementId = Fse.FormManager.getFseAttribute( oField, "labelelementid" );
    if( sElementId != undefined ) {
        oLabelElement = document.getElementById( sElementId );
    } else {
        oLabelElement = document.getElementById( oField.name + "_label" );
    }
    return oLabelElement;
};


Fse.FormManager.checkField = function( oField ) {
    var iValidationStatus = Fse.FormManager.ValidationStatus.OK;
    var sCustomValidator = Fse.FormManager.getFseAttribute( oField, "validator" );
    if( ! sCustomValidator ) {
   		iValidationStatus = Fse.FormManager.checkSingleField( oField );
    } else {
        iValidationStatus = window[sCustomValidator]( oField );
    }
    return iValidationStatus;
};


Fse.FormManager.validateField = function( oField ) {

	var bValid = true;	
	var iValidationStatus = Fse.FormManager.checkField( oField );
	if( iValidationStatus != Fse.FormManager.ValidationStatus.OK ) {
		Fse.FormManager.validationAlert( Fse.FormManager.getErrorMessage( oField, iValidationStatus ));
		// alert( Fse.FormManager.getErrorMessage( oField, iValidationStatus ));	
		Fse.FormManager._setFocus ( oField );
		bValid = false;	
	}
	
	return bValid;
};

Fse.FormManager._setFocus = function( oField ) {
	
	if( oField ) {
		
		if( oField.form._tabView ) {
			var oTabBodyElement = YAHOO.util.Dom.getAncestorByClassName( oField, "tab-body" );
			if( oTabBodyElement) {
				var _tabView = oField.form._tabView
				var nTabIdx = 0;
				var oTab = _tabView.getTab( nTabIdx );
				while( oTab ) {
					
					var contentEl = oTab.get( "contentEl" );
					if( contentEl == oTabBodyElement ) {
						break;
					}
					nTabIdx++;
					oTab = _tabView.getTab( nTabIdx );
				}
				
				if( oTab ) {
					_tabView.selectTab( nTabIdx );
				}
			}
		}
		
		// move the cursor
		oField.focus();
		
	}
	
};

Fse.FormManager.getErrorMessage = function( oField, iValidationStatus ) {

	var sMessage = "Validation Error";

	switch( iValidationStatus ) {
	    case Fse.FormManager.ValidationStatus.REQUIRED : {
	        sMessage = Fse.FormManager.getFseAttribute( oField, "message" );
	        if( sMessage == undefined ) {
	
	            var sFormat = Fse.FormManager.getFseAttribute( oField, "format" );
	            if( sFormat ) {
	                sMessage = Fse.FormManager._defaultInvalidFormatMessages[sFormat];
	                if( sMessage ){
	                    sMessage = "Required field missing.\n"+sMessage;
	                }
	            }
	            if( sMessage == undefined ) {
	                sMessage = "Required field missing";
	            }
	        }
	    }
	    break;
	    
	    case Fse.FormManager.ValidationStatus.INVALID : {
	        sMessage = Fse.FormManager.getFseAttribute( oField, "message" );
	        if( sMessage == undefined ) {
	            
	            var sFormat = Fse.FormManager.getFseAttribute( oField, "format" );
	            if( sFormat ) {
	                sMessage = Fse.FormManager._defaultInvalidFormatMessages[sFormat];
	            }
	            if( sMessage == undefined ) {
	                sMessage = "Invalid format";
	            }
	        }
	    }
	    break;
	
	}
	
	return sMessage;
	
};

Fse.FormManager.getFseAttribute = function( oField, sAttributeName ) {

	var vValue;
	var sRawValue = oField.getAttribute( "fse:" + sAttributeName );
	if( sRawValue != undefined ) {
		/* if( sAttributeName == "required" ) {
			vValue = Boolean( sRawValue );
		} else */ 
		if ( sAttributeName == "minimumlength" ) {
		    vValue = Number( sRawValue );
		} else if ( sAttributeName == "maximumlength" ) {
		    vValue = Number( sRawValue );
		} else {
			vValue = sRawValue;
		}
	}
	return vValue;
};

Fse.FormManager.checkGroupField = function( oGroupField ) {
    var iValidationStatus = Fse.FormManager.ValidationStatus.OK;
    if( oGroupField.required ) {
        iValidationStatus = Fse.FormManager.ValidationStatus.REQUIRED;
        for( var idx=0; idx < oGroupField.fields.length; idx++ ){
            if( oGroupField.fields[idx].checked ) {
                iValidationStatus = Fse.FormManager.ValidationStatus.OK;
                break;
            }
        }
    }
    return iValidationStatus;
};

Fse.FormManager.checkSingleField = function( oInputField ) {

	var iValidationStatus = Fse.FormManager.ValidationStatus.OK;
	
	var fseRequired = Fse.FormManager.getFseAttribute( oInputField, "required" );
	var reEmpty;
	var sEmpty = Fse.FormManager.getFseAttribute( oInputField, "empty" );
	if( sEmpty != undefined ) {
        reEmpty = new RegExp( "^" + sEmpty + "$");
	} else {
	    reEmpty = Fse.FormManager._reEmptyString;
	}
	if( reEmpty.test( oInputField.value ) == false ) {
    	var fseFormat = Fse.FormManager.getFseAttribute( oInputField, "format" );
    	if( ! fseFormat ) {
    	    fseFormat = "string";
    	}
        if( fseFormat == "email" ) {
            if( ! Fse.FormManager._reEmail.test( oInputField.value ) ) {
                iValidationStatus = Fse.FormManager.ValidationStatus.INVALID;
            }
        } else if ( fseFormat == "email-list" ) {
        	var sCleanValue = oInputField.value.replace( /\s+|;+/g, "," ).replace( /,+/g, "," ); 
        	var aValues = sCleanValue.split( "," );
        	for( var idx = 0; idx < aValues.length; idx++ ) {
                if( ! Fse.FormManager._reEmail.test( aValues[idx] ) ) {
                    iValidationStatus = Fse.FormManager.ValidationStatus.INVALID;
                }
        	}
        	if( iValidationStatus == Fse.FormManager.ValidationStatus.OK ) {
        		oInputField.value = aValues.join( "," );
        	}
        } else if ( fseFormat == "time" ) {
            if( ! Fse.FormManager.checkTime( oInputField.value )) {
                iValidationStatus = Fse.FormManager.ValidationStatus.INVALID;
            }
        } else if ( fseFormat == "date" ) {
            if( ! Fse.FormManager.checkDate( oInputField.value )) {
                iValidationStatus = Fse.FormManager.ValidationStatus.INVALID;
            }
        } else if ( fseFormat == "decimal" ) {
            if( ! Fse.FormManager._reDecimal.test( oInputField.value ) ) {
                iValidationStatus = Fse.FormManager.ValidationStatus.INVALID;
            } else {
                iValidationStatus = Fse.FormManager.checkNumericRange( oInputField );
            }
        } else if ( fseFormat == "integer" ) {
            if( ! Fse.FormManager._reInteger.test( oInputField.value ) ) {
                iValidationStatus = Fse.FormManager.ValidationStatus.INVALID;
            } else {
                iValidationStatus = Fse.FormManager.checkNumericRange( oInputField );
            }
        } else if ( fseFormat == "url" ) {
            if( ! Fse.FormManager.checkURL( oInputField.value )) {
                iValidationStatus = Fse.FormManager.ValidationStatus.INVALID;
            }
        } else if ( fseFormat == "url2" ) {
            if( ! Fse.FormManager.checkURL2( oInputField.value )) {
                iValidationStatus = Fse.FormManager.ValidationStatus.INVALID;
            }
        } else if( ( fseFormat + "___" ).slice( 0, 3 ) == "gs1" ) {
        	iValidationStatus = Fse.FormManager.checkGS1Identifier( oInputField.value, fseFormat );
        } else if ( fseFormat == "string" ) {
            iValidationStatus = Fse.FormManager.ValidationStatus.OK;
            var iMinLength = Fse.FormManager.getFseAttribute( oInputField, "minimumlength" );
            if( iMinLength != undefined ) {
                if( oInputField.value.length < iMinLength ) {
                    iValidationStatus = Fse.FormManager.ValidationStatus.INVALID;
                }
            }
			// catch >max len pasted in textarea values
            var iMaxLength = Fse.FormManager.getFseAttribute( oInputField, "maximumlength" );
            if( iMaxLength != undefined && oInputField.type == 'textarea') {
                if( oInputField.value.length > iMaxLength ) {
                    iValidationStatus = Fse.FormManager.ValidationStatus.INVALID;
                }
            }
    	} else {
            // treat as regular expression
            var reCustom = new RegExp( fseFormat );
            if( ! reCustom.test( oInputField.value ) ) {
                iValidationStatus = Fse.FormManager.ValidationStatus.INVALID;
            }
        }
	} else {
		if( fseRequired != null ) {
			if( fseRequired.substring( 0, 1 ) == "|" ) {

				var requiredFieldMissing = true;
				var aOtherFields = fseRequired.split( "|" );
				for( var fx = 0; requiredFieldMissing && fx < aOtherFields.length; fx++ ) {
					var sOtherFieldName = aOtherFields[fx];
					if( sOtherFieldName && sOtherFieldName != "" ) {
						
						var oOtherField = oInputField.form.elements[sOtherFieldName];
						if( oOtherField ) {
							var reOtherEmpty;
							var sOtherEmpty = Fse.FormManager.getFseAttribute( oOtherField, "empty" );
							if( sOtherEmpty != undefined ) {
						        reOtherEmpty = new RegExp( "^" + sOtherEmpty + "$");
							} else {
							    reOtherEmpty = Fse.FormManager._reEmptyString;
							}
							requiredFieldMissing = reOtherEmpty.test( oOtherField.value );
						}
						
					}
				}
				
				if( requiredFieldMissing ) {
		       	    iValidationStatus = Fse.FormManager.ValidationStatus.REQUIRED;
				}
				
				
			} else if( fseRequired.toLowerCase() == "true" ) {
	       	    iValidationStatus = Fse.FormManager.ValidationStatus.REQUIRED;
			}
		}
	}
	return iValidationStatus;
};

Fse.FormManager.checkGS1Identifier = function( sValue, sFormat ) {
	
	var iValidationStatus = Fse.FormManager.ValidationStatus.INVALID;
	
	var _reFormatTest = null;
	
	// validate the format
	switch( sFormat ) {

		case "gs1_gln" :
			_reFormatTest = Fse.FormManager._reN13;
			break;

		case "gs1_gtin_8" :
			_reFormatTest = Fse.FormManager._reN8;
			break;

		case "gs1_gtin_12" :
			_reFormatTest = Fse.FormManager._reN12;
			break;

		case "gs1_gtin_13" :
			_reFormatTest = Fse.FormManager._reN13;
			break;
			
		case "gs1_gtin_14" :
			_reFormatTest = Fse.FormManager._reN14;
			break;
		
	}
	
	if( _reFormatTest != null && _reFormatTest.test( sValue )) {
	
		// now validate the check digit
		var _s = 0;
		var _x = sValue.charAt( sValue.length - 1 );
		var _m = 3;
		var _f = sValue.length - 2;
		for( var _p = _f; _p >= 0; _p-- ){
			_s = _s + ( sValue.charAt( _p ) * _m );
			if( _m == 3 ) {
				_m = 1;
			} else {
				_m = 3;
			}
		}
		
		if( _s % 10 != 0 ) {
			_b = Math.floor( (_s + 10 ) / 10 ) * 10;
		} else {
			_b = _s;			
		}
		
		var _c = _b - _s;
		
		if( _x == _c ) {
			iValidationStatus = Fse.FormManager.ValidationStatus.OK;
		}

	}
	
	return iValidationStatus;
};

Fse.FormManager.cleanseNumericValue = function( sValue ) {
	
	var reCleanse = /\$|,/g;
	return sValue.replace( reCleanse, "" );
};

Fse.FormManager.checkNumericRange = function( oField ) {

    var iValidationStatus = Fse.FormManager.ValidationStatus.OK;
    var nMinimum = Fse.FormManager.getFseAttribute( oField, "minvalue" );
    if( nMinimum != undefined ) {
        if( Fse.FormManager._reDecimal.test( nMinimum ) && (oField.value - nMinimum < 0) ) {
            iValidationStatus = Fse.FormManager.ValidationStatus.INVALID;
        }
    }

    /* skip the max check if we have already failed */    
    if( iValidationStatus != Fse.FormManager.ValidationStatus.OK ) {
        return iValidationStatus;
    }
    
    var nMaximum = Fse.FormManager.getFseAttribute ( oField, "maxvalue" );
    if( nMaximum != undefined ) {
        if( Fse.FormManager._reDecimal.test( nMaximum ) && ( nMaximum - oField.value < 0 )) {
            iValidationStatus = Fse.FormManager.ValidationStatus.INVALID;
        }
    }
    
    return iValidationStatus;
    
};

Fse.FormManager.getGroupField = function( oField ) {
    
    var oGroup = new Object();
    oGroup.name = oField.name;
    oGroup.required = false;
    oGroup.fields = new Array();
    
    var aElements = document.getElementsByName( oGroup.name );
    for( var idx = 0; idx < aElements.length; idx++ ) {
        var oFieldToCheck = aElements[idx];
        // on the same form?
        if( oFieldToCheck.form != undefined && oFieldToCheck.form == oField.form ) {
            oGroup.fields.push( oFieldToCheck );
            if( oFieldToCheck.getAttribute( "fse:required") == "true" ) {
                oGroup.required = true;
            }
        }
    }
    
    return oGroup;
}

Fse.FormManager.checkURL = function( sValueToText ) {
    return Fse.FormManager._reURL.test( sValueToText );    
};

Fse.FormManager.checkURL2 = function( sValueToText ) {
	if( sValueToText.search( /^(h|H)|:|\/\// )  != -1 ) {
		return Fse.FormManager._reURL.test( sValueToText )
	} else {
	    return Fse.FormManager._reURL2.test( sValueToText );    
	}
};

Fse.FormManager.checkTime = function( sValueToTest ) {
	return Fse.FormManager._reTime.test( sValueToTest );
};

Fse.FormManager.checkDate = function( sValueToTest ) {

    // do preliminary format check
    if( ! Fse.FormManager._reDate.test( sValueToTest ) ) {
        return false;
    }

    
    // change these for other date formats - currently uses mm/dd/yyyy
    var sDatePartDelimeter = "\/";
    var iMonth = 0; 
    var iDay = 1;
    var iYear = 2; 
    var bValid = true;
    
    var dtValueToTest;
    var aDate;
    try {
        aDate = sValueToTest.split( sDatePartDelimeter );  
        dtValueToTest = new Date(aDate[iYear], aDate[iMonth] - 1, aDate[iDay]);
        if ( isNaN(dtValueToTest) ) {
            bValid = false;
        }
    } catch (e) {
        bValid = false;
    }
    
    // if the date conversion succeeded, check its the actual date that was input
    // (e.g. it will accept 31/2/2003 but will change it to 3/3/2003)
    if (bValid) {
        if (aDate[iYear] != dtValueToTest.getFullYear()) {
            bValid = false;
        }
        if (aDate[iMonth] != 1 + dtValueToTest.getMonth()) {
            bValid = false;
        }
        if (aDate[iDay] != dtValueToTest.getDate()) {
            bValid = false;
        }
    }

    return bValid;
};

Fse.FormManager.updateCharsLeft = function ( oFieldToUpdate ) {
	//add delay - onkeyup and onkeydown timing issue with onkeypress
	setTimeout(function(){Fse.FormManager.updateCharsLeftDelay(oFieldToUpdate)},.2);
};

Fse.FormManager.updateCharsLeftDelay = function ( oFieldToUpdate ) {
    var iMaxLength = oFieldToUpdate.getAttribute( "fse:maximumlength" );
    if( iMaxLength ) {
        var iCurrentLength = oFieldToUpdate.value.length;
        var sStatusFieldName = oFieldToUpdate.name + "_charsleft";
        var oCharsLeft = document.getElementById( sStatusFieldName );
		if( iCurrentLength >= iMaxLength ){
			str = oFieldToUpdate.value;
			oFieldToUpdate.value = str.substring(0,iMaxLength);
		}
        if( oCharsLeft ) {
            var iCharsLeft = iMaxLength - iCurrentLength;
			if(oCharsLeft.type == 'text'){
				oCharsLeft.value = iCharsLeft;
			} else {
   	            oCharsLeft.innerHTML = iCharsLeft;
			}
        }
    }	
}


Fse.FormManager.checkFieldLength = function( oFieldToCheck ) {
    var bOk = true;
    var iMaxLength = oFieldToCheck.getAttribute( "fse:maximumlength" );
    if( iMaxLength ) {
        var iCurrentLength = oFieldToCheck.value.length;
        if( iCurrentLength >= iMaxLength ) {
			if( event.keyCode == 8 || event.keyCode == 46){
	            bOk = true;
			}else{
				bOk = false;
			}
        }
    }
    return bOk;
};



Fse.FormManager.registerForm = function( sForm ) {
	
	var oForm = document.forms[sForm];
	for( var fieldIdx = 0; fieldIdx < oForm.elements.length; fieldIdx++ ) {

		if( oForm.elements[fieldIdx].nodeType == 1 ) {
			
			if( oForm.elements[fieldIdx].type == "select-one" ) {
				var oSelect = oForm.elements[fieldIdx];
				var sSrc = Fse.FormManager.getFseAttribute( oSelect, "src" );
				if( sSrc != undefined ) {
					
					var sLoadMessage = Fse.FormManager.getFseAttribute( oSelect, "load-message" );
					if( sLoadMessage == undefined ) {
						sLoadMessage = "loading...";
					}
					
					// found fse:src - setup load on demand
					Fse.EventManager.addEventHandler( oSelect, "mousedown", 
						function () {
							Fse.FormManager._loadSelect( oSelect, sSrc, sLoadMessage );
						}
					);
					
					
				} else {
					// no fse:src - skip it
				}
			}
		}
	}
	
};


Fse.FormManager._loadSelect = function( oSelect, sSrc, sLoadMessage ) {

	if( oSelect.fseLoaded == undefined && ! oSelect.fseLoading ) {

		oSelect.fseLoading = true;

		var sSrcURL;
		if( false ) {
			sSrcURL = sSrc + "&jso=oSelect";
			//sSrc.search( "\?" )
		} else {
			sSrcURL = sSrc + "?jso=oSelect";
		}

		var oCurrentOption = oSelect.options[oSelect.selectedIndex];
		var sSaveText = oCurrentOption.text;
		oCurrentOption.text = sLoadMessage;

		try {
			
			var callback = function( oRequest ) {

				if( oRequest.xhRequest.status == "200" ) {
					eval( oRequest.xhRequest.responseText );
					var iOptionCount = oSelect_options.length;
					for( var idx = 0; idx < iOptionCount; idx++ ) {
						var _oOption = document.createElement( "option" );
						_oOption.appendChild( document.createTextNode( oSelect_options[idx].text ));
						_oOption.setAttribute( "value", oSelect_options[idx].value );
						oSelect.appendChild( _oOption );
					}
					oSelect.fseLoading = false;
					oSelect.fseLoaded = true;
				} else {
					alert( "Status: " + oRequest.xhRequest.status );
				}
				
				oCurrentOption.text = sSaveText;
				
			};
			
			Spry.Utils.loadURL( "GET", sSrcURL, true, callback );    
			
		} catch( exception ) {
			alert( exception.description );
		}
		
		
		
	}	
	
};


if( !Fse.FlexFields ) Fse.FlexFields = {};

Fse.FlexFields.addAnother = function( iFieldId, iMax ) {

	var oFieldNode = document.getElementById( "field_" + iFieldId + "_1" );
	var oAddAnotherNode = document.getElementById( "field_" + iFieldId + "_add_another" );
	if( oFieldNode && oAddAnotherNode) {

		var bInsert = false;

		var oLastFieldNode = oAddAnotherNode.parentNode.parentNode;
		if( oLastFieldNode.nextSibling ) {
			bInsert = true;
		} else {
			bInsert = false;
		}

		var iCurrentCount = oAddAnotherNode.getAttribute( "currentCount" ) * 1;
		var iNewCount = iCurrentCount + 1;
		
		oAddAnotherNode.parentNode.removeChild( oAddAnotherNode );
		var oNewFieldNode = oFieldNode.cloneNode( true );
		
		/* adjust as necessary to support new fieldIndex */
		var sNewId = oNewFieldNode.getAttribute( "id" ); 
		sNewId = sNewId.replace( /\d*$/, iNewCount );
		oNewFieldNode.setAttribute( "id", sNewId );
		
		var sOldName = oNewFieldNode.getAttribute( "nameToUse" );
		var sNewName = sOldName.replace( /\d*$/, iNewCount  );
		
		var reOldName = new RegExp( sOldName );
		oNewFieldNode.setAttribute( "nameToUse", sNewName );
		
		for( var idx = 0; idx < oNewFieldNode.childNodes.length; idx++ ) {
	
			var oNode = oNewFieldNode.childNodes[idx];
			if( oNode.nodeType == 1) {

				// look at elements
				var sNewId = oNode.getAttribute( "id" );
				if( sNewId ) {
					sNewId = sNewId.replace( reOldName, sNewName );
					oNode.setAttribute( "id", sNewId );
				}
				
				var sRawLabel = oNode.getAttribute( "rawLabel" );
				if( sRawLabel ) {
					var sNewLabel = sRawLabel.replace( /\${index}/, iNewCount );
					oNode.innerHTML = sNewLabel;
				}
				
				for( var ndx = 0; ndx < oNode.childNodes.length; ndx++ ) {
					
					oInnerNode = oNode.childNodes[ndx];
					// only elements
					if( oInnerNode.nodeType == 1 ) {
						
						var _sNewId = oInnerNode.getAttribute( "id" );
						if( _sNewId ) {
							_sNewId = _sNewId.replace( reOldName, sNewName );
							oInnerNode.setAttribute( "id", _sNewId );
						}

						var _sNewName = oInnerNode.getAttribute( "name" );
						if( _sNewName ) {
							_sNewName = _sNewId.replace( reOldName, sNewName );
							oInnerNode.setAttribute( "name", _sNewName );
						}
						
						var sType = oInnerNode.getAttribute( "type" );
						if( sType && sType == "text" ) {
							oInnerNode.value = "";
						}
						
						if( oInnerNode.nodeName == "TEXTAREA") {
							oInnerNode.innerHTML = "";
						}
						
						// && oInnerNode.getAttribute( "class" ) == "chars-left"
						if( oInnerNode.nodeName == "SPAN" ) {
							oInnerSpan = oInnerNode.firstChild;
							while( oInnerSpan && oInnerSpan.nodeName != "SPAN" ) {
								oInnerSpan = oInnerSpan.nextSibling;
							}
							if( oInnerSpan ) {
								var _sNewId = oInnerSpan.getAttribute( "id" );
								if( _sNewId ) {
									_sNewId = _sNewId.replace( reOldName, sNewName );
									oInnerSpan.setAttribute( "id", _sNewId );
									oInnerSpan.innerHTML = oInnerSpan.getAttribute( "maxLength" );
								} 
							}
						}
					
					}
					
				}
				
			}			
			
		}
		
		if( bInsert ) {
			oLastFieldNode.parentNode.insertBefore( oNewFieldNode, oLastFieldNode.nextSibling );
		} else {
			oLastFieldNode.parentNode.appendChild( oNewFieldNode );
		}		

		if( iNewCount < iMax ) {

			oAddAnotherNode.setAttribute( "currentCount", iNewCount );
		
			if( oNewFieldNode.lastChild.nodeType == 3) {
				/* firefox views the white space between the elements as a text node */
				oNewFieldNode.lastChild.previousSibling.appendChild( oAddAnotherNode );
			} else {
				oNewFieldNode.lastChild.appendChild( oAddAnotherNode );
			}
		
		}
	}
	
};

Fse.FormManager.toQueryString = function( oForm, sFieldPattern ) {

	var data = [];
	var item = 0;
	
	var reFieldPattern = null;
	if( sFieldPattern ) {
		reFieldPattern = new RegExp( sFieldPattern );
	}
	
	// Iterate over the form elements collection to construct the
	// label-value pairs.
	for (i=0,len=oForm.elements.length; i<len; ++i){
		oElement  = oForm.elements[i];
		oDisabled = oElement.disabled;
		
        oName     = oElement.name;
        
        // when a pattern was provided, skip any fields where the name doesn't match the pattern 
        if( oName && reFieldPattern ) {
        	if( reFieldPattern.test( oName ) == false) {
        		bSkip = true;
        	} else {
        		bSkip = false;
        	}
        } else {
        	bSkip = false;
        }

		// Do not submit fields that are disabled or
		// do not have a name attribute value.
		if(!bSkip && !oDisabled && oName)
		{
            oName  = encodeURIComponent(oName)+'=';
            oValue = encodeURIComponent(oElement.value);

			switch(oElement.type)
			{
                // Safari, Opera, FF all default opt.value from .text if
                // value attribute not specified in markup
				case 'select-one':
                    if (oElement.selectedIndex > -1) {
                        opt = oElement.options[oElement.selectedIndex];
                        data[item++] = oName + encodeURIComponent(
                            (opt.attributes.value && opt.attributes.value.specified) ? opt.value : opt.text);
                    }
                    break;
				case 'select-multiple':
                    if (oElement.selectedIndex > -1) {
                        for(j=oElement.selectedIndex, jlen=oElement.options.length; j<jlen; ++j){
                            opt = oElement.options[j];
                            if (opt.selected) {
                                data[item++] = oName + encodeURIComponent(
                                    (opt.attributes.value && opt.attributes.value.specified) ? opt.value : opt.text);
                            }
                        }
                    }
					break;
				case 'radio':
				case 'checkbox':
					if(oElement.checked){
                        data[item++] = oName + oValue;
					}
					break;
				case 'file':
					// stub case as XMLHttpRequest will only send the file path as a string.
				case undefined:
					// stub case for fieldset element which returns undefined.
				case 'reset':
					// stub case for input type reset button.
				case 'button':
					// stub case for input type button elements.
					break;
				case 'submit':
					if(hasSubmit === false){
						if(this._hasSubmitListener && this._submitElementValue){
                            data[item++] = this._submitElementValue;
						}
						hasSubmit = true;
					}
					break;
				default:
                    data[item++] = oName + oValue;
			}
		}
	}

	var s = data.join( "&" );
	return s;
	
};

Fse.FormManager.validationAlert = function( oForm, sMessage ) {
	var oSocket = Fse.FormManager.getValidationAlertElement( oForm );
	if( oSocket ) {
		oSocket.innerHTML = sMessage.split(".")[0];
		oSocket.setAttribute( "title",sMessage );
	} else {
		alert( sMessage ); 
	}
};

Fse.FormManager.resetValidationAlert = function( oForm ) {
	var oSocket = Fse.FormManager.getValidationAlertElement( oForm );
	if( oSocket ) {
		oSocket.innerHTML = "";
		oSocket.removeAttribute( "title" ); 
	}
};

Fse.FormManager.getValidationAlertElement = function( oForm ) {
	var sFormName = oForm.getAttribute( "name" );
	return document.getElementById( sFormName + "_validationAlert" );
};

