//////////////////////////////////////////////////////////////////////////////////
//                                                                              //
// File Name   : val_form_date.js                                               //
//                                                                              //
// Description : Set of JavaScript functions for validating data                //
//                                                                              //
// Copyright   : 2004 - MKH Computer Services Ltd.                              //
//                                                                              //
//////////////////////////////////////////////////////////////////////////////////

var whitespace = " \t\n\r";

// Returns true if string "s" is empty.
function isEmpty(s)
{
  return ((s == null) || (s.length == 0));
}

// Returns true if string "s" contains only whitespace characters.
function isWhitespace(s)
{
  var i;

  if (isEmpty(s)) return true;

  for (i = 0; i < s.length; i++)
  {   
    var c = s.charAt(i);
    if (whitespace.indexOf(c) == -1) return false;
  }

  return true;
}

// Returns true if character "c" is empty.
function isDigit(c)
{
  return ((c >= "0") && (c <= "9"));
}

// Returns true if string "s" contains only numbers.
function isInteger(s)
{
  var i;
  if (isEmpty(s)) return true;

  for (i = 0; i < s.length; i++)
  {
    var c = s.charAt(i);
    if (!isDigit(c)) return false;
  }

  return true;
}

// Returns true if string "s" is in the range "min" and "max".
function isIntegerInRange(s, min, max)
{
  if (isEmpty(s)) return true;

  if (!isInteger(s)) return false;

  var num = parseInt(s, 10);

  return ((num >= min) && (num <= max));
}

// Returns true if string s is a valid 2 or 4 digit year number between 1900 and 2000
function isYear(s)
{
  if (isEmpty(s)) return false;
  if (!isInteger(s)) return false;
  return true;
}

// Returns true if string s is a valid month
function isMonth(s)
{
  if (isEmpty(s)) return false;
  return isIntegerInRange (s, 1, 12);
}

// Returns true if string s is a valid day
function isDay(s)
{
  if (isEmpty(s)) return false;
  return isIntegerInRange (s, 1, 31);
}

// Given integer argument year returns number of days in February of that year.
function daysInFebruary(year)
{
  return ( ((year % 4 == 0) && ( (!(year % 100 == 0)) || (year % 400 == 0) ) ) ? 29 : 28 );
}

// Returns true if string arguments year, month, and day form a valid date.
function isDate(day, month, year)
{
  var daysInMonth = new Array(31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)

  if (! (isYear(year) && isMonth(month) && isDay(day))) return false;

  var intYear = parseInt(year, 10);
  var intMonth = parseInt(month, 10);
  var intDay = parseInt(day, 10);

  if (intDay > daysInMonth[intMonth-1]) return false;
  if ((intMonth == 2) && (intDay > daysInFebruary(intYear))) return false;
  return true;
}

// Strips leading and trailing whitespace from a string
function trimWhitespace(s)
{
  var i, j;
  
  if (whitespace.indexOf(s.charAt(s.length-1)) != -1)
  {
    i = s.length - 1;
    while (i >= 0 && whitespace.indexOf(s.charAt(i)) != -1)
    {
      i--;
    }
    s = s.substring(0, i+1);
  }

  if (whitespace.indexOf(s.charAt(0)) != -1)
  {
    j = 0; i = s.length;
    while (j < i && whitespace.indexOf(s.charAt(j)) != -1)
    {
      j++;
    }
    s = s.substring(j, i);
  }

  return s;
}

// Checks that an email address is valid
function valEmail(field, mandatory, max_length, field_desc)
{
  var s = trimWhitespace(field.value);
  if (mandatory)
  {
    if ( isWhitespace(s) )
    {
      alert(field_desc + " not supplied.");
      field.select();
      field.focus();
      return false;
    }
  }
  
  if ( ! isWhitespace(s) )
  {
    if ( max_length != null )
    {
      if ( s.length > max_length )
      {
        alert(field_desc + " must be a maximum of " + max_length + " characters long.");
        field.select();
        field.focus();
        return false;
      }

      if ( ! /^[a-z0-9'+ ]+([_\.-][a-z0-9'+ ]+)*@[a-z0-9]+([\.-][a-z0-9]+)*\.[a-z]{2,}$/i.test(s) )
      {
        alert(field_desc + " is not a valid format for an email address.");
        field.select();
        field.focus();
        return false;
      }
    }
  }

  return true;
}

// Checks that a string is valid
function valString(field, mandatory, min_length, max_length, field_desc)
{
  var s = trimWhitespace(field.value);
  if (mandatory)
  {
    if ( isWhitespace(s) )
    {
      alert(field_desc + " not supplied.");
      field.select();
      field.focus();
      return false;
    }
  }
  
  if ( ! isWhitespace(s) )
  {
    if ( min_length != null )
    {
      if ( s.length < min_length )
      {
        alert(field_desc + " must be a minimum of " + min_length + " characters long.");
        field.select();
        field.focus();
        return false;
      }
    }
    if ( max_length != null )
    {
      if ( s.length > max_length )
      {
        alert(field_desc + " must be a maximum of " + max_length + " characters long.");
        field.select();
        field.focus();
        return false;
      }
    }
    if ( /["]/i.test(s) )
    {
        alert(field_desc + " cannot contain Double Quotes.");
        field.select();
        field.focus();
        return false;
    }
  }

  return true;
}

// Checks that a numeric field is valid
function valNumber(field, mandatory, min_length, max_length, field_desc)
{
  var s = trimWhitespace(field.value);
  if (mandatory)
  {
    if ( isWhitespace(s) )
    {
      alert(field_desc + " not supplied.");
      field.select();
      field.focus();
      return false;
    }
  }

  if ( ! isWhitespace(s) )
  {
    if ( ! isInteger(s) )
    {
      alert(field_desc + " must be numeric.");
      field.select();
      field.focus();
      return false;
    }
    if ( min_length != null )
    {
      if ( s.length < min_length )
      {
        alert(field_desc + " must be a minimum of " + min_length + " digits long.");
        field.select();
        field.focus();
        return false;
      }
    }
    if ( max_length != null )
    {
      if ( s.length > max_length )
      {
        alert(field_desc + " must be a maximum of " + max_length + " digits long.");
        field.select();
        field.focus();
        return false;
      }
    }
  }

  return true;
}

// Checks that a decimal field is valid
function valDecimal(field, mandatory, allow_zero, min_length, max_length, max_dp, field_desc)
{
  var s = trimWhitespace(field.value);
  if (mandatory)
  {
    if ( isWhitespace(s) )
    {
      alert(field_desc + " not supplied.");
      field.select();
      field.focus();
      return false;
    }
  }

  if ( ! isWhitespace(s) )
  {
    if ( ! (/(^-?\d{1,3}(,\d{3})*\.\d*$)|(^-?\d\d*\.\d*$)|(^-?\d{1,3}(,\d{3})*$)|(^-?\d\d*$)|(^-?\.\d\d*$)/.test(s)) )
    {
      alert(field_desc + " must be a decimal number.");
      field.select();
      field.focus();
      return false;
    }
    if ( allow_zero == false && field.value == 0 )
    {
      alert(field_desc + " must not be zero.");
      field.select();
      field.focus();
      return false;
    }
    var numarray = s.split(".", 2)
	if ( numarray[0] != null )
	{
      if ( min_length != null )
      {
        if ( numarray[0].length < min_length )
        {
          alert(field_desc + " must be a minimum of " + min_length + " digits before the decimal point.");
          field.select();
          field.focus();
          return false;
        }
      }
      if ( max_length != null )
      {
        if ( numarray[0].length > max_length )
        {
          alert(field_desc + " must be a maximum of " + max_length + " digits before the decimal point.");
          field.select();
          field.focus();
          return false;
        }
      }
    }
	if ( numarray[1] != null )
	{
      if ( max_dp != null )
      {
        if ( numarray[1].length > max_dp )
        {
          alert(field_desc + " must be a maximum of " + max_dp + " decimal places.");
          field.select();
          field.focus();
          return false;
        }
      }
    }
  }

  return true;
}


// Checks that a date field is valid
function valDate(field, mandatory, field_desc)
{
  var s = trimWhitespace(field.value);
  if (mandatory)
  {
    if ( isWhitespace(s) )
    {
      alert(field_desc + " not supplied.");
      field.select();
      field.focus();
      return false;
    }
  }

  if ( ! isWhitespace(s) )
  {
    if ( ! /^\d{1,2}\/\d{1,2}\/\d{4,4}$/i.test(s) )
    {
      alert("Invalid format " + field_desc + " (must be DD/MM/YYYY format and contain a real date)");
      field.select();
      field.focus();
      return false;
    }
    var datearray = s.split("/", 3)
    if ( datearray[0] != 0 || datearray[1] != 0)
    {
      if (! isDate(datearray[0], datearray[1], datearray[2]))
      {
        alert("Invalid format " + field_desc + " (must be DD/MM/YYYY format and contain a real date)");
        field.select();
        field.focus();
        return false;
      }
    }
    if ( datearray[2] < 1900 )
    {
      alert("The year portion of " + field_desc + "  must be greater than or equal to 1980");
      field.select();
      field.focus();
      return false;
    }
    if ( datearray[2] > 2030 )
    {
      alert("The year portion of " + field_desc + "  must be less than or equal to 2030");
      field.select();
      field.focus();
      return false;
    }
  }

  return true;
}

// Checks that a time field is valid format (hh:mm) 
function valTime(field, mandatory, field_desc)
{
  var s = trimWhitespace(field.value);
  if (mandatory)
  {
    if ( isWhitespace(s) )
    {
      alert(field_desc + " not supplied.");
      field.select();
      field.focus();
      return false;
    }
  }

  if ( ! isWhitespace(s) )
  {
    if ( ! /^\d{1,2}:\d{2,2}$/i.test(s) )
    {
      alert("Invalid format " + field_desc + " (must be hh:mm format and contain a real time)");
      field.select();
      field.focus();
      return false;
    }
    var timearray = s.split(":", 2)
    if (! isIntegerInRange (timearray[0], 0, 23) || ! isIntegerInRange (timearray[1], 0, 59) )
    {
      alert("Invalid format " + field_desc + " (must be hh:mm format and contain a real time)");
      field.select();
      field.focus();
      return false;
    }
  }

  return true;
}

// Checks that a picklist has a selected value
function valPicklist(field, field_desc)
{
  if( field.selectedIndex < 1 )
  {
      alert("You have not chosen a " + field_desc);
      field.focus();
      return false;
  }

  return true;
}

// Checks that a URL is valid
function valUrl(field, mandatory, max_length, field_desc)
{
  var s = trimWhitespace(field.value);
  if (mandatory)
  {
    if ( isWhitespace(s) )
    {
      alert(field_desc + " not supplied.");
      field.select();
      field.focus();
      return false;
    }
  }
  
  if ( ! isWhitespace(s) )
  {
    if ( max_length != null )
    {
      if ( s.length > max_length )
      {
        alert(field_desc + " must be a maximum of " + max_length + " characters long.");
        field.select();
        field.focus();
        return false;
      }

      if ( ! /^(http|https):\/\//i.test(s) )
      {
        alert(field_desc + " must start with 'http://' or 'https://'");
        field.select();
        field.focus();
        return false;
      }
    }
  }

  return true;
}

// Checks that a OS Grid Reference is valid
function valOSGridRef(field, mandatory, field_desc)
{
  var s = trimWhitespace(field.value);
  if (mandatory)
  {
    if ( isWhitespace(s) )
    {
      alert(field_desc + " not supplied.");
      field.select();
      field.focus();
      return false;
    }
  }
  
  if ( ! isWhitespace(s) )
  {
    if ( ! /^[STNHO][A-Z][ ]?[0-9]{3}[ ]?[0-9]{3}$/i.test(s) && ! /^[ABCDEFGHJKLMNOPQRSTUVWXYZ][ ]?[0-9]{3}[ ]?[0-9]{3}$/i.test(s)  )
    {
      alert(field_desc + " must be a valid 8 digit OS UK Grid Reference of the format XXYYYZZZ (or XX YYY ZZZ) or 7 digit OS NI Grid Reference of the format XYYYZZZ (or X YYY ZZZ) , where X is the one/two letter OS Grid Area, Y is the three number easting and Z is the three number northing");
      field.select();
      field.focus();
      return false;
    }
  }

  return true;
}
