/*
FileName: /include/Validate.js
Purpose : To perform validation checks on the specific fields of the form.

Validation Functions Available:
* isDate(year, month,day)
* isValidDate(dateStr, resultDate)
* isDD(day,month,year)
* isMM(month)
* isEmpty(data)
* isAlphaNumeric(data, specialStr)
* isInteger(data)
* isFloat(data)
* isEmail(email)
* isValidNRIC(strData)
* isValidFIN(strData)
* isValidLuhn10(data)
* isValidCreditCardNo(ccNo, type)
* haveDoubleQuote(data)
* isValidPostal(data)

All the above functions return boolean data type indicating 
the status of the validation (unless otherwise stated above).
The function of the functions are self-explanatory by their function names.
Please refer to the following functions for more details.

*/

// Checks for the following valid date formats:
// DD/MM/YY   DD/MM/YYYY   DD-MM-YY   DD-MM-YYYY
// Also separates date into month, day, and year variables

function isDate (year, month, day) {
   // month argument must be in the range 1 - 12
   month = month - 1;  // javascript month range : 0- 11
   var tempDate = new Date(year,month,day);
  
   if ( (tempDate.getFullYear() == year) &&
        (month == tempDate.getMonth()) &&
        (day == tempDate.getDate()) ){
       return true;
   }else{
    
      return false;
   }
}

function isNotFuture (year,month,day ){
  
  // month argument must be in the range 1 - 12
   month = month - 1;  // javascript month range : 0- 11
   var today = new Date;
   var tempDate = new Date(year,month,day);
   if ( tempDate < today ){
       return true;
   }else{
      return false;
   }
 
}

function isValidDate(dateStr, resultDate) {
  var datePat = /^(\d{1,2})(\/|-)(\d{1,2})\2(\d{2}|\d{4})$/;

  // To require a 4 digit year entry, use this line instead:
  // var datePat = /^(\d{1,2})(\/|-)(\d{1,2})\2(\d{4})$/;

  var matchArray = dateStr.match(datePat); // is the format ok?
  if (matchArray == null) {
    alert("Date is not in a valid format.")
    return false;
  }
  
  day = matchArray[1];
  month = matchArray[3]; // parse date into variables
  year = matchArray[4];
  
  if (day < 1 || day > 31) {
    alert("Day must be between 1 and 31.");
    return false;
  }

  if (month < 1 || month > 12) { // check month range
    alert("Month must be between 1 and 12.");
    return false;
  }
  
  if ((month==4 || month==6 || month==9 || month==11) && day==31) {
    alert("Month "+month+" doesn't have 31 days!")
    return false
  }
  if (month == 2) { // check for february 29th
    var isleap = (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));
    if (day>29 || (day==29 && !isleap)) {
      alert("February " + year + " doesn't have " + day + " days!");
      return false;
     }
  }

  // set MM/DD/YYYY format to resultDate
  resultDate.value = month + "/" + day + "/" + year
  return true;
}

function isMM(month)
{
  if (month < 1 || month > 12) { 
    alert("Month must be between 1 and 12.");
    return false;
   }
   return true;
}

function isDD(day, month, year)
{
  if (day < 1 || day > 31) {
    alert("Day must be between 1 and 31.");
    return false;
  }

  if ((month==4 || month==6 || month==9 || month==11) && day==31) {
    alert("Month "+month+" doesn't have 31 days!")
    return false;
  }
  
  if (month == 2) { // check for february 29th
    var isleap = (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));
    if (day>29 || (day==29 && !isleap)) {
      alert("February " + year + " doesn't have " + day + " days!");
      return false;
     }
  }
  return true;
}

function haveDoubleQuote(data)
{
  var i;
  
  for (i=0; i < data.length; i++) {
    if (data.charAt(i) == "\"") {
      return true;
    }
  }
  return false;
}

function isEmpty(data)
{
  var i;

  for (i=0; i < data.length; i++) {
    if (data.charAt(i) != ' ') {
      return false;
    }
  }
  return true;
}


function isUserId(s)
{
    var rx = /^[A-Z0-9]([A-Z0-9_. ]*[A-Z0-9])?$/i;
    return rx.test(s);
}

function isAlphaNumeric(data, specialStr)
{
  var numStr = "0123456789"
  var alphaStr = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
  var currChar
  var i

  if (isEmpty(data)) {
    return false;
  }

  for (i=0; i < data.length; i++) {
    currChar = data.charAt(i)
    if ((numStr.indexOf(currChar) == -1) &&
        (alphaStr.indexOf(currChar) == -1) && 
        (specialStr.indexOf(currChar) == -1)) {
      // current char is not valid digit or letter or an accepted special character
      return false;
    }
  }
  return true;
}

function isInteger(data)
{
  var numStr = "0123456789"
  var currChar
  var i

  if (isEmpty(data)) {
    return false;
  }

  for (i=0; i < data.length; i++) {
    currChar = data.charAt(i)
    if (numStr.indexOf(currChar) == -1) {
      // current char is not valid digit
      return false;
    }
  }
  return true;
}

function isValidPostal(data)
{
  var numStr = "0123456789"
  var currChar
  var i

  if (isEmpty(data)) {
    return false;
  }

  if (data.length != 6)
     return false;
 
  for (i=0; i < data.length; i++) {
    currChar = data.charAt(i)
    if (numStr.indexOf(currChar) == -1) {
      // current char is not valid digit
      return false;
    }
  }
  return true;
}



function isFloat(data)
{
  var numStr = "0123456789"
  var currChar
  var decpt = 0
  var i

  if (isEmpty(data)) {
    return false;
  }

  for (i=0; i < data.length; i++) {
    currChar = data.charAt(i)
    if (numStr.indexOf(currChar) == -1) {
      if ((currChar == '.' ) && (decpt == 0)) {
        decpt++
      } else {
        // more than 1 decimal point found or
        // non valid char
        return false;
      }
    }
  }
  return true;
}

function isEmail(email)
{
  var posOfAt = email.indexOf("@")
  var lastPosOfAt = email.lastIndexOf("@")
  var lastPosOfDot = email.lastIndexOf(".")
  var currChar

  if (isEmpty(email) || email.length < 5 || posOfAt != lastPosOfAt ||
      (posOfAt < 1) || (email.indexOf(" ") != -1) || 
      (lastPosOfDot <= posOfAt) || (lastPosOfDot == email.length - 1))  {
    return false;
  }
  return true;
}

// This code should only check on NRIC no. started with prefix "S" or "T".
function isValidNRIC(strData)
{
  var intLen = strData.length
  var intWeights = new Array(2, 7, 6, 5, 4, 3, 2)
  var strChkAlpha = new Array("A", "B", "C", "D", "E", "F", "G", "H", "I", "Z", "J")
	
  var strDigits
  var strValidAlpha
  var strCardType
  var strCardAlpha
  var i
  var strCurrDigit
  var j = 0

// Perform NRIC Format validation:
  // NRIC should be of 9 alphanumeric length data.
  if ((intLen < 8) || (intLen > 9)) {
    return false;
  }
  
  strCardAlpha = strData.charAt(intLen - 1).toUpperCase()
  
  
  strCardType = strData.charAt(0).toUpperCase()
  if ((strCardType != "S") && strCardType != "T") {
    return false;
  }
  
  strDigits = strData.substring(intLen - 8, intLen - 1)
  if (!isInteger(strDigits)) {
    return false;
  }


// Perform Checksum on NRIC no.:
  
	for (i=0; i < strDigits.length; i++) {
	  strCurrDigit = parseInt(strDigits.charAt(i))
	  j = j + (strCurrDigit * intWeights[i]) 
	}
	
	if (strCardType == "T") {
		j = j + 4
	}
	
	j = j % 11

	j = 11 - j
	
	if (strCardAlpha == strChkAlpha[j - 1]) {
	   return true;
	} else {
	   return false;
	}	
}

// This code should only check on FIN no. started with prefix "F" or "G".
function isValidFIN(strData)
{
  var intLen = strData.length
  var intWeights = new Array(2, 7, 6, 5, 4, 3, 2)
  var strChkAlpha = new Array("K", "L", "M", "N", "P", "Q", "R", "T", "U", "W", "X")
	
  var strDigits
  var strValidAlpha
  var strCardType
  var strCardAlpha
  var i
  var strCurrDigit
  var j = 0

// Perform NRIC Format validation:
  // NRIC should be of 9 alphanumeric length data.
  if ((intLen < 8) || (intLen > 9)) {
    return false;
  }
  
  strCardAlpha = strData.charAt(intLen - 1).toUpperCase()
  
  
  strCardType = strData.charAt(0).toUpperCase()
  if ((strCardType != "F") && strCardType != "G") {
    return false;
  }
  
  strDigits = strData.substring(intLen - 8, intLen - 1)
  if (!isInteger(strDigits)) {
    return false;
  }


// Perform Checksum on FIN no.:
  
	for (i=0; i < strDigits.length; i++) {
	  strCurrDigit = parseInt(strDigits.charAt(i))
	  j = j + (strCurrDigit * intWeights[i]) 
	}
	
	if (strCardType == "G") {
		j = j + 4
	}
	
	j = j % 11

	j = 11 - j
	
	if (strCardAlpha == strChkAlpha[j - 1]) {
	   return true;
	} else {
	   return false;
	}	
}

function isValidLuhn10(data)
{
  var i = data.length - 1
  var j
  var total = parseInt(data.charAt(i))
  var curr
  var dbl = true

  for (i = i - 1; i >= 0; i--) {
    curr = data.charAt(i)
    if (dbl) {
      curr = (2 * parseInt(curr)) + ""
      for (j=0; j<curr.length;j++) {
        total = total + parseInt(curr.charAt(j))
      }
    } else {
      total = total + parseInt(curr)
    }
    dbl = !dbl
  }
  return ((total % 10) == 0)
}

function isValidCreditCardNo(ccNo, type)
{
  var len = ccNo.length

  if (isEmpty(ccNo) || len < 13) {
    return false
  }
  if (type == "amex") {
    if (len != 15 || ccNo.charAt(0) != "3" || 
        (ccNo.charAt(0) != "4" && ccNo.charAt(1) != "7")) {
      return false
    }
  }
  if (type == "diners") {
    if (len != 14 || ccNo.charAt(0) != "3" || 
        (ccNo.charAt(1) != "6" && ccNo.charAt(1) != "8" && 
         (ccNo.substring(1,3) != "00") &&
         (ccNo.substring(1,3) != "01") &&
         (ccNo.substring(1,3) != "02") &&
         (ccNo.substring(1,3) != "03") &&
         (ccNo.substring(1,3) != "04") &&
         (ccNo.substring(1,3) != "05") )) {
      return false
    }
  }
  if (type == "mc") {
    if (len != 16 || ccNo.charAt(0) != "5" ||
        (ccNo.charAt(1) != "1")
        (ccNo.charAt(1) != "2")
        (ccNo.charAt(1) != "3")
        (ccNo.charAt(1) != "4")
        (ccNo.charAt(1) != "5") ) {
      return false
    }
  }
  if (type == "visa") {
    if ((len != 13 && len != 16) || ccNo.charAt(0) != "4") {
      return false
    }
  }
  if (isValidLuhn10(ccNo)) {
    return true
  } else {
    return false
  }
}



