/**
 * validation.js
 *
 * This file contains javascript functions used by mpower-suite
 * modules.
 * Functions in this file are concerned with validating user input
 *
 * $Header: /JavaScript/validation.js 26    15/12/05 17:01 Aa $
 * $Revision: 26 $
 *
 * $Log: /JavaScript/validation.js $
 * 
 * 26    15/12/05 17:01 Aa
 * 2022881
 * 
 * 25    3/11/05 17:21 Gc
 * 2026001
 * 
 * 24    1/11/05 14:36 Ds
 * 2025981
 *
 * 23    24/10/05 15:05 Aa
 * 2025772
 *
 * 22    27/09/05 10:37 Gc
 * 2025245RW
 *
 * 21    5/09/05 9:53 Ds
 * 2024071
 *
 * Copyright 1996-2003 Monitor Management Control Systems Ltd.
 *
 *  Amendment History
 *
 *  Who  When         Why
 *  GC   10-02-05     2017616 : Added formatNumber
 *  GC   07-03-05     2017616 : Added getFloat
 *  GC   28-03-05     2017616 : Fixed bug in formatNumber (-200 would be written as -,200 as the - counted as a character)
 *  GC   26-04-05     2020224 : Added check for isInteger when validating fields.
 *  GC   04-05-05     2020400 : Added isValidSearchFlag
 *  AA   11-05-05     Added/removed functionality for filtering
 *  AA   12-05-05     Adjusted functionality for filtering
 *  DS   05-09-05     2024071 : Various issues with the calendar screen
 *  GC   27-09-05     2025245RW : Allow encode_url to encode &
 *  AA   24-10-05     2025772 : Various issues with the calendar screen
 *  DS   01-11-05     2025981 : Allow Decimal Durations
 *  GC   03-11-05     2026001 : Corrections to formatNumber and formatDecimalPart for 999.9999
 *  AA   15-12-05     2022881 : checkNum now detects multiple decimal points in a string e.g 7.1.6
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

var unloading = true;
function f_setUnloading(newVal){
  unloading = newVal;
}

var requiredFields = new Array();
var fieldNames = new Array();
// CHECK REQUIRED FIELDS - ENSURE THAT A VALUE HAS BEEN ENTERED FOR
// EVERY FIELD LISTED IN THE "requiredFields" ARRAY
function checkRequiredFields(input) {
  var fieldCheck = true ;
  var fieldsNeeded = ""
  var mainMsg = "[JS-001]";

  for(var fieldNum=0; fieldNum < requiredFields.length; fieldNum++) {
    var requiredField = requiredFields[fieldNum] ;
    var value ;
    var currentField;
    var descField;

    if (requiredField.name) {
      // Field has been specified as an input element
      currentField = requiredField;
    } else {
      currentField = input.elements[requiredField];
    }

    if ( typeof currentField == "object" ){
      value = currentField.value ;

      if (currentField.type == "hidden"){
        descField = currentField.name.substring(0,2)+"desc_"+currentField.name.substring(2,currentField.name.length);
        currentField = input.elements[descField];
      }

      if ((value == "") || (value == " ")) {
        fieldsNeeded += (fieldsNeeded.length>0?", ":"") + fieldNames[fieldNum];
        fieldCheck = false;
        colourField("missing", currentField);
      }else{
        colourField("mandatory", currentField);
      }
    }
  }

  if (fieldCheck == true) {
    // ALL REQUIRED FIELDS HAVE BEEN ENTERED
    return true;
  }

  // SOME REQUIRED FIELDS ARE MISSING VALUES
  alertDialog(mainMsg, true, fieldsNeeded);
  return false;
}

// CHECK REQUIRED FIELDS - ENSURE THAT A VALUE HAS BEEN ENTERED FOR
// EVERY FIELD LISTED IN THE "requiredFields" ARRAY
function checkRequiredFieldsRow(input, row)
{
  var fieldCheck   = true;
  var fieldsNeeded = "";
  var mainMsg = "[JS-002$" + Number(row+1) + "]";
  var fldElement;
  var currentField;
  var currentFieldElement;
  var descField;

  for(var fieldNum=0; fieldNum < requiredFields.length; fieldNum++) {;
   //fldElement = document.all ? document.all[requiredFields[fieldNum]] : document.getElementById(requiredFields[fieldNum]);
    fldElement = input.elements[requiredFields[fieldNum]]
    if ( typeof fldElement != "undefined"){
      currentField = realObj(fldElement, row);

      if (currentField.type == "hidden"){
        descField = currentField.name.substring(0,2)+"desc_"+currentField.name.substring(2,currentField.name.length);
        currentFieldElement = input.elements[descField];

        if ( typeof currentFieldElement == "object" ) currentField = currentFieldElement[row];
      }

      if ((realObj(fldElement, row).value == "") ||
          (realObj(fldElement, row).value == " ")) {
        fieldsNeeded += (fieldsNeeded.length>0?", ":"") + fieldNames[fieldNum];
        fieldCheck = false;
        colourField("missing", realObj(fldElement, row));
      }else{
        colourField("mandatory", currentField);
      }
    }
  }
  // ALL REQUIRED FIELDS HAVE BEEN ENTERED
  if (fieldCheck == true)
  {
      return true;
  }
  // SOME REQUIRED FIELDS ARE MISSING VALUES
  else
  {
      alertDialog(mainMsg, true, fieldsNeeded);
      return false;
  }
}

function colourField(type, field){
  var newColour = "#FFFFFF";
  var newBorder = "#7B91A5";

  if (type == "missing"){
    newColour = "#FFE0FF";
    newBorder = "#FF0000";
  }

  if (typeof field != "undefined" && field.style && !field.readOnly){
    field.style.backgroundColor = newColour;
    field.style.borderColor = newBorder;
  }

}


// Function to reset the required fields arrays (required in master/detail operations)

function resetRequiredFields(){
  delete requiredFields;
  requiredFields = new Array();
  delete fieldNames;
  fieldNames = new Array();
}

// Function to add a new required fields to the arrays arrays

function addRequiredField(p_fld, p_name) {
  requiredFields[requiredFields.length] = p_fld;
  fieldNames[fieldNames.length] = p_name;
}

//###################################################################

// function oc(field, options) {
//   var removeChars = ((options & 1)==1);
//   var keyCol      = ((options & 2)==2);
//   var upper       = ((options & 4)==4);
//   var iframe      = ((options & 8)==8);

//   if (removeChars) {
//     remove_invalid_characters(field, keyCol);
//     field.style.color="red";
//   }
//   if (upper) field.value=uCase(field.value);

//   if (iframe) {
//     parent.f_setUnloading(true);
//   } else {
//     f_setUnloading(true);
//   }
//}

// function of(field, colName, colDesc, colDescTerm, options, changedCol, row) {
//   var search      = ((options & 16)==16);
//   var grid        = ((options & 32)==32);
//   var select      = ((options & 64)==64);
//   var calendar    = ((options & 128)==128);
//   var calSubmit   = ((options & 256)==256);
//   var standalone  = ((options & 512)==512);

//   p_extra.value="";
//   p_row.value=row;
//   p_column.value = "p_" + colName;
//   p_column_desc.value = colDesc;
//   p_changedcol.value = changedCol;

//   if (!standalone) {
//     if (calendar) {
//       top.frames[0].enableCalendar(field.form, field, calSubmit);
//     } else if (search) {
//       p_column.title = colDescTerm;
//       top.frames[0].enableSearch(p_column_desc, p_column);
//     } else {
//       top.frames[0].disableSearch();
//     }
//   }

//   if (select) {
//     if (grid) {
//       field.form.p_select[row]?field.form.p_select[row].checked=true:void(0);
//     } else {
//       if (typeof field.form.p_select != "undefined") field.form.p_select?field.form.p_select.checked=true:void(0);
//     }
//   }
//}

// function od(field, calendar) {
//   if (!calendar) {
//     if (p_column.value.indexOf("_desc") != -1) {
//       top.frames[0].f_set_search_desc(field.value);
//     } else {
//       top.frames[0].f_set_search_code(field.value);
//     }
//   }

//   top.frames[0].f_activate_search();
//}

function checkNum(data) {      // checks if all characters
  var valid = "0123456789,.-";     // are valid numbers or a "."
  var ok = 1; var checktemp;
  var decimalCount = 0;           //check there is only 1 decimal point
  for (var i=0; i<data.length; i++) {
    checktemp = "" + data.substring(i, i+1);
    if (checktemp == ".") decimalCount++;
    if (decimalCount > 1) return 0;
    if (valid.indexOf(checktemp) == "-1") return 0; }
      return 1;
}

function isNumber(data, lower, upper) {
  var space = / /g;
  var comma = /,/g;
  data.value = data.value.replace(space, "");
  data.value = data.value.replace(comma, "");
  
  if (checkNum(data.value) == 0 ) {
    alertDialog("[JS-003$"+data.value+"]");
    data.value = "";
    doChangeShare(data);
    return false;
  } else {
    var value = data.value * 1;

    if (typeof lower != "undefined" && value < lower) {
      alertDialog("[JS-005${GREATER}@" + lower + "]");
      data.value = formatNumber(lower, data.isInteger);
    } else if (typeof upper != "undefined" && value > upper) {
      alertDialog("[JS-005${LESS}@" + upper + "]");
      data.value = formatNumber(upper, data.isInteger);
    } else if (data.value.length > 0) {
      data.value = "" + formatNumber(value, data.isInteger);
    }
    doChangeShare(data);

    return true;
  }
}


function checkTime(data) {
  var timeStr = "";

  if (data.toUpperCase() == "NOW"){
    var date = new Date();
    timeStr = date.getHours()+":"+date.getMinutes();
  }else{
    if (data != ""){
      var minutes = 999;
      var time = data.split(':');
      if (time.length > 1){
        minutes = parseInt(time[1], 10);
      }

      try{
        var hours = parseInt(time[0], 10);

        if (minutes != 999){
          if (hours >= 0 && hours < 24 && minutes >= 0 && minutes < 60){
            timeStr = " " + (hours<10?"0":"") + hours + ":" + (minutes<10?"0":"") + minutes;
          }
        } else {
          if (hours >= 0 && hours < 24){
            timeStr = " " + (hours<10?"0":"") + hours + ":00";
          }
        }
      }catch (e) {
        timeStr = "";
      }

    }
  }
  return timeStr;
}

function isTime(data) {
  if(data.value != ""){
    var timeStr = checkTime(data.value);
    if (timeStr == "") {
      alertDialog("[JS-011$"+data.value+"]");
      data.value = "";
      doChangeShare(data);
      return false;
    }
    data.value = timeStr;
    doChangeShare(data);
    return true;
  }else{
    return true;
  }
}

function uCase(instr) { return instr.toUpperCase(); }


// --------------------------------------------------------------------
function checkDuration(p_data, p_reporting) {
  var types = "hdwmy"
  var checktemp;
  var regExpSP = / /g;
  var data = p_data.value.replace(regExpSP, "");
  var nDur = getFloat(data);

  if (data.length == 0) {return true};  // Ignore blanks

  if ( isNaN(nDur) ) {return false};

  var sDur = ""+nDur;
  // second part must start with h,d,w,m,y
  checktemp = data.charAt(sDur.length).toLowerCase();
  if (checktemp.length == 0) { checktemp = "d";}
  if (checktemp == ".") { checktemp = "d";}
  if (types.indexOf(checktemp) < 0) return false;

  // If p_reporting == 1 then allow month etc
  if ( p_reporting != 1 ) {
    if ( checktemp != "h" && checktemp !="d" && checktemp != "w") { return false; }

    if ( checktemp == "w" ){
      nDur *= 7;
      checktemp = "d";
    }
  }

  // Round nDur to 2 decimal places
  // If no decimal places in number, then no formatting
  if ( parseFloat(nDur,10) == parseInt(nDur,10) ){
    nDur = parseInt(nDur,10);
  } else {
    nDur = formatNumber( nDur, "false" );
  }

  if (checktemp == "h") { p_data.value = nDur + " hour"; }
  if (checktemp == "d") { p_data.value = nDur + " day"; }
  if (checktemp == "w") { p_data.value = nDur + " week";}
  if (checktemp == "m") { p_data.value = nDur + " month";}
  if (checktemp == "y") { p_data.value = nDur + " year";}
  if (nDur != 1) { p_data.value += "s";}

  doChangeShare(p_data);

  return true;
}
// --------------------------------------------------------------------
function isDuration(p_field, p_reporting) {
  if ( !checkDuration(p_field, p_reporting) ) {
    alertDialog((p_reporting==1?"[JS-007$"+p_field.value+"]":"[JS-006$"+p_field.value+"]"));
    p_field.value = "";
    doChangeShare(p_field);
    return false;
  }
  return true;
}
// --------------------------------------------------------------------

/**
 * Function to format a number field using an Oracle number format i.e. 9G999G999G999G999G990D99
 */                                                                     
function formatNumber(number, isInteger) {
  var format = getNumberFormat();

  if (isInteger == "true"){
    var aFormat = format.split('D');
    format = aFormat[0];
  }

  var multiplier = 1;

  if (typeof format == "undefined"){
    return number;
  }
  if (number - 0 < 0){
    multiplier = -1;
  }

  var decimalPart = formatDecimalPart(number * multiplier, format);
  var integerNumber = Math.floor(number * multiplier);
  var includeDecimal = (decimalPart.indexOf(".") >= 0)

  if (includeDecimal){
    if ((decimalPart-0) >= 1){
      integerNumber += (decimalPart-0);
      decimalPart = '.';
      for (var i = 0; i < format.substring(format.indexOf("D")+1, format.length).length; i++){
        decimalPart += '0';
      }
    }
  }else{
    integerNumber += (decimalPart-0);
  }

  return (multiplier<0?"-":"") + formatIntegerPart(integerNumber + '', format) + (includeDecimal?decimalPart:"");
}

/**
 * Function called by formatNumber
 */
function formatIntegerPart(number, format) {
  var includeComma = (format.indexOf("G") != -1)

  if (number.length <= 3 || !includeComma){
    return (number == '' ? '0' : number);
  }else{
    var firstComma = format.indexOf("G");
    var secondComma = format.indexOf("G", firstComma+1);

    if (firstComma == -1 || secondComma == -1){
      return (number == '' ? '0' : number);
    }

    var commaSpacing = secondComma - firstComma - 1;

    var mod = number.length%commaSpacing;
    var rval = (mod == 0 ? '' : (number.substring(0,mod)));
    for (i=0 ; i < Math.floor(number.length/commaSpacing) ; i++) {
      if ((mod ==0) && (i ==0)){
        rval+= number.substring(mod+commaSpacing*i,mod+commaSpacing*i+commaSpacing);
      }else{
        rval+= ',' + number.substring(mod+commaSpacing*i,mod+commaSpacing*i+commaSpacing);
      }
    }
    return rval;
  }
}

/**
 * Function called by formatNumber
 */
function formatDecimalPart(amount, format) {
  var decimalPart = amount - Math.floor(amount);

  if (format.indexOf("D") == -1){
    return ""+Math.round(decimalPart);
  }else{
    var maxPart = (format.substring(format.indexOf("D")+1, format.length)-0);
    var multiplier = maxPart + 1;
    var places = (""+maxPart).length;
    var rval = '0.00';   
    
    amount = Math.round( decimalPart * multiplier);

    if (amount > maxPart){
      rval = Math.round(amount / multiplier)+'.';
      for (var i = 0; i < places; i++){
        rval += '0';
      }
    }else{
      rval = '';
      for (var i = 0; i < places - (amount+"").length; i++){
        rval += '0';
      }
      rval = '.'+rval+amount;
    }
    return rval;
  }
}

function trim(value) {
  var rval = value;

  var obj = /^ +/;  // String that begin with one or more spaces
  if (obj.test(rval)) { rval = rval.replace(obj, ""); }
  obj = / +$/;      // String that end with one or more spaces
  if (obj.test(rval)) { rval = rval.replace(obj, ""); }

  return rval;
}


function encode_url(p_params, p_ampersand){
  var chars = new Array("%", "+");      // List of characters to be replaced
  var codes = new Array("%25", "%2B");  // List of URL-encoded characters to use insteadfs
  var newValue = p_params;
  var re;

  for (var i = 0; i < chars.length; i++){
    if (newValue.indexOf(chars[i]) != -1){
      re = new RegExp("\\" + chars[i], "g");
      newValue = newValue.replace(re, codes[i]);
    }
  }

  if (p_ampersand){
    re = new RegExp("\\&", "g");
    newValue = newValue.replace(re, "%26");
  }
  return newValue ;
}

/**
 * Return a float from a string value
 * @param string - the value from the field on the screen
 * @return float
 */
function getFloat(p_value){
  var rval = 0;
  var stringVal = trim(p_value);
  // remove any commas
  var re = new RegExp(",", "g");
  stringVal = stringVal.replace(re, "");
  try{
    rval = parseFloat(stringVal, 10);
  }catch (e){
    rval = 0;
  }
  return rval;
}

function isValidSearchFlag(p_obj){
  var sVal = p_obj.value.toUpperCase();
  if (sVal.substring(0,1) == "="){
    sVal = sVal.substring(1);
  }

  if (sVal.length == 0){
    p_obj.value = "";
    return true;
  }

  if (sVal == "Y" || sVal == "1" || sVal == "N" || sVal == "0"){
    p_obj.value = "="+sVal
  }else{
    alertDialog("[JS-017]");
    p_obj.value = "";
    return false;
  }
  return true;
}