﻿var __FormErrorCount=0;

/**************************************************************
*
* Function Name: __Replace
*
* Description:   Replaces all occurences of searchString with 
*                replaceString in value and returns value.
*
**************************************************************/
function __Replace(value,searchString,replaceString)
{
  if(searchString!=replaceString&&value!="")
  {
    while(value.indexOf(searchString)>-1)
    {
      value=value.replace(searchString,replaceString);
    }
  }
  return(value);
}

/**************************************************************
*
* Function Name: __Compare
*
* Description:   Compare's one control's value against another.
*                If both are the same then true is returned 
*                otherwise false is returned.
*
**************************************************************/
function __Compare(ctlId1, ctlId2)
{
  var isValid=false;
  var ctl1=document.getElementById(ctlId1);
  if(ctl1!=null)
  {
    var ctl2=document.getElementById(ctlId2);
    if(ctl1!=null)
    {
      if(ctl1.value==ctl2.value)
      {
        isValid=true;
      }
    }
  }
  return(isValid);
}

/**************************************************************
*
* Function Name: __IsEmpty
*
* Description:   Returns true or false to indicate whether a 
*                control's value is empty (i.e. no value).
*
**************************************************************/
function __IsEmpty(ctlId)
{
  return(__GetValue(ctlId)=="");
}

/**************************************************************
*
* Function Name: __GetValue
*
* Description:   Returns a boolean value to indicate whether a
*                checkbox control is checked or not.
*
**************************************************************/
function __GetValue(ctlId)
{
  var ctl=document.getElementById(ctlId);
  if(ctl!=null)
  {
    return(ctl.value.replace(/^\s+|\s+$/g, ''));
  }
  else
  {
    return("");
  }
}

/**************************************************************
*
* Function Name: __GetCheckValue
*
* Description:   Returns the value in the specified control.
*
**************************************************************/
function __GetCheckValue(ctlId)
{
  var ctl=document.getElementById(ctlId);
  if(ctl!=null)
  {
    return(ctl.checked);
  }
  else
  {
    return(false);
  }
}

/**************************************************************
*
* Function Name: __GetBooleanValue
*
* Description:   Returns a boolean value to indicate whether a
*                control's text value contains true, false, yes 
*                or no.
*
**************************************************************/
function __GetBooleanValue(ctlId)
{
  var ctl=document.getElementById(ctlId);
  if(ctl!=null)
  {
    var val=ctl.value.replace(/^\s+|\s+$/g, '').toLowerCase();
    var boolVal=false;
    if(val=="true"||val=="yes")
    {
      boolVal=true;
    }
    return(boolVal);
  }
  else
  {
    return(false);
  }
}

/**************************************************************
*
* Function Name: __GetNumericValue
*
* Description:   Returns the numeric value held within a control.
*                If the value is non numeric then 0 is returned.
*
**************************************************************/
function __GetNumericValue(ctlId)
{
  var ctl=document.getElementById(ctlId);
  if(ctl!=null)
  {
    var val=ctl.value.replace(/^\s+|\s+$/g, '').toLowerCase();
    if(isNaN(val))
    {
      return(0);
    }
    else
    {
      return(val*1);
    }
  }
  else
  {
    return(0);
  }
}

/**************************************************************
*
* Function Name: __SetValue
*
* Description:   Sets a control's value.
*
**************************************************************/
function __SetValue(ctlId, value)
{
  var ctl=document.getElementById(ctlId);
  if(ctl!=null)
  {
    ctl.value=value;
  }
}

/**************************************************************
*
* Function Name: __ValidateNotEmpty
*
* Description:   Validates that a control's value is not empty.
*
**************************************************************/
function __ValidateNotEmpty(ctlId)
{
  var isEmpty=true;
  var ctl=document.getElementById(ctlId);
  if(ctl)
  {
    isEmpty=__IsEmpty(ctlId);
  __SetLabel(ctl,isEmpty);
  }
  __FormErrorCount=__FormErrorCount+(isEmpty==true?1:0);
  return(!isEmpty);
}

