// List of allowed symbols for different field types
var digits      = "0123456789";
var letters_low = "abcdefghijklmnopqrstuvwxyz";
var letters_up  = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var letters = letters_low + letters_up;
var simbols = digits + letters;
// List of banned simbols for different field types
var all_banned  = "!?.,;:/\'\"@#$&^%~|+=()[]{}<>_*-";
var banned      = "!?,;:/\"@#$&^%~|+=[]{}<>_*";
var aError = new Array();

// Check if value of target field is name (first name, last name, etc.)
//   max length is 150
function isName(oField, sName)
{
  var max_length = 150;

  return checkLength(max_length, oField, sName);
} 


// Check if value of target field is address
//   max length is 150
function isAddress(oField, sName)
{
  var max_length = 150;

  return checkLength(max_length, oField, sName);
} 


// Email address must be of form a@b.c ... in other words:
//   there must be at least one character before the "@"
//   there must be at least one character before the "."
//   there must be at least two character after the "."
//   the characters @ and . are both required
function isEmail(oField, sName)
{
  var s = oField.value;
  var l = s.length;
  var max_length = 150;
  var sError = "Field '" + sName + "': invalid e-mail address.";

  if (isEmpty(s)) return true;
  if (!checkLength(max_length, oField, sName)) return false;

// there must be >= 1 character before "@", so we
// start looking at character position 1 
// (i.e. second character)
  var i = 1;

// look for "@"
  while ((i < l) && (s.charAt(i) != "@"))
  {
    i++;
  }

  if ((i >= l) || (s.charAt(i) != "@"))
  {
    error(oField, sError);
    return false;
  }
  else
  {
//  Check First Part
    if (!checkAllowed(s.substring(0, i), simbols + "-_."))
    {
      error(oField, sError);
      return false;
    }

//  Check Last Part
    if (!checkAllowed(s.substring(i + 1, s.length), simbols + "-."))
    {
      error(oField, sError);
      return false;
    }

    i += 2;
  }

// look for "."
  while ((i < l) && (s.charAt(i) != "."))
  {
    i++;
  }

// there must be at least two character after the "."
  if ((i >= l - 2) || (s.charAt(i) != "."))
  {
    error(oField, sError);
    return false;
  }
  else
  {
    return true;
  }
}


// Value of target field should be an integer number
function isInteger(oField, sName)
{
  if (checkAllowed(oField.value, digits))
  {
    return true;
  }
  else
  {
    error(oField, "Field '" + sName + "' should be an integer number.");
    return false;
  }
}

// Value of target field should be an integer number
function isIntegerPositive(oField, sName)
{
  if (checkAllowed(oField.value, digits) && oField.value > 0)
  {
    return true;
  }
  else
  {
    error(oField, "Field '" + sName + "' should be a positive integer number.");
    return false;
  }
}

// Value of target field should be a string of latin characters
function isString(oField, sName)
{
  if (checkAllowed(oField.value, letters))
  {
    return true;
  }
  else
  {
    error(oField, "Field '" + sName + "' should contain letter symbols only.");
    return false;
  }
}


// Check if value of target field is city name
//   max length is 150
//   letters of any language are allowed (digits and special simbols are banned)
function isCity(oField, sName)
{
  var max_length = 150;

  if (!checkLength(max_length, oField, sName)) return false;

  if (checkNotAllowed(oField.value, banned + digits))
  {
    return true;
  }
  else
  {
    error(oField, "Field '" + sName + "' is incorrect city name.");
    return false;
  }
}


// Check if value of target field is "russian" city name (could contain digits)
//   max length is 150
//   letters of any language and digits are allowed (only special simbols are banned)
function isCityRU(oField, sName)
{
  var max_length = 150;

  if (!checkLength(max_length, oField, sName)) return false;

  if (checkNotAllowed(oField.value, banned))
  {
    return true;
  }
  else
  {
    error(oField, "Field '" + sName + "' is incorrect city name.");
    return false;
  }
}


// Check if value of target field is zip code (in free format)
//   max length is 10
//   latin letters and digits are allowed
function isZip(oField, sName)
{
  var max_length = 10;

  if (!checkLength(max_length, oField, sName)) return false;
  
  if (checkAllowed(oField.value, simbols))
  {
    return true;
  }
  else
  {
    error(oField, "Field '" + sName + "' should contain letters and digits only.");
    return false;
  }
}


// Check if value of target field is USA zip code (in format XXXXX or XXXXX-XXXX, X - digit)
function isZipUS(oField, sName)
{
  var zipPattern1 = /^(\d{5})$/;
  var zipPattern2 = /^(\d{5})\-(\d{4})$/;
  var s = oField.value;

  if (isEmpty(s)) return true;

  //if ((s.match(zipPattern1) == null) && (s.match(zipPattern2) == null))
  if (s.match(zipPattern1) == null)
  {
    error(oField, "Field '" + sName + "' should be in format XXXXX.");
    return false;
  }

  return true;
}

// Check if value of target field is phone number (in free format)
//   max length is 7
//   max length is 50
//   latin letters and digits and "-.()+ " simbols are allowed
function isPhone(oField, sName)
{
  var min_length = 7;
  var max_length = 50;

  if (!checkLength(max_length, oField, sName)) return false;
  if (!checkMinLength(min_length, oField, sName)) return false;
  
  if (checkAllowed(oField.value, simbols + "-.()+ "))
  {
    return true;
  }
  else
  {
    error(oField, "Field '" + sName + "' is incorrect phone number.");
    return false;
  }
}


// Check if value of target field is USA phone number (in format XXX-XXX-XXXX, X is digit)
function isPhoneUS(oField, sName)
{
  var phonePattern = /^(\d{3})\-(\d{3})\-(\d{4})$/;

  if (isEmpty(oField.value)) return true;
  if (oField.value.match(phonePattern) == null)
  {
    error(oField, "Field '" + sName + "' should be in format XXX-XXX-XXXX.");
    return false;
  }

  return true;
}


// Check if value of target field is "russian" phone number (couldn't contain letters)
//   max length is 7
//   max length is 50
//   digits and "-.()+ " simbols are allowed
function isPhoneRU(oField, sName)
{
  var min_length = 7;
  var max_length = 50;

  if (!checkLength(max_length, oField, sName)) return false;
  if (!checkMinLength(min_length, oField, sName)) return false;
  
  if (checkAllowed(oField.value, digits + "-.()+ "))
  {
    return true;
  }
  else
  {
    error(oField, "Field '" + sName + "' is incorrect phone number.");
    return false;
  }
}


// Check if value of target field is password
//   max length is 6
//   max length is 12
function isPassword(oField, sName)
{
  var min_length = 6;
  var max_length = 12;

  if (!checkLength(max_length, oField, sName)) return false;
  if (!checkMinLength(min_length, oField, sName)) return false;

  return true;
}


// Check if value of target field is credit card number
//   max length is 16
//   max length is 18
//   only digits are allowed
function isCreditCardNumber(oField, sName)
{
  var min_length = 16;
  var max_length = 18;

  if (!checkLength(max_length, oField, sName)) return false;
  if (!checkMinLength(min_length, oField, sName)) return false;
  
  if (checkAllowed(oField.value, digits))
  {
    return true;
  }
  else
  {
    error(oField, "Field '" + sName + "' should contain digits only.");
    return false;
  }
}


// Check if value of target field is credit card cvv
//   max length is 3
//   max length is 4
//   only digits are allowed
function isCreditCardCVV(oField, sName)
{
  var min_length = 3;
  var max_length = 4;

  if (!checkLength(max_length, oField, sName)) return false;
  if (!checkMinLength(min_length, oField, sName)) return false;
  
  if (checkAllowed(oField.value, digits))
  {
    return true;
  }
  else
  {
    error(oField, "Field '" + sName + "' should contain digits only.");
    return false;
  }
}


// Check if value of target field is flat number
//   max length is 5
//   letters and digits are allowed
function isFlat(oField, sName)
{
  var max_length = 5;

  if (isEmpty(oField.value)) return true;
  if (!checkLength(max_length, oField, sName)) return false;
  
  if (checkNotAllowed(oField.value, all_banned))
  {
    return true;
  }
  else
  {
    error(oField, "Field '" + sName + "' should contain digits only.");
    return false;
  }
}


// Check if value of target field is building number
//   max length is 3
//   letters and digits are allowed
function isBuilding(oField, sName)
{
  var max_length = 3;
  var s = new String(oField.value);

  if (isEmpty(s)) return true;
  if (!checkLength(max_length, oField, sName)) return false;
  
  if (checkNotAllowed(s, all_banned))
  {
    return true;
  }
  else
  {
    error(oField, "Field '" + sName + "' should contain letters and digits only.");
    return false;
  }
}


// Returns true if the string passed in is a valid money
//   only digits and "." are allowed
//   rounds to two digits after decimal dot
function isMoney(oField, sName)
{
  var max_length = 10;
  var s = oField.value;

  if (isEmpty(s)) return true;
  if (!checkLength(max_length, oField, sName)) return false;

  if (checkAllowed(s, digits + "."))
  {
    //oField.value = Math.round(parseFloat(s)*100)/100;
    return true;
  }
  else
  { 
    //alert("Field '" + sName + "' contains incorrect money amount.");
	//oField.focus();
    return false;
  }
}


// Check if value of target field is float number
//   only digits and "." are allowed
//   no accuracy limitations
function isFloat(oField, sName)
{
  var s = oField.value;

  if (isEmpty(s)) return true;
  if (checkAllowed(s, digits + "."))
  {
    oField.value = parseFloat(s);
    return true;
  }
  else
  {
    error(oField, "Field '" + sName + "' is incorrect float number.");
    return false;
  }
}

function isStartUrl(oField, sName)
{
  var s = oField.value;

  if (s.substr(0, 7) == 'http://')
	return true;
  if (s.substr(0, 7) == 'HTTP://')
	return true;
  if (s.substr(0, 8) == 'https://')
	return true;
  if (s.substr(0, 8) == 'HTTPS://')
	return true;
 
 return false;
}

// Check if value of target field is URL
//   function automatically cuts 'http://' value 
//   max length is 4
//   max length is 100
//   only digits and "." simbol are allowed
//   value should contain "." simbol, but not in first or last position
function isURL(oField, sName)
{
  var s = oField.value;

  var min_length = 4;
  var max_length = 100;
  var sError = "Field '" + sName + "' is incorrect URL.";

// Cut http
  if (s.substr(0, 7) == 'http://')
  {
    oField.value = s.replace('http://', '');
  }
  else if (s.substr(0, 7) == 'HTTP://')
  {
    oField.value = s.replace('HTTP://', '');
  }

  if (!checkLength(max_length, oField, sName)) return false;
  if (!checkMinLength(min_length, oField, sName)) return false;

  if (checkAllowed(oField.value, simbols + "-./&?_"))
  {
//  Search dot (from second position)
    var i = 1;

// look for "."
    while ((i < s.length) && (s.charAt(i) != "."))
    {
      i++;
    }

    if ((i == 0) || (i == (s.length)))
    {
      error(oField, sError);
      return false;
    }
    else
    {
//    Check last simbol isn't dot
      if (s.substring(s.length - 1, s.length) == ".")
      {
        error(oField, sError);
        return false;
      }
      else
      {
        return true;
      }
    }
  }
  else
  {
    error(oField, sError);
    return false;
  }
}


// Check if value of target field is IP address
//   required format is N.N.N.N, N is number from 0 to 255
//   IP Addresses 0.0.0.0 and 255.255.255.255 are banned
function isIP(oField, sName) 
{
  var s = oField.value;
  var sError = "Field '" + sName + "' is incorrect IP address.";
  
  var ipPattern = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/;

  if (isEmpty(s)) return true;

  if ((s == "0.0.0.0") || (s == "255.255.255.255"))
  {
    error(oField, sError);
    return false;
  }

  var ipArray = s.match(ipPattern);
  if (ipArray == null)
  {
    error(oField, sError);
    return false;
  }
  else
  {
    for (i = 1; i <= 4; i++)
    {
      if (ipArray[i] > 255)
      {
        error(oField, sError);
        return false;
      }
    }
  }

  return true;
}


// Check if value of target field is SSN - Social Security Number (in format XXX-XX-XXXX or XX-XXXXXXX, X is digit)
function isSSN(oField, sName)
{
  var ssnPattern1 = /^(\d{3})\-(\d{2})\-(\d{4})$/;
  var ssnPattern2 = /^(\d{2})\-(\d{7})$/;
  var s = oField.value;

  if (isEmpty(s)) return true;

  if ((s.match(ssnPattern1) == null) && (s.match(ssnPattern2) == null))
  {
    error(oField, "Field '" + sName + "' should be in format XXX-XX-XXXX or XX-XXXXXXX.");
    return false;
  }

  return true;
}


// Check if value of target field is house number
//   digits and letters are allowed
//   one letter (in any language) is optional and could be only on last position
function isHouse(oField, sName)
{
  var housePattern = /^(\d{1,4})(\S{0,1})$/;

  if (isEmpty(oField.value)) return true;

  if (!checkNotAllowed(oField.value, all_banned))
  {
    error(oField, "Field '" + sName + "' should contain digits and letters only.");
    return false;
  }
  else if ((oField.value.match(housePattern) == null))
  {
    error(oField, "Field '" + sName + "': incorrect value.");
    return false;
  }

  return true;
}


// Check if value of target field is a valid date (in USA format: MM/DD/YYYY)
function isDate(oField, sName)
{   
  var s = new String(oField.value);
  var len = s.length;
  var sError = "Field '" + sName + "' should be in MM/DD/YYYY format.";

  if (isEmpty(oField.value)) return true;

  var aDate = s.split("/");

  if (checkAllowed(s, digits + "/") && (aDate.length == 3))
  {
//  Month
    if ((aDate[0] <= 0) || (aDate[0] > 12))
    {
      error(oField, sError);
      return false;
    }

//  Day
    if ((aDate[1] <= 0) || (aDate[1] > 31))
    {
      error(oField, sError);
      return false;
    }

//  Year
    if ((aDate[2] < 1000) || (aDate[2] > 9999))
    {
      error(oField, sError);
      return false;
    }
  }
  else
  {
    error(oField, sError);
    return false;
  }

  return true;
}


// Check if value of target field is a valid date (in USA format: MM/DD/YYYY or MM/DD/YY)
function isDateUS(oField, sName)
{   
	var s = new String(oField.value);
	var len = s.length;
	var sError = "Field '" + sName + "' should be in MM/DD/YYYY or MM/DD/YY format.";
	
	if (isEmpty(oField.value)) 
		return true;
	
	var aDate = s.split("/");
	
	if (checkAllowed(s, digits + "/") && (aDate.length == 3))
	{
		//  Month
		if ((aDate[0] <= 0) || (aDate[0] > 12))
		{
			error(oField, sError);
			return false;
		}
		//  Day
		if ((aDate[1] <= 0) || (aDate[1] > 31))
		{
			error(oField, sError);
			return false;
		}
		//  Year
		var isLongYear = (aDate[2] >= 1000) && (aDate[2] <= 9999);
		var isShortYear = (aDate[2] >= 00) && (aDate[2] <= 99);
		if ( !isLongYear && !isShortYear )
		{
			error(oField, sError);
			return false;
		}
	}
	else
	{
		error(oField, sError);
		return false;
	}
	return true;
}

// Check if value of target field is a valid date (in USA format: MM/YYYY or MM/YY)
function isShortDateUS(oField, sName)
{   
	var s = new String(oField.value);
	var len = s.length;
	var sError = "Field '" + sName + "' should be in MM/YYYY or MM/YY format.";
	
	if (isEmpty(oField.value)) 
		return true;
	
	var aDate = s.split("/");
	
	if (checkAllowed(s, digits + "/") && (aDate.length == 2))
	{
		//  Month
		if ((aDate[0] <= 0) || (aDate[0] > 12))
		{
			error(oField, sError);
			return false;
		}
		//  Year
		var isLongYear = (aDate[1] >= 1000) && (aDate[1] <= 9999);
		var isShortYear = (aDate[1] >= 00) && (aDate[1] <= 99);
		if ( !isLongYear && !isShortYear )
		{
			error(oField, sError);
			return false;
		}
	}
	else
	{
		error(oField, sError);
		return false;
	}
	return true;
}

// Check if value of target field is a valid date (in Europian format: DD.MM.YYYY)
function isDateRU(oField, sName)
{   
  var s = new String(oField.value);
  var len = s.length;
  var sError = "Field '" + sName + "' should be in DD.MM.YYYY format.";

  if (isEmpty(oField.value)) return true;

  var aDate = s.split(".");

  if (checkAllowed(s, digits + ".") && (aDate.length == 3))
  {
//  Day
    if ((aDate[0] <= 0) || (aDate[0] > 31))
    {
      error(oField, sError);
      return false;
    }

//  Month
    if ((aDate[1] <= 0) || (aDate[1] > 12))
    {
      error(oField, sError);
      return false;
    }

//  Year
    if ((aDate[2] < 1000) || (aDate[2] > 9999))
    {
      error(oField, sError);
      return false;
    }
  }
  else
  {
    error(oField, sError);
    return false;
  }

  return true;
}


// Check if value of target field is a valid time (in Europian format: HH:MM, HH from 0 to 23 and MM from 0 to 59)
function isTime(oField, sName)
{   
  var s = new String(oField.value);
  var len = s.length;
  var sError = "Field '" + sName + "' should be in HH:MM format.";

  if (isEmpty(oField.value)) return true;

  var aTime = s.split(":");

  if (checkAllowed(s, digits + ":") && (aTime.length == 2))
  {
    if (s == "24:00")
    {
      oField.value = "23:59";
      s = oField.value;
    }

//  Hour
    h = aTime[0];
    if ((h < 0) || (h > 23) || (h.length > 2))
    {
      error(oField, sError);
      return false;
    }

//  Minute
    m = aTime[1];
    if ((m < 0) || (m > 59) || (m.length > 2))
    {
      error(oField, sError);
      return false;
    }
    else if ((m < 10) && (m.length == 1))
    {
      oField.value = h + ":0" + m;
    }
  }
  else
  {
    error(oField, sError);
    return false;
  }

  return true;
}


/* ##Internal Functions## */

// Check if target value contains simbols only from list sValid
//   return false if value contains any additional simbols
function checkAllowed(value, sValid)
{
  var temp;

  for (var i = 0; i < value.length; i++)
  {
    temp = value.substring(i, i + 1);
    if (sValid.indexOf(value.substring(i, i + 1)) == "-1")
    {
      return false;
    }
  }

  return true;
}


// Check if target value doesn't contains simbols from sInvalid list
//   return false if value contains simbol from sInvalid list
function checkNotAllowed(value, sInvalid)
{
  var temp;

  for (var i = 0; i < value.length; i++)
  {
    temp = value.substring(i, i + 1);
    if (sInvalid.indexOf(temp) > -1)
    {
      return false;
    }
  }

  return true;
}


// Check if target value length less then target maximum
//  if value length more then maximum - show error message and return false
function checkLength(maximum, oField, sName)
{
  if (isEmpty(oField.value)) return true;

  if (oField.value.length > maximum)
  {
    error(oField, "Field '" + sName + "' has " + oField.value.length + " symbols (maximum allowed length is " + maximum + ").");
    return false;
  }
  else
  {
    return true;
  }
}


// Check if target value length more then target minimum
//  if value length less then minimum - show error message and return false
function checkMinLength(minimum, oField, sName)
{
  if (isEmpty(oField.value)) return true;

  if (oField.value.length < minimum)
  {
    error(oField, "Field '" + sName + "' has " + oField.value.length + " symbols (minimum required length is " + minimum + ').\n');
    return false;
  }
  else
  {
    return true;
  }
}


// Show error message and return focus to target field
function error(oField, sError)
{
  aError.push(sError);
}


// Check whether string s is empty.
function isEmpty(s)
{
  return ((s == null) || (s.length == 0));
}


function checkMandatory(oField, sName)
{
  if (oField.value.length)
  {
    return true;
  }
  else
  {
    error(oField, "Mandatory field '" + sName + "' is empty.");
    return false;
  }
}

function checkInterval(oPass1, oPass2)
{
  if (isEmpty(oPass2.value) || isEmpty(oPass2.value))
  {
    return true;
  }

  if (parseFloat(oPass1.value) > parseFloat(oPass2.value))
  {
    error(oPass2, "Incorrect Interval");
    return false;
  }

  return true;
}

function checkSubmit(sForm, aMandatory, aValid, aExt)
{
  aError = Array();
  sError = "Form corrupted";
  sForm = 'document.' + sForm + '.';
  var oFocusField;
// Check Mandatory Fields
  for (var i in aMandatory)
  {
    try
    {
        oField = eval(sForm + i);
        if (!checkMandatory(oField, aMandatory[i]))
        {
            if (!oFocusField)
            {
                oFocusField = oField;
            }
        }
    }
    catch(er)
    {
        alert(sError);
        return false;
    }
  }
// Check Field Validation
  for (var i in aValid)
  {
    try
    {
      if (!eval(aValid[i][1] + '(' + sForm + i + ', "' + aValid[i][0] + '")'))
      {
        oFocusField = eval(sForm + i);
      }
    }
    catch(er)
    {
        alert(sError);
        return false;
    }
  }
// Check Result
  if (aError.length)
  {
    var s = 'There are following problem(s) in form:\n\n';
    for (i = 0; i < aError.length; i++)
    {
      s += aError[i] + '\n';
    }

    alert(s);
    try
    {
      if (oFocusField.type != 'hidden')
      {
//      For Mozilla
        window.field = oFocusField;
        setTimeout('window.field.focus();', 1);
      }
    }
    catch(er)
    {
      return false;
    }
    return false;
  }
  else
  {
    // Additional Checks
    for (i = 0; i < aExt.length; i++)
    {
      try
      {
        if (!eval(aExt[i]))
        {
          return false;
        }
      }
      catch(er)
      {
        alert(sError);
        return false;
      }
    }
    return true;
  }
}

function checkInterval(oField1, oField2, sName)
{
  if (isEmpty(oField1.value) || isEmpty(oField2.value))
  {
    return true;
  }

  if (parseFloat(oField1.value) > parseFloat(oField2.value))
  {
    error(oField1, "Fields '" + sName + "': incorrect range.");
    return false;
  }

  return true;
}

function isSame(src1,src2,str)
{
    if (src1.value!=src2.value)
    {
        alert(str);
        src1.focus();
        return false;
    }
    else
    {
        return true;
    }
}
