// Perform Validation Checks //
function ValidateRuleSet(ruleSet, controlName, value)
{
	var errMsg;
	
	value = value.trim();

	if(ruleSet.IsRequiredForSubmit && (value.length == 0))
	{
		errMsg = ruleSet.GetRequiredFieldErrorMessage(controlName, value);
	}
	else if((value.length != 0) && ruleSet.HasTextFieldRuleSet)
	{
		errMsg = ValidateTextFieldRuleSet(ruleSet.TextFieldRuleSet, controlName, value);
	}

	return errMsg;
}

function ValidateTextFieldRuleSet(textFieldRuleSet, controlName, value)
{
	var errMsg = null;

	if(value == UNKNOWN_VALUE)
	{
		if(!textFieldRuleSet.CanBeUnknown)
		{
			errMsg = textFieldRuleSet.GetUnknownErrorMessage(controlName, value);
		}
	}
	else
	{
	    if((value.indexOf(OVERRIDE_STRING) == 0) && (errMsg == null))
	    {
	        if(textFieldRuleSet.CanUseOverride)
            {
                value = value.substr(1);
                
                if (value.length == 0)
                {
                    errMsg = textFieldRuleSet.GetOnlyOverrideStringErrorMessage(controlName, value);
                }
            }
            else
            {
                errMsg = textFieldRuleSet.GetRangeOverrideErrorMessage(controlName, value);
            }
	    }
    	
	    if(textFieldRuleSet.HasFormat && (value.length > 0) && (errMsg == null))
	    {
		    var regExp = new RegExp(textFieldRuleSet.RegularExpression.Expression);

		    if(!regExp.exec(value))
		    {
			    errMsg = textFieldRuleSet.RegularExpression.CreateRegExErrorMessage(controlName, value);
		    }
	    }
	}

	return errMsg;
}

String.prototype.trim = function() { return this.replace(/^\s+|\s+$/, ''); };

// Validation Rule Objects //
function RuleSet(name, IsRequiredForSubmit, textFieldRuleSet)
{
	this.Name = name;
	this.IsRequiredForSubmit = IsRequiredForSubmit;
	this.TextFieldRuleSet = textFieldRuleSet;

	this.HasTextFieldRuleSet = (textFieldRuleSet != null);

	this.GetRequiredFieldErrorMessage = function(controlName, value)
    {
		var array = new Array();
		array[0] = controlName;
		array[1] = value;

		return PopulateStringPlaceholders(REQUIRED_ERROR_MSG, array);
    }
}

function TextFieldRuleSet(maxLength, canBeUnknown, canUseOverride, regularExpression)
{
	this.MaxLength = maxLength;
	this.CanBeUnknown = canBeUnknown;
	this.CanUseOverride = canUseOverride;
	this.RegularExpression = regularExpression;

	this.HasFormat = (regularExpression != null);

	this.GetUnknownErrorMessage = function(controlName, value)
	{
		return UNKNOWN_ERROR_MSG.replace("{0}", controlName);
	}
        
	this.GetRangeOverrideErrorMessage = function(controlName, value)
	{
		var array = new Array();
		array[0] = controlName;
		array[1] = value;

		return PopulateStringPlaceholders(OVERRIDE_ERROR_MSG, array);
	}
	
	this.GetOnlyOverrideStringErrorMessage = function(controlName, value)
    {
        var array = new Array();
		array[0] = controlName;
		array[1] = value;
		array[2] = OVERRIDE_STRING;
		
        return PopulateStringPlaceholders(ONLY_OVERRIDE_STRING_ERROR_MSG, array);
    }
}

function RegularExpression(name, expression, dataType, displayExpression)
{
	this.Name = name;
	this.Expression = expression;
	this.DataType = dataType;
	this.DisplayExpression = displayExpression;

	this.CreateRegExErrorMessage = function (controlName, value)
	{
		var array = new Array();
		array[0] = controlName;
		array[1] = value;
		array[2] = dataType;

		var errMsg = PopulateStringPlaceholders(REGEX_ERROR_MSG_BASE, array);

		if ((displayExpression != null) && (displayExpression.length != 0))
		{
			errMsg += REGEX_ERROR_MSG_EX.replace("{0}", displayExpression);
		}

		return errMsg;
	}
}

// Helpers //
function GetValue(controlId)
{
    var value = "";
    var control = document.getElementById(controlId+"_0");

    // This indicates a radio button or check box group
    if(control != null)
    {
        // There is no need to validate radio or check values here, because they are created
        // at design time (if they exist at all).  It only makes sense to validate whether 
        // any in the group have been checked, so just keep a count.
        var selected = 0;
	   
        for(var i=1; control != null; i++)
        {
            if(control.checked)
            {
                selected++;
            }

            control = document.getElementById(controlId+"_"+i);
        }
        
        if(selected > 0)
        {
            value += selected;
        }
    }
    // This handles a drop down, text box, or text area
    else
    {
        control = document.getElementById(controlId);

        if(control != null)
        {
            // Select/Multiselect
            if(control.type.indexOf("select") == 0)
            {
                var selected = 0;

                for(var i=0; i<control.options.length; i++)
                {
                    if(control.options[i].selected && control.options[i].value != NO_VALUE)
                    {
                        selected++;
                    }
                }

                if(selected > 0)
                {
                    value += selected;
                }
            }
            // Single checkbox/radiobutton
            else if((control.type == 'checkbox') || (control.type == 'radio'))
            {
                if(control.checked)
                {
                    value += 1;
                }
            }
            // Text control
            else
            {
                value = control.value.replace(/\s/g, "");
            }
        }
        else
        {
            alert("Control [" + controlId + "] not found");
        }
    }

    return value;
}

function PopulateStringPlaceholders(genericMsg, array)
{
	var regExp;

	for(var i=0; i<array.length; i++)
	{
		regExp = new RegExp("\\{"+i+"\\}","g");
		genericMsg = genericMsg.replace(regExp, array[i]);
	}

	return genericMsg;
}