/**************************************************************
*
* Function Name: __ValidateEmailAddress
*
* Description:   Validates that a control's value is an e-mail 
*                address. If not then __FormErroCount is 
*                incremented and an appropriate error message
*                is displayed.
*
**************************************************************/
function __ValidateEmailAddress(ctlId)
{
  var isValid=false;
  var ctl=document.getElementById(ctlId);
  if(ctl)
  {
    var emailPattern = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/; 
    isValid=emailPattern.test(ctl.value.replace(/^\s+|\s+$/g, ''));
    __SetLabel(ctl,!isValid,"The e-mail address that you have entered is invalid");
  }  
  __FormErrorCount=__FormErrorCount+(isValid==true?0:1);
  return(isValid);
}

/**************************************************************
*
* Function Name: __ValidateURL
*
* Description:   Validates that a control's value is a url
*                If not then __FormErroCount is incremented
*                and an appropriate error message is displayed.
*
**************************************************************/
function __ValidateURL(ctlId)
{
  var isValid=false;
  var ctl=document.getElementById(ctlId);
  if(ctl)
  {
    isValid=true;
    var urlPattern = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/
    isValid=urlPattern.test(ctl.value.toLowerCase().replace(/^\s+|\s+$/g, ''));
    __SetLabel(ctl,!isValid,"The URL that you have entered is invalid");
    
  }  
  __FormErrorCount=__FormErrorCount+(isValid==true?0:1);
  return(isValid);
}

/**************************************************************
*
* Function Name: __ValidateCompare
*
* Description:   Compare's one control's value against another.
*                If both are the same then true is returned 
*                otherwise false is returned and __FormErrorCount
*                is incremented.
*
**************************************************************/
function __ValidateCompare(ctlId1, ctlId2)
{
  isValid=__Compare(ctlId1,ctlId2);
  __FormErrorCount=__FormErrorCount+(isValid==true?0:1);
  return(isValid);
}

/**************************************************************
*
* Function Name: __ValidateIsNumeric
*
* Description:   Validates a control's value to see if it is
*                numeric. If not then __FormErrorCount is 
*                incremented.
*
**************************************************************/
function __ValidateIsNumeric(ctlId)
{
  var isValid=false;
  var ctl=document.getElementById(ctlId);
  if(ctl)
  {
    isValid=!isNaN(ctl.value.replace(/^\s+|\s+$/g, ''));
    __SetLabel(ctl,!isValid);
  }  
  __FormErrorCount=__FormErrorCount+(isValid==true?0:1);
  return(isValid);
}

/**************************************************************
*
* Function Name: __ValidateRange
*
* Description:   Ensures that a control's numeric value is
*                within a minimum and maximum range. If the
*                value is empty or outwith the range then an
*                appropriate error message is displayed and
*                __FormErrorCount is incremented.
*
**************************************************************/
function __ValidateRange(ctlId,min,max)
{
  var isValid=false;
  var ctl=document.getElementById(ctlId);
  if(ctl)
  {
    var message="Please enter a numeric value";
    var value=ctl.value.replace(/^\s+|\s+$/g, '');
    if(!isNaN(value))
    {
      value=value*1;
      isValid=true;
      if(min!=null&&value<min)
      {
        isValid=false;
        message="Amount must be greater than "+min;
      }      
      else
      {
        if(max!=null&&value>max)
        {
          isValid=false;
          message="Amount must be less than "+max;
        }
      }
    }
    __SetLabel(ctl,!isValid,message);
  }  
  __FormErrorCount=__FormErrorCount+(isValid==true?0:1);
  return(isValid);
}

/**************************************************************
*
* Function Name: __ValidateMinLen
*
* Description:   Ensures that a control's value has a minimum
*                number of characters. If not then an
*                appropriate error message is displayed and
*                __FormErrorCount is incremented.
*
**************************************************************/
function __ValidateMinLen(ctlId,minLen)
{
  var isValid=false;
  var ctl=document.getElementById(ctlId);
  if(ctl)
  {
    isValid=ctl.value.replace(/^\s+|\s+$/g, '').length>=minLen;
    __SetLabel(ctl,!isValid,"Please enter a minimum of "+minLen+" characters");
  }  
  __FormErrorCount=__FormErrorCount+(isValid==true?0:1);
  return(isValid);
}

/**************************************************************
*
* Function Name: __ValidateMaxLen
*
* Description:   Ensures that a control's value has a maximum
*                number of characters. If not then an
*                appropriate error message is displayed and
*                __FormErrorCount is incremented.
*
**************************************************************/
function __ValidateMaxLen(ctlId,maxLen)
{
  var isValid=false;
  var ctl=document.getElementById(ctlId);
  if(ctl)
  {
    isValid=ctl.value.replace(/^\s+|\s+$/g, '').length<=maxLen;
    __SetLabel(ctl,!isValid,"Please enter no more than "+maxLen+" characters");
  }  
  __FormErrorCount=__FormErrorCount+(isValid==true?0:1);
  return(isValid);
}

/**************************************************************
*
* Function Name: __ValidateDate
*
* Description:   Ensures that a control's value is a valid date
*                in the format dd/mm/yyyy. If not then 
*                __FormErrorCount is incremented and an 
*                appropriate error message is displayed.
*
**************************************************************/
function __ValidateDate(ctlId)
{
  var isValid=false;
  var ctl=document.getElementById(ctlId);
  if(ctl)
  {
    var isValid=ctl.value.length==10&&ctl.value.substr(2,1)=="/"&&ctl.value.substr(5,1)=="/";
    if(isValid){
      isValid=__isValidDate(ctl.value,"DMY");      
    }
    __SetLabel(ctl,!isValid,"Please enter a valid date in the format dd/mm/yyyy");
  }  
  __FormErrorCount=__FormErrorCount+(isValid==true?0:1);
  return(isValid);
}

/**************************************************************
*
* Function Name: __isValidDate
*
* Description:   Validates a date string against a specified format.
*
**************************************************************/
function __isValidDate(dateStr, format) {
   if (format == null) { format = "MDY"; }
   format = format.toUpperCase();
   if (format.length != 3) { format = "MDY"; }
   if ( (format.indexOf("M") == -1) || (format.indexOf("D") == -1) || (format.indexOf("Y") == -1) ) { format = "MDY"; }
   if (format.substring(0, 1) == "Y") { // If the year is first
      var reg1 = /^\d{2}(\-|\/|\.)\d{1,2}\1\d{1,2}$/
      var reg2 = /^\d{4}(\-|\/|\.)\d{1,2}\1\d{1,2}$/
   } else if (format.substring(1, 2) == "Y") { // If the year is second
      var reg1 = /^\d{1,2}(\-|\/|\.)\d{2}\1\d{1,2}$/
      var reg2 = /^\d{1,2}(\-|\/|\.)\d{4}\1\d{1,2}$/
   } else { // The year must be third
      var reg1 = /^\d{1,2}(\-|\/|\.)\d{1,2}\1\d{2}$/
      var reg2 = /^\d{1,2}(\-|\/|\.)\d{1,2}\1\d{4}$/
   }
   // If it doesn't conform to the right format (with either a 2 digit year or 4 digit year), fail
   if ( (reg1.test(dateStr) == false) && (reg2.test(dateStr) == false) ) { return false; }
   var parts = dateStr.split(RegExp.$1); // Split into 3 parts based on what the divider was
   // Check to see if the 3 parts end up making a valid date
   if (format.substring(0, 1) == "M") { var mm = parts[0]; } else 
      if (format.substring(1, 2) == "M") { var mm = parts[1]; } else { var mm = parts[2]; }
   if (format.substring(0, 1) == "D") { var dd = parts[0]; } else 
      if (format.substring(1, 2) == "D") { var dd = parts[1]; } else { var dd = parts[2]; }
   if (format.substring(0, 1) == "Y") { var yy = parts[0]; } else 
      if (format.substring(1, 2) == "Y") { var yy = parts[1]; } else { var yy = parts[2]; }
   if (parseFloat(yy) <= 50) { yy = (parseFloat(yy) + 2000).toString(); }
   if (parseFloat(yy) <= 99) { yy = (parseFloat(yy) + 1900).toString(); }
   var dt = new Date(parseFloat(yy), parseFloat(mm)-1, parseFloat(dd), 0, 0, 0, 0);
   if (parseFloat(dd) != dt.getDate()) { return false; }
   if (parseFloat(mm)-1 != dt.getMonth()) { return false; }
   return true;
}

/**************************************************************
*
* Function Name: __SetLabel
*
* Description:   Adds or removes an error message label to or 
*                from the form below the specified control.
*
**************************************************************/
function __SetLabel(ctl,isError,message)
{
  var parent=ctl.parentNode;
  if(parent)
  {
    var label=null;
    var labels=parent.getElementsByTagName("label");
    if(labels.length>0)
    {
      label=labels[0];
    }
    if(label!=null)
    {
      label.className=(isError==true?"NormalRed":"");
    }   
  }
  __SetErrorMessage(ctl,isError,message);
}

/**************************************************************
*
* Function Name: __SetErrorMessage
*
* Description:   Used in conjunction with __SetLabel.
*
**************************************************************/
function __SetErrorMessage(ctl,isError,message)
{
  var parent=ctl.parentNode;
  if(parent)
  {
    var spans=parent.getElementsByTagName("span");
    for(var i=spans.length-1;i>=0;i--)
    {
      if(spans[i].className=="NormalRed")
      {
        parent.removeChild(spans[i]);
      }      
    }
    if(message!=null&&isError)
    {
      errorSpan=document.createElement("span");
      errorSpan.innerHTML=message;
      errorSpan.className="NormalRed";
      parent.appendChild(errorSpan);
    } 
  }
}

/**************************************************************
*
* Function Name: __AcceptNumericOnly
*
* Description:   Used with a control's onkeypress event to ensure
*                that only numeric characters are accepted.
*
**************************************************************/
function __AcceptNumericOnly(e)
{
  var result=true;
  var unicode=e.charCode?e.charCode:e.keyCode;
  if(unicode!=8&&unicode!=9)
  {
    if(unicode<48||unicode>57)
    {
      result=false;
    }
  }
  return(result);
}

/**************************************************************
*
* Function Name: __AcceptDecimalOnly
*
* Description:   Used with a control's onkeypress event to ensure
*                that only decimal values are accepted.
*
**************************************************************/
function __AcceptDecimalOnly(e,obj)
{
  var result=true;
  var unicode=e.charCode?e.charCode:e.keyCode;
  if(unicode!=8&&unicode!=9&&unicode!=46)
  {
    if(unicode<48||unicode>57)
    {
      result=false;
    }
  }
  else
  {
    if(obj!=null&&unicode==46)
    {
      if(obj.value.indexOf(".")>-1)
      {
        result=false;
      }
    }
  }
  return(result);
}

/**************************************************************
*
* Function Name: __AcceptNumericAndSpace
*
* Description:   Used with a control's onkeypress event to ensure
*                that only numbers and spaces are accepted.
*
**************************************************************/
function __AcceptNumericAndSpace(e)
{
  var result=true;
  var unicode=e.charCode?e.charCode:e.keyCode;
  if(unicode!=8&&unicode!=9&&unicode!=32)
  {
    if(unicode<48||unicode>57)
    {
      result=false;
    }
  }
  return(result);
}

/**************************************************************
*
* Function Name: __AcceptNonSpace
*
* Description:   Used with a control's onkeypress event to ensure
*                that only non space characters are accepted.
*
**************************************************************/
function __AcceptNonSpace(e)
{
  var result=true;
  var code=e.charCode? e.charCode : e.keyCode;
  if(code==" "){
    result=false;
  }
  return(result);
}

/**************************************************************
*
* Function Name: __FormatCurrency
*
* Description:   Formats a numeric value to 2 decimal places.
*
**************************************************************/
function __FormatCurrency(ctlId)
{
  var obj=document.getElementById(ctlId);
  if(obj)
  {
    obj.value=(Math.round(__GetNumericValue(ctlId)*100)/100).toFixed(2);
  } 
}