<!--
/*
  Amendment History:
  1) jty2 (12/6/05)
  	- added validateHkId(anItem)
  	- added generateCheckFromHKID(anId)
  2) mmarable (12/12/05)
  	- added validateCrbSrefNo(anItem)
  	- added generateCheckFromCrbSrefNo(aValue)
  3) Azeus.jco3 (04/12/06)
    - added UNKNOWN and II as valid in validateHkId
  4) Azeus.jco3 (04/17/06)
    - added validateCRO
    - modified HKID to not raise mandatory error anymore
    - modified HKID to not check CHECK DIGIT anymore
  5) Azeus.vmalubay  (04/25/2006)
    - added validateUniqueUser
  6) Azeus.gfabic (05/03/2006)
    - added validateFileInput
  6) Azeus.pvillangca (05/03/2006)
    - added validatePartialDate, validatePartialDateRange
*/

function validateTrim(anItem) {
  anItem.setValue(anItem.getAsString().trimWS());
  return true;
}

function validateCaps(anItem) {
  anItem.setValue(anItem.getAsString().toUpperCase());
  return true;
}

function validatePhoneNo(anItem) {
  var s = anItem.getAsString();
  var i;
  var s2 = '';
  for (i=0; i<s.length; i++) {
    if (s.charAt(i) >= '0' && s.charAt(i) <= '9') {
      s2 = s2 + s.charAt(i);
    } else {
      anItem.showError(LBJSErrorMsgs.MSG_INVALID_PHONE_NO, [anItem.Description]);
      return false;
    }
  }
  anItem.setValue(s2);
  return true;
}

function hasUserInput(anIS) {
  var di;
  with(anIS) {
    for (di in Items){
      if (!Items[di].isNull()) return true;
    }
    for (di in Items){
      Items[di].Control.focus();
      Items[di].showError(LBJSErrorMsgs['NO_CRITERIA_SPECIFIED']);
      return false;
    }
  }
}

//should attach to the 'from' item
function validateDateRange(anItem) {
  if (anItem.isNull()) return true;
  if (anItem.partner.isNull()) return true;

  var dtFormatter = new SimpleDateFormat("yyyy-MM-dd");
  var dFrom = dtFormatter.format(anItem.getAsDate());
  //to format the to field since it doesn't get formatted in lbjs.validate.
  anItem.setValue(dFrom);
  var dTo;
  
  if (anItem.partner.getAsDate())
    dTo = dtFormatter.format(anItem.partner.getAsDate());
  else
    return false;
  
  if (dFrom > dTo) {
    anItem.showError(LBJSErrorMsgs.MSG_DATE_AFTER_EQ, [anItem.partner.Description, anItem.Description]);
    return false;
  }
  return true;
}

//Validator for Date fields that have time component.
//should attach to the 'from' item
function validateTimestampRange(anItem) {
  if (anItem.isNull()) return true;
  if (anItem.partner.isNull()) return true;

  var dtFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  var dFrom = dtFormatter.format(anItem.getAsTimestamp());
  //to format the to field since it doesn't get formatted in lbjs.validate.
  anItem.setValue(dFrom);  
  var dTo;
  if (anItem.partner.getAsDate())
    dTo = dtFormatter.format(anItem.partner.getAsTimestamp());
  else
    return false;
  
  if (dFrom > dTo) {
    anItem.showError(LBJSErrorMsgs.MSG_DATE_AFTER_EQ, [anItem.partner.Description, anItem.Description]);
    return false;
  }
  return true;
}

function isValidRange(anItem) {
  if (!anItem.isNull()) {
    var lFrom = anItem.getAsDouble();
    var lTo = anItem.partner.getAsDouble();
	if (anItem.partner.isNull())return true;
    if (lTo < lFrom) {
      anItem.showError(LBJSErrorMsgs.MSG_FROM_GREATER_THAN_TO, [anItem.Description, anItem.partner.Description]);
      return false;
    }
    return true;
  }
  return true;
}

//should attach to the 'from' item
function validatePartnerRequired(anItem) {
  if (anItem.isNull() && !anItem.partner.isNull()) {
    anItem.showError('%1 is required if %0 is entered. ', [anItem.Description, anItem.partner.Description]);
    return false;
  }
  return true;
}

// should attach to the 'from' item
function validateRange(anItem) {
  if (anItem.isNull() || anItem.partner.isNull())
    return true;

  var lFrom = anItem.getAsDouble();
  var lTo = anItem.partner.getAsDouble();
  
  if (lTo < lFrom) {
    anItem.showError(LBJSErrorMsgs.MSG_FROM_NOT_GREATER_THAN_TO, [anItem.Description, anItem.partner.Description]);
    return false;
  }
  return true;
}

function validateAfterCurDate(anItem){
  if (anItem.isNull()) return true;

  var dtFormatter = new SimpleDateFormat("yyyy-MM-dd");
  var dtItem = dtFormatter.format(anItem.getAsDate());
  var dtCurDate = dtFormatter.format(new Date());

  if (dtItem <= dtCurDate) {
     anItem.showError(LBJSErrorMsgs.MSG_AFTER_CUR_DATE,[anItem.Description]);
     return false;
  }
  return true;
}

function validateEqLaterCurDate(anItem){
  if (anItem.isNull()) return true;

  var dtFormatter = new SimpleDateFormat("yyyy-MM-dd");
  var dtItem = dtFormatter.format(anItem.getAsDate());
  var dtCurDate = dtFormatter.format(new Date());

  if (dtItem < dtCurDate) {
     anItem.showError(LBJSErrorMsgs.MSG_EQ_LATER_CUR_DATE, [anItem.Description]);
     return false;
  }
  return true;
}

function validateEqBeforeCurDate(anItem){
  if (anItem.isNull()) return true;

  var dtFormatter = new SimpleDateFormat("yyyy-MM-dd");
  var dtItem = dtFormatter.format(anItem.getAsDate());
  var dtCurDate = dtFormatter.format(new Date());

  if (dtItem > dtCurDate) {
     anItem.showError(LBJSErrorMsgs.MSG_EQ_BEFORE_CUR_DATE, [anItem.Description]);
     return false;
  }
  return true;
}


function validatePositive(anItem) {
  if (anItem.isNull()) return true;
  var lValue = anItem.getAsLong();
  if (lValue <= 0) {
    anItem.showError('%0 must be greater than zero.', [anItem.Description]);
    return false; 
  }
  return true;
}

function validateAtLeastOneOfPair(anItem) {
  if (anItem.isNull() && anItem.partner.isNull()) {
    anItem.showError(LBJSErrorMsgs.MSG_CANT_BE_BOTH_NULL, [anItem.Description, anItem.partner.Description]);
    return false;
  }
  return true;
}

/* jty2: validateHKID
   validator for HKID field
   
   Azeus.jco3
   - Removed checking of HK Check Digit (as advised by Angus)
   - Added UNKNOWN and II as valid HKIDs
*/
function validateHkId(anItem) {
  if (anItem.isNull()) return true;
  var sHkId = anItem.getAsString();
  if(!isValidHkId(sHkId)) {
    anItem.showError(LBJSErrorMsgs.MSG_INVALID_HK_ID, [sHkId]);
    return false;
  }
  return true;
}

function isValidHkId(anHkId) {
  if (anHkId==null) return true;
  if (anHkId=="") return true;
  var regHkid = /^[A-Za-z]{1,2}\d{6}$/;
  if(anHkId != "UNKNOWN" && anHkId != "II" && !regHkid.test(anHkId)) {
    return false;
  }
  return true;
}

/* generateCheckFromHKID
generate the Check value for HKID

Parameters:
anId - value of HKID
*/
function generateCheckFromHKID(anId){
  var sId = anId;
  var arCheck = ["0","A","9","8","7","6","5","4","3","2","1"];
  var iSum = (anId.length == 7)? 324: 0;
  
  for(var i=0; i<sId.length; i++) {
    var iValue = parseInt(sId.charAt(sId.length-1-i), 36) * (i+2);
    iSum += iValue;
  }

  var iRem = iSum % 11;
  return arCheck[iRem];
}

/*mmarable: validateCrbSrefNo
validates CRB/SREF No. against the check digit if it is not empty

Prarameters:
anItem - LBJS item to be validated as a CRB/SREF No. field
*/
function validateCrbSrefNo(anItem){
  if (anItem.isNull()){
    return(true);
  }
  var reCrb = /^\d{5}[/]\d{2}[A-Za-z]{1}$/; //99999/YYC format for CRB
  var reSref = /^[A-Za-z]{1}\d{5}[/]\d{2}$/; //C99999/YY format for SREF
  var sCrbSrefNo = anItem.getAsString();
  var sValue = "";
  var sCheckDigit = "";
  
  if (reCrb.test(sCrbSrefNo)) {
    sValue = sCrbSrefNo.substr(0,sCrbSrefNo.length-1);
    sCheckDigit = sCrbSrefNo.charAt(sCrbSrefNo.length-1);
  } else if (reSref.test(sCrbSrefNo)) {
    sValue = sCrbSrefNo.substr(1);
    sCheckDigit = sCrbSrefNo.charAt(0);
  } else {
    anItem.showError(LBJSErrorMsgs.MSG_INVALID_VALUE, [anItem.Description,sCrbSrefNo]);
    return false;
  }
  //remove all '/' separators from the value  
  var sDataOnlyValue = sValue.replace(/[/]/gi,'');
  
  var sCorrectCheckDigit = generateCheckFromCrbSrefNo(sDataOnlyValue);
  if (sCheckDigit != sCorrectCheckDigit) {
    anItem.showError(LBJSErrorMsgs.MSG_INVALID_CRB_SREF_CHECK_DIGIT, [anItem.getAsString()]);
    return(false);
  }
  
  return(true);
}

/*mmarable: generateCheckFromCrbSrefNo
generate the CheckDigit value for CRB/SREF No.

Parameters:
aValue - value of CRB/SREF No.
*/
function generateCheckFromCrbSrefNo(aValue){
  if(!(aValue && aValue.charAt)) {
    return(null);
  }
  
  var arrWeights = ["8","7","6","5","4","3","2"];
  var arrCheck = ["A","B","C","D","E","F","G","H","J","K","L",
                  "M","N","P","Q","R","T","U","V","W","X","Y","Z"];
  var nCheckDigitTotal = 0;
  
  for(var i = 0; i<aValue.length; i++) {
    var nMultipliedPositionValue = parseInt(aValue.charAt(i)) * arrWeights[i%aValue.length];
    nCheckDigitTotal += nMultipliedPositionValue;
  }
  
  var nRem = nCheckDigitTotal % 23;
  return(arrCheck[nRem]);
}

/**
 * Validates that CRO is in any of the ff formats:
 *   99999/YYC
 *   C99999/YY
 * NOTE: Numbers must be 5 digits. YY indicate year so must be numerical
 */
function validateCRO(anItem) {
  if( anItem.isNull() ) return true;
  var sCro = anItem.getAsString();
  
  var reFormat1 = /^\d{5}\/\d{2}[A-Za-z]{1}$/; //99999/YYC
  var reFormat2 = /^[A-Za-z]{1}\d{5}\/\d{2}$/; //C99999/YY
  
  if( reFormat1.test(sCro) || reFormat2.test(sCro) )
    return true;
  anItem.showError(LBJSErrorMsgs.MSG_INVALID_FORMAT, [sCro,anItem.Description,"99999/YYC or C99999/YY"]);
  return false;
}

function validateEmail(anItem) {
 
  if(anItem.isNull()) {
    anItem.showError(LBJSErrorMsgs.MSG_MANDATORY, [anItem.Description]);
    return false;
  }
  
  var reEmail = /\w@\w/;
  var sEmail = anItem.getAsString();
  if( !reEmail.test(sEmail) ) {
    anItem.showError(LBJSErrorMsgs.MSG_INVALID_VALUE, [anItem.Description, sEmail]);
    return false;
  }
  return true;
}

function validateDob(anIS) {
  // See NmDobChildGrid
  var itemMonth = anIS.boi("BIRTH_MONTH");
  var itemYear = anIS.boi("BIRTH_YEAR");
  var itemDay = anIS.boi("BIRTH_DAY");
  
  var firstItem = anIS.getItemOrder()[0];
  
  // Check that at least one is supplied
  if( itemYear.isNull() && itemMonth.isNull() && itemDay.isNull() ) {
    firstItem.showError(LBJSErrorMsgs.MSG_CANT_BE_BOTH_NULL, ["YYYY, MM", "DD"]);
    return false;
  }
  
  // Assign default values
  var sYear = itemYear.isNull() ? 2000 : itemYear.getAsString(); // use 2000, so leap year
  var sMonth = itemMonth.isNull() ? 1 : itemMonth.getAsString();
  var sDay = itemDay.isNull() ? 1 : itemDay.getAsString();
  
  // Check if valid date
  var sConsolidated = sYear + "-" + sMonth + "-" + sDay;
  var dDob = Util.StringToDate(sConsolidated, "yyyy-MM-dd");
  
  if( !dDob ) {

    var sDisplay = (itemYear.isNull() ? "yyyy" : itemYear.getAsString()); // use 2000, so leap year
    sDisplay = sDisplay + "-" + (itemMonth.isNull() ? "MM" : itemMonth.getAsString());
    sDisplay = sDisplay + "-" + (itemDay.isNull() ? "dd" : itemDay.getAsString());
    
    firstItem.showError(LBJSErrorMsgs.MSG_NON_EXISTING_DATE, ["Date of Birth", sDisplay + " (yyyy-MM-dd)"]); 
    return false;
  }

  // if no year no need to check for range
  if( itemYear.isNull() ) {
    return true;
  }  

  // Check DOB between 1850 - sysdate
	dDob = new Date( sYear, sMonth-1, sDay );  

  var dEarliest = new Date("Jan 1, 1850");
  var dLatest = new Date();
  
  if( dDob < dEarliest ) {
    firstItem.showError(LBJSErrorMsgs.MSG_DATE_AFTER, ["Date of Birth", "1850-01-01"]);
    return false;
  }
  
  if( dDob > dLatest ) {
    firstItem.showError(LBJSErrorMsgs.MSG_EQ_BEFORE_CUR_DATE, ["Date of Birth"]);
    return false;
  }
  return true;
}

