<!--
// =====================================================================
// Name  :    Validation.js
// Copyright: Innovations Pty Ltd
//
// Description
// -----------
// Contains validation routines used at the client's browser.
//
// Notes
// Functions assume form field of the correct type is passed.
// See http://javascriptkit.com/javatutors/redev2.shtml for reference
//
// Modification History
// --------------------
// 03.02.06 AS Add indexOf prototype
// 14.06.06 BB Add stripWhiteSpace prototype 
// 21.03.05 BB Fix to the regexp used in isEmail
// 10.07.04 BB Written
// =====================================================================
Array.prototype.indexOf = function(v) 
{
   // Return index of the first element that matches value otherwise will return -1.
   // Usage: offset = arrayName.indexOf(value to search for in first element) 
   for (var i=0, l=this.length; i<l; i++)
   {
      if (this[i][0]==v) 
      {
          return i;
      }
   }
   return -1;
}   

String.prototype.stripWhiteSpace = function()
{
   // Remove all whitespace from everywhere in the value ...
   return( this.replace(/\s+/g,'') );   
}

String.prototype.trim = function()
{
   // Remove leading and trailing whitespace and then remove duplicates in the middle ...
   return( this.replace(/^\s*([\s\S]*\S+)\s*$|^\s*$/,'$1') );   
}

function isChecked(o)
{
  // Confirm a check box group has at least one entry checked ...
  if (typeof o.length == 'undefined')
  {
    // One instance on the form ...
    return o.checked;
  }
  else
  {
    // Many instances on the form ...
    for (var i=0; i<o.length; i++)
    {
      if (o[i].checked) return true;
    }
  }
  return false;
}

function isEmail(o)
{
  // Email address must be at least of form a@b.cc for this validation to work. We do
  // not use the IP address based form of email addresses since they are uncommon [see
  // http://www.quirksmode.org/js/mailcheck.html for more information on this]. Old
  // script used regexp of  /^([\w\.!#\$%\-\+])+@([\w-]+\.)+[a-zA-Z]{2,7}$/
  //
  // New script based on http://www.irt.org/articles/js049/index.htm [but differs]
  //    User Name
  //    ---------
  //    Zero or more leading spaces
  //    One or more alphanumerics/_ or !#$%-+
  //    Zero or more [dot followed by one or more alphanumerics/_ or !#$%-+]
  //
  //    Separator
  //    ---------
  //    @ sign
  //
  //    Domain name
  //    -----------
  //    One or more alphanumeric 
  //    Zero or more [. or - , followed by one or more alphabetics]
  //    Dot
  //    Two to seven alphanumeric characters for top-level domain name
  //    Zero or more trailing spaces
  var regEmail = /^\s*([\w\!\#\$\%\-\+])+(\.([\w\!\#\$\%\-\+])+)*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]{2,7}\s*$/;
  return regEmail.test(o.value);
}

function isEmpty(o)
{
  return (trim(o) == '');
}

function isNegative(o) 
{
   if (o==null) return false;   // Reject parameters that are not objects
   var cCheck = o.value;  // Extract the value from the object
   cCheck = cCheck.trim().replace(/\,/gi,'').replace(/ /gi,'');
   
   if ((cCheck == '') || isNaN(cCheck) || (parseInt(cCheck) >= 0) ) 
   {  
      return false;
   }
   return true;
}

function isPhoneNumber(oPrefix, oNumber)
{
  var sPrefix='';
  var sNumber='';
  
  if (arguments.count==1)
  {
    oPrefix = null;
    oNumber = oPrefix;
  }
  if (oPrefix) sPrefix = oPrefix.value; // Allow the prefix to be 'null'
  if (oNumber) sNumber = oNumber.value; // Allow the number to be 'null'
 
  var s = (sPrefix+sNumber).stripWhiteSpace();
  
  // Either STD, mobile or local number (allowing for shorter Australian regional phone numbers)
  // OR [an addition for Homecare tests] the 'number' begins with an *
  return ( /^0[1-9]\d{4,9}$/.test(s) || /^[1-9]\d{5,10}$/.test(s) || /^\*/.test(s) );
}

function isPositive(o) 
{
   if (o==null) return false;   // Reject parameters that are not objects
   var cCheck = o.value;  // Extract the value from the object
   cCheck = cCheck.trim().replace(/\,/gi,'').replace(/ /gi,'');
   if ( (cCheck == '') || isNaN(cCheck) || (parseInt(cCheck) <= 0) ) 
   {  
      return false;
   }
   return true;
}

function isPostCode(o)
{
  // Australian postcodes are strings between 0000 and 9999 ...
  return /^\d{4}$/.test(trim(o));
}

function isPushed(o)
{
  // Confirm radio button group has an option pushed ...
  return isChecked(o);
}

function isSelected(o)
{
  // Confirm a drop down group has at least one entry selected ...
  //
  // There is no guaranteed way to tell if the user has made
  // a selection from a list without a predefined SELECT in it.
  // For the code in this routine we make the assumption that
  // the 0th element has no information in it and hence we can
  // fail if the indexSelected value is 0
  //
  // It is also worth noting that browsers:
  //    - set selectedIndex to zero (0) if nothing has been
  //      selected in the option set (whether through SELECTED
  //      option on the tag, or by user action); and
  //    - set 'selected' property to true or false as
  //      appropriate the field being examined, but always set
  //      zero (0) to true to match selectedIndex if nothing
  //      has been selected in the set; and
  //    - set defaultSelected to true or false as appropriate to
  //      the selection.
  //
  // However, if no value is associated with the selected
  // then we can use the following code:
  //        o[o.selectedIndex].value != ''
  //        o[i][o[i].selectedIndex].value != ''
  if (typeof o.selectedIndex == 'undefined')
  {
    // Many identically named drop downs on the form ...
    for (var i=0; i<o.length; i++)
    {
      if (o[i].selectedIndex > 0) return true;
    }
  }
  else
  {
    // One drop down on the form ...
    return (o.selectedIndex > 0);
  }
  return false;
}

function isZero(o) 
{
   if (o==null) return false;   // Reject parameters that are not objects
   var cCheck = o.value;  // Extract the value from the object
   cCheck = cCheck.trim().replace(/\,/gi,'').replace(/ /gi,'');
   if ( (cCheck == '') || isNaN(cCheck) || (parseInt(cCheck) != 0) ) 
   {  
      return false;
   }
   return true;
}

function trim(o)
{
  // Remove leading and trailing whitespace and then remove duplicates in the middle ...
  var s='';
  if (o) 
  {
     s =  o.value.replace(/^\s*([\s\S]*\S+)\s*$|^\s*$/,'$1').replace(/(\s)+/g,'$1') ;
  }
  return s;
}

// Support forms validations ...

// Use lFormSubmitted to control behaviour of user submission prior to allowing submission ...
lFormSubmitted = false; 

function setNotOKToProcess()
{
  lFormSubmitted = true;
}

function setNotOKToSubmit()
{
  // Deprecated function [supplied for existing code] ...
  setNotOKToProcess();
}

function isOKToProcess()
{
  if (lFormSubmitted)
  {
    alert('Request is being processed, please wait');
    return false;
  }
  return true;
}

function isOKToSubmit()
{
   // Deprecated function [supplied for existing code] ...
   return isOKToProcess();
}

// The checkQtyForm function is used on those shopping cart screens 
// that create individual forms for each line of qty that might be 
// updated. The code is intended to cover off all uses of the same
// style of form irrespective of the origin of the form.

function checkQtyForm(oForm)
{
  var oField;

  if (!isOKToSubmit())
  {
    return false;
  }    
 
  oField = oForm.qty;
  if (!isPositive(oField))
  { 
    alert('Quantity must be a number that is greater than zero!')
    oField.focus();
    oField.select();
    return false;
  }
  
  // A number of shopping carts use this routine and so we need 
  // to code for forms where quantities and dollar amounts must
  // be confirmed ...
  if (oForm.availableqty)
  {
    var requestedQty = parseInt(oForm.qty.value);   
    var availableQty = parseInt(oForm.availableqty.value);
    var startQty = 0;
    if (oForm.startqty)   // Specified in some update cart routines
    {
      startQty = parseInt(oForm.startqty.value);
    }
    
    availableQty = availableQty+startQty;  // User is specifying new quantity so give back existing qty as available ...
    if (requestedQty > availableQty)
    {
      alert('Requested quantity of '+ requestedQty +' exceeds available quantity of '+availableQty+'!')
      oField.focus();
      oField.select();
      return false;
    }
  
    if (oForm.availabledollars)
    {
      // Field exists so confirm that we can order the qty ...
      var cost=requestedQty*oForm.price.value;
      var available=oForm.availabledollars.value*1+startQty*oForm.price.value;  // Allow for existing stock returning funds to be used
      
      if (cost > available)
      {
        alert('Requested quantity of '+ requestedQty +' results in an amount of $'+cost+' which exceeds available dollars of $'+available+'!')
        oField.focus();
        oField.select();
        return false;
      }
    }
  }
  
  setNotOKToSubmit();
  return true;
}


function CheckDate(o)
{
  var valDateFormat=/^\d{2}\/\d{2}\/\d{4}$/ // Basic check for date format validity
  
  if (o.value == "")
  {
     return 1;
  }
  
  if (!valDateFormat.test(o.value))
  {
     return 2;
  }   
  
  // Detailed check for valid date ranges
  var cDay = o.value.split("/")[0]
  var cMonth = o.value.split("/")[1]
  var cYear = o.value.split("/")[2]
   
  var dayobj = new Date(cYear, cMonth-1, cDay) // Note: months in Date() and getmonth() are 0 to 11, hence the -1 :-)
   
  if ((dayobj.getMonth()+1!=cMonth) || (dayobj.getDate()!=cDay) || (dayobj.getFullYear()!=cYear))
  {   
    return 3;
  }
  return 0;	
}

// -->