// Unicode chars: "网イ"  (to force Eclipse to save as UTF-8 encoding)

// FORM VALIDATION LIBRARY 1.2 by Jean-Matthieu Bourgeot 2002

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// VALIDATION TYPES CONSTANTS
var LETTERS_ONLY = 1;
var VALID_NUMBER = 2;
var VALID_INTEGER = 3;
var INTEGER_GREATER_OR_EQUAL = 4;
var INTEGER_SMALLER_OR_EQUAL = 5;
var INTEGER_BETWEEN_INCLUSIVE = 6;
var VALID_EMAIL_ADDRESS = 7;
var VALID_IP_ADDRESS = 8;
var MUST_MATCH_OTHER_FIELD = 9;
var FIELD_MUST_NOT_BE_EMPTY = 10;
var FIELD_MUST_NOT_BE_MINUS_ONE = 11;
var PERCENTAGE = 12;
var NUMBER_GREATER_OR_EQUAL = 13;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ERROR MESSAGES

var must_be_letters = unescape("[{0}] must be composed of letters only.");
var must_be_a_number = unescape("[{0}] must be a valid number.");
var must_be_an_integer = unescape("[{0}] must be an integer.");
var must_be_an_integer_greater_or_equal = unescape("[{0}] must be an integer greater or equal than {1}.");
var must_be_an_integer_smaller_or_equal = unescape("[{0}] must be an integer smaller or equal than {1}.");
var must_be_an_integer_between_inclusive = unescape("[{0}] must be a integer between {1} and {2}.");
var must_be_a_valid_email_address = unescape("[{0}] must be a valid email address.");
var must_be_a_valid_ip_address = unescape("[{0}] must be a valid IP address.");
var must_match_other_field = unescape("[{0}] does not match [{1}].");
var must_not_be_empty = unescape("[{0}] must not be empty.");
var must_not_be_minus_one = unescape("Select a value for [{0}]");
var must_be_a_number_greater_or_equal = unescape("[{0}] must be a number greater or equal than {1}.");


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// GLOBALS
var controlsToValidate = [];

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// VALIDATOR OBJECT
function o_controlValidator(control, controlLabel, validationType, param1, param2)
{
     this.control = control;
     this.controlLabel = controlLabel;
     this.param1 = param1 || 0;
     this.param2 = param2 || 0;

     if (validationType == LETTERS_ONLY) this.validate = validateLettersOnly;
     if (validationType == VALID_NUMBER) this.validate = validateNumber;
     if (validationType == VALID_INTEGER) this.validate = validateInteger;
     if (validationType == INTEGER_GREATER_OR_EQUAL) this.validate = validateIntegerGreaterOrEqual;
     if (validationType == INTEGER_SMALLER_OR_EQUAL) this.validate = validateIntegerSmallerOrEqual;
     if (validationType == INTEGER_BETWEEN_INCLUSIVE) this.validate = validateIntegerBetweenInclusive;
     if (validationType == VALID_EMAIL_ADDRESS) this.validate = validateEmailAddress;
     if (validationType == VALID_IP_ADDRESS) this.validate = validateIPAddress;
     if (validationType == MUST_MATCH_OTHER_FIELD) this.validate = validateMatchOtherField;
     if (validationType == FIELD_MUST_NOT_BE_EMPTY) this.validate = validateFieldMustNotBeEmpty;
     if (validationType == FIELD_MUST_NOT_BE_MINUS_ONE) this.validate = validateFieldMustNotBeMinusOne;
     if (validationType == PERCENTAGE) { this.param1 = 0; this.param2 = 100;  this.validate = validateIntegerBetweenInclusive; }
     if (validationType == NUMBER_GREATER_OR_EQUAL) this.validate = validateNumberGreaterOrEqual;
     
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// VALIDATION MEMBER METHODS

function validateLettersOnly()
{
     var errorMessage = "";
     return errorMessage;
}

// CAN BE EITHER A MEMBER METHOD OR A STANDALONE METHOD
function validateNumber(value)
{
     var errorMessage = "";
     var valueToValidate = (value === undefined) ? this.control.value : value;

     // REPLACE EVENTUAL COMMA BY A DOT FOR THE NUMBER VALIDATION TO WORK : isNaN() 
     valueToValidate = valueToValidate.replace(",", ".");

     if (valueToValidate === "" || isNaN(valueToValidate))
          errorMessage = must_be_a_number.replace("{0}", this.controlLabel);

     return errorMessage;
}

// CAN BE EITHER A MEMBER METHOD OR A STANDALONE METHOD
function validateInteger(value)
{
     var errorMessage = "";
     var valueToValidate = (value === undefined) ? this.control.value : value;

     if ( validateNumber(valueToValidate) !== "" || (valueToValidate.indexOf(".") != -1))
          errorMessage = must_be_an_integer.replace("{0}", this.controlLabel);

     return errorMessage;
}

// CAN BE EITHER A MEMBER METHOD OR A STANDALONE METHOD
function validateIntegerGreaterOrEqual(value)
{
     var errorMessage = "";
     var valueToValidate = (value === undefined) ? this.control.value : value;

     if (!((validateInteger(valueToValidate) === "") && (valueToValidate >= this.param1)))
          errorMessage = must_be_an_integer_greater_or_equal.replace("{0}", this.controlLabel).replace("{1}", this.param1);

     return errorMessage;
}

// CAN BE EITHER A MEMBER METHOD OR A STANDALONE METHOD
function validateIntegerSmallerOrEqual(value)
{
     var errorMessage = "";
     var valueToValidate = (value === undefined) ? this.control.value : value;

     if (!((validateInteger(valueToValidate) === "") && (valueToValidate <= this.param2)))
          errorMessage = must_be_an_integer_smaller_or_equal.replace("{0}", this.controlLabel).replace("{1}", this.param2);

     return errorMessage;
}

function validateIntegerBetweenInclusive()
{
     var errorMessage = "";

     if (!((validateInteger(this.control.value) === "") && (this.control.value >= this.param1) && (this.control.value <= this.param2)))
          errorMessage = must_be_an_integer_between_inclusive.replace("{0}", this.controlLabel).replace("{1}", this.param1).replace("{2}", this.param2);

     return errorMessage;
}

function validateEmailAddress()
{
     var errorMessage = "";

     var filter=/^[a-zA-Z0-9._\-]+@([a-zA-Z0-9.\-]+\.)+[a-zA-Z0-9.\-]{2,4}$/;
     if (!filter.test(this.control.value))
          errorMessage = must_be_a_valid_email_address.replace("{0}", this.controlLabel);

     return errorMessage;
}

function validateIPAddress()
{
     var errorMessage = "";

     var filter=/^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$/i;
     if (!filter.test(this.control.value))
          errorMessage = must_be_a_valid_ip_address.replace("{0}", this.controlLabel);

     return errorMessage;
}

// param1: target control whose value must match
// param2: target control label
function validateMatchOtherField()
{
     var errorMessage = "";

     if (this.control.value != this.param1.value)
          errorMessage = must_match_other_field.replace("{0}", this.controlLabel).replace("{1}", this.param2);

     return errorMessage;
}


function validateFieldMustNotBeEmpty()
{
     var errorMessage = "";
     
     // If jQuery is present it is better to use val() to get the control value
     // which always returns the correct value when using customized UI controls
     // such as "jQuery Chosen" (Select Box Enhancer).
     var value = (jQuery) ? jQuery(this.control).val() : this.control.value; 

     if (trimString(value) === "")
          errorMessage = must_not_be_empty.replace("{0}", this.controlLabel);

     return errorMessage;
}


function validateFieldMustNotBeMinusOne()
{
     var errorMessage = "";

     if (this.control.value == -1)
         errorMessage = must_not_be_minus_one.replace("{0}", this.controlLabel);

     return errorMessage;
}

// CAN BE EITHER A MEMBER METHOD OR A STANDALONE METHOD
function validateNumberGreaterOrEqual(value)
{
     var errorMessage = "";
     var valueToValidate = (value === undefined) ? this.control.value : value;

     // REPLACE EVENTUAL COMMA BY A DOT FOR THE NUMBER VALIDATION TO WORK : isNaN() 
     valueToValidate = valueToValidate.replace(",", ".");

     if (!((validateNumber(valueToValidate) === "") && (valueToValidate >= this.param1)))
          errorMessage = must_be_a_number_greater_or_equal.replace("{0}", this.controlLabel).replace("{1}", this.param1);

     return errorMessage;
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// GLOBAL METHODS

// USED TO REGISTER A CONTROL TO BE VALIDATED WHEN validateControls() IS CALLED
function registerControlForValidation(control, controlLabel, validationType, param1, param2)
{
     controlsToValidate[controlsToValidate.length] = new o_controlValidator(control, controlLabel, validationType, param1, param2);
}

// STARTS VALIDATION OF EVERY REGISTERED CONTROL, RETURNS TRUE OR FALSE AND DISPLAY ERROR MESSAGE FOR CONTROLS THAT ARE INVALID
function validateControls()
{
     var errorMessage = "";

     for (var i=0; i<controlsToValidate.length; i++) {
          var msg = controlsToValidate[i].validate();
          if (msg !== "")
               errorMessage+= msg + "\n";
     }

     if (errorMessage === "")
          return true;
     else
          alert(errorMessage);

     return false;
}


// REMOVES LEADING AND TRAILING SPACES FROM THE PASSED STRING.
// If something besides a string is passed in (null, custom object, etc.)
// then return the input.
function trimString(inputString)
{
   if (typeof inputString != "string")
       return inputString;

   var retValue = inputString;
   var ch = retValue.substring(0, 1);

   // REMOVES LEADING SPACES.
   while (ch == " ") {
      retValue = retValue.substring(1, retValue.length);
      ch = retValue.substring(0, 1);
   }
   ch = retValue.substring(retValue.length-1, retValue.length);

   // REMOVES TRAILING SPACES.
   while (ch == " ") {
      retValue = retValue.substring(0, retValue.length-1);
      ch = retValue.substring(retValue.length-1, retValue.length);
   }

   return retValue;
}