function validateUniqueUser(anItem) {
  if (anItem.isNull()) return true;
  if (anItem.partner.isNull()) return true;

  if (anItem.getAsString() == anItem.partner.getAsString()) {
    anItem.showError(LBJSErrorMsgs.MSG_NO_SAME_USER, [anItem.Description, anItem.partner.Description]);
    return false;
  }
  return true;
}

function validateFileInput(anItem) {
  if (anItem.isNull()) {
    return true;
  }
  var sInput = anItem.getAsString();
  var regFile = /^(\S:)/;
  var regFile2 = /^(\\+)/;
  if (!regFile.test(sInput) && !regFile2.test(sInput)) {
    anItem.showError(LBJSErrorMsgs.MSG_INVALID_VALUE, [anItem.Description, sInput]);
    return false;
  }
  return true;
}


/**
 * Check if Start Date and End Date are valid, and if Start Date <= End Date
 *  - note: attach to Start Year
 */
function validatePartialDateRange(anItem) {
  var bRetCode;
  var IS = anItem.Owner;

  with (IS) {
    var startYear = boi("START_YEAR");
    var startMonth = boi("START_MONTH");
    var startDay = boi("START_DAY");
    var startTime = boi("START_TIME");
    var endYear = boi("END_YEAR");
    var endMonth = boi("END_MONTH");
    var endDay = boi("END_DAY");
    var endTime = boi("END_TIME");
  }

  // Check if Start, End Date are valid
  bRetCode = validatePartialDate(startYear, startMonth, startDay);
  bRetCode = validatePartialDate(endYear, endMonth, endDay) && bRetCode;

  if (!bRetCode) {
    return false;
  }

  // Get Start, End Date values
  var sStartYear = startYear.isNull() ? 2000 : startYear.getAsString();
  var sStartMonth = startMonth.isNull() ? 1 : startMonth.getAsString();
  var sStartDay = startDay.isNull() ? 1 : startDay.getAsString();

  var sEndYear = endYear.isNull() ? 2000 : endYear.getAsString();
  var sEndMonth;
  var sEndDay;
  
  // Set default value of end month equal to first month of the year if both
  // are null, otherwise set default to last month of year
  if (endMonth.isNull()) {
    sEndMonth = startMonth.isNull() ? 1 : 12;
  } else {
    sEndMonth = endMonth.getAsString();
  }
  
  // Set default value of end day equal to first day of the month if both
  // are null, otherwise set default to last day of month
  if (endDay.isNull()) {
    if (startDay.isNull()) {
      sEndDay = 1;
    } else {
      sEndMonth++;
      sEndDay = 0;
    }
  } else {
    sEndDay = endDay.getAsString();
  }

  // Used to check against current date
  var sEndMonthTemp = endMonth.isNull() ? 1 : endMonth.getAsString();
  var sEndDayTemp = endDay.isNull() ? 1 : endDay.getAsString();

  // Get time components, and get Start and End Dates as Date objects
  var dStart;
  var dEnd;
  var dEndTemp;

  if (startTime && !startTime.isNull()) {
    var sStartTime = startTime.getAsString().split(":");
    var sStartHour = sStartTime[0];
    var sStartMin = sStartTime[1];
    var sStartSec = sStartTime[2];
    if (!(sStartHour && sStartMin && sStartSec
        && !isNaN(Util.StringToNumber(sStartHour) + Util.StringToNumber(sStartMin) + Util.StringToNumber(sStartSec)))) {
      // Invalid time format - will be reported by another validator
      return false;
    }
    dStart = new Date( sStartYear, sStartMonth - 1, sStartDay, sStartHour, sStartMin, sStartSec );
  } else {
    dStart = new Date( sStartYear, sStartMonth - 1, sStartDay );
  }

  if (endTime && !endTime.isNull()) {
    var sEndTime = endTime.getAsString().split(":");
    var sEndHour = sEndTime[0];
    var sEndMin = sEndTime[1];
    var sEndSec = sEndTime[2];
    if (!(sEndHour && sEndMin && sEndSec
        && !isNaN(Util.StringToNumber(sEndHour) + Util.StringToNumber(sEndMin) + Util.StringToNumber(sEndSec)))) {
      // Invalid time format - will be reported by another validator
      return false;
    }
    dEnd = new Date( sEndYear, sEndMonth - 1, sEndDay, sEndHour, sEndMin, sEndSec );
    dEndTemp = new Date( sEndYear, sEndMonthTemp - 1, sEndDayTemp, sEndHour, sEndMin, sEndSec );
  } else {
    dEnd = new Date( sEndYear, sEndMonth - 1, sEndDay, "23", "59", "59" );
    dEndTemp = new Date( sEndYear, sEndMonthTemp - 1, sEndDayTemp);
  }

  // Check if date is less than current date
  bRetCode = true;
  var dLatest = new Date();
  if( dStart > dLatest ) {
    startYear.showError(LBJSErrorMsgs.MSG_EQ_BEFORE_CUR_DATE, ["Start Date"]);
    bRetCode = false;
  }
  if( dEndTemp > dLatest ) {
    endYear.showError(LBJSErrorMsgs.MSG_EQ_BEFORE_CUR_DATE, ["End Date"]);
    bRetCode = false;
  }
  if (!bRetCode) {
    return false;
  }

  // If START_YEAR or END_YEAR is null, no need for further validation
  if (startYear.isNull() || endYear.isNull()) {
    return true;
  } else if( dStart > dEnd ) {
    endYear.showError(LBJSErrorMsgs.MSG_DATE_AFTER, ["End Date", "Start Date"]);
    return false;
  }

  return true;
}

/**
 * Check if partial Date is valid. Partial dates can be in the following formats:
 *   YYYY/MM/DD
 *   YYYY/MM
 *   YYYY
 */
function validatePartialDate(aYear, aMonth, aDay) {
  var sDesc;
  if (aYear.Description.search(/start/i) != -1) {
    sDesc = "Start Date";
  } else if (aYear.Description.search(/end/i) != -1) {
    sDesc = "End Date";
  } else {
    sDesc = aYear.Description;
  }

  // Year should not be empty if Month has a value
  // Month should not be empty if Day has a value
  var oEmptyItem;
  var oItem;
  if (!aYear.Mandatory && aYear.isNull() && !aMonth.isNull()) {
    oEmptyItem = aYear;
    oItem = aMonth;
  } else if (aMonth.isNull() && !aDay.isNull()) {
    oEmptyItem = aMonth;
    oItem = aDay;
  }
  if (oEmptyItem) {
    oEmptyItem.showError(LBJSErrorMsgs.MSG_PARTNER_REQUIRED, [oItem.Description, oEmptyItem.Description]); 
    return false;
  }

  var sYear = aYear.isNull() ? 2000 : aYear.getAsString();
  var sMonth = aMonth.isNull() ? 1 : aMonth.getAsString();
  var sDay = aDay.isNull() ? 1 : aDay.getAsString();

  // Invalid year/month/day format, will be reported by another validator
  if (isNaN(Util.StringToNumber(sYear)) ||
      isNaN(Util.StringToNumber(sMonth)) ||
      isNaN(Util.StringToNumber(sDay))) {
    return false;
  }

  if ( aYear && !aYear.isNull() && aYear.getAsLong() < 1901 ) {
    aYear.showError(LBJSErrorMsgs.MSG_DATE_AFTER, [sDesc, "1901-01-01"]);
    return false;
  }

  dDate = Util.StringToDate(sYear + "-" + sMonth + "-" + sDay, "yyyy-MM-dd");
  if (!dDate) {
    var sDisplay = (aYear.isNull() ? "YYYY" : aYear.getAsString())
        + "-" + (aMonth.isNull() ? "MM" : aMonth.getAsString())
        + "-" + (aDay.isNull() ? "DD" : aDay.getAsString());

    aYear.showError(LBJSErrorMsgs.MSG_NON_EXISTING_DATE, [sDesc, sDisplay]); 
    return false;
  }

  return true;
}

//-->