/**************************************************************************************
 * Remove spaces from the left
 **************************************************************************************/
function lTrim ( strTest ){
	return strTest.replace( /^\s*/, "" )
}
/**************************************************************************************
 * Remove spaces from the right
 **************************************************************************************/
function rTrim ( strTest ){
	return strTest.replace( /\s*$/, "" );
}


/**************************************************************************************
 * Remove leading and trailing spaces
 **************************************************************************************/
function trim(strTest){
  var test = strTest;
  
  return lTrim(rTrim(strTest));
  
  
/*following replaced by code above - PCC 24/05/2002
  while (test.substr(0,1)==" "){
     test = test.substr(1);
  }

  while (test.substr(test.length-1,1)==" "){
     test = test.substring(0,test.length-1);
  }
  return test;      

*/
}


/**************************************************************************************
 * Test for string (strTest) containing given substring (testPattern).
 * Returns True or False
 **************************************************************************************/
function withinString(strTest,testPattern){
  if (testPattern){
    var patn = eval("/.*"+testPattern+".*/i");
    return patn.test(strTest);    
  }
}    

/**************************************************************************************
 * Test for string being zero length or equal to spaces or null
 **************************************************************************************/
function isEmpty(strTest){

  var test = strTest.replace(/ /g,"");   //Replace all spaces by null

  if (test.length==0){
      return true;
  }else{    
      return false;
  }
}

/**************************************************************************************
 *  Verify that a string is a valid date.
 *
 *  strDate  Required  String to verify.
 *  strFmt   Optional  Date format expected.
 *
 *  Returns true if strDate is a valid date, false otherwise.
 *
 **************************************************************************************/
function isDate(strDate, strFmt) {
  var Fmt = (isEmpty(strFmt)) ? "ymd" : strFmt;      // default date format
 
  function isLeapYear(y) {
    return (y%4!=0) ? false : (y%100!=0) ? true : (y%400!=0) ? false : true;
  }

  switch (Fmt.toLowerCase()) {
    case "yyyy/mm/dd" : 
      var reDate = /^(\d{4})\/(\d{1,2})\/(\d{1,2})$/;
      var y = 1, m = 2, d = 3;
      break;
    case "dd/mm/yyyy" : 
      var reDate = /^(\d{1,2})\/(\d{1,2})\/(\d{4})$/;
      var y = 3, m = 2, d = 1;
      break;
    case "dd/mm/yy" : 
      var reDate = /^(\d{1,2})\/(\d{1,2})\/(\d{2})$/;
      var y = 3, m = 2, d = 1;
      break;
    case "mm/dd/yyyy" : 
      var reDate = /^(\d{1,2})\/(\d{1,2})\/(\d{4})$/;
      var y = 3, m = 1, d = 2;
      break;
    case "mm/dd/yy" : 
      var reDate = /^(\d{1,2})\/(\d{1,2})\/(\d{2})$/;
      var y = 3, m = 1, d = 2;
      break;
    case "dd-mon-yyyy" : 
      var reDate = /^(\d{2})-(\D{3})-(\d{4})$/i;
      var y = 3, m = 2, d = 1;
      break;
    case "ddmmyyyy" : 
      var reDate = /^(\d{2})(\d{2})(\d{4})$/i;
      var y = 3, m = 2, d = 1;
      break;
    case "ddmmyy" : 
      var reDate = /^(\d{2})(\d{2})(\d{2})$/i;
      var y = 3, m = 2, d = 1;
      break;
    case "mmddyyyy" : 
      var reDate = /^(\d{2})(\d{2})(\d{4})$/i;
      var y = 3, m = 1, d = 2;
      break;
    case "mmddyy" : 
      var reDate = /^(\d{2})(\d{2})(\d{2})$/i;
      var y = 3, m = 1, d = 2;
      break;
    case "ddmonyyyy" : 
      var reDate = /^(\d{2})(\D{3})(\d{4})$/i;
      var y = 3, m = 2, d = 1;
      break;
    case "ddmonyy" : 
      var reDate = /^(\d{2})(\D{3})(\d{2})$/i;
      var y = 3, m = 2, d = 1;
      break;
   default:
      return false;                  // invalid date format specified
  }

  if (!reDate.test(strDate)){
   return false;  // date has invalid format
  }
  var dateParts = reDate.exec(strDate)
  var year  = dateParts[y];
  var month = dateParts[m];
  var day   = dateParts[d];
  if (day < 1) return false;

  switch (month.toUpperCase()) {
    case  '1':
    case  '01':
    case  '3':
    case  '03':
    case  '5':
    case  '05':
    case  '7':
    case  '07':
    case  '8':
    case  '08':
    case  '10':
    case  '12':
    case  'JAN':
    case  'MAR':
    case  'MAY':
    case  'JUL':
    case  'AUG':
    case  'OCT':
    case  'DEC':
     if (day > 31) return false;
      break;
    case  '4':
    case  '04':
    case  '6':
    case  '06':
    case  '9':
    case  '09':
    case  '11':
    case  'APR':
    case  'JUN':
    case  'SEP':
    case  'NOV':
      if (day > 30) return false;
      break;
    case  '2':
    case  '02':
    case  'FEB':
      if (day > (isLeapYear(year) ? 29 : 28)) return false;
      break;
    default:
      return false;
  }

  // Put any year range checks here
  // if (year < min || year > max) return false;

 return true;
}



/**************************************************************************************
 *  Verify that a string is a valid 24-hour time.
 *
 *  strTime  Required  String to verify.
 *
 *  Returns true if valid time, false otherwise.
 *
 **************************************************************************************/
function is24HrTime(strTime) {
  var reTime = /^(\d{1,2})\:(\d{2})$/;
 
  if (!reTime.test(strTime)){
    return false;  
  }
  var timeParts = reTime.exec(strTime)
  var hour  = timeParts[1];
  var mins = timeParts[2];

  if (hour>23) return false;
  if (mins>59) return false;

  return true;
}

/**************************************************************************************
 *  Convert a date string to Oracle format.
 *
 *  strDate  Required  String to convert.
 *
 *  Returns date in dd-mon-yyyy format.
 *
 **************************************************************************************/
function toOracle_Date(strDate) {
  var strReturn;
  var reDate;
  var y, m, d;
  var monthNumeric;
 
  if (isDate(strDate,'dd-mon-yyyy')){
    return strDate;
  }else{
    if (isDate(strDate,'ddmmyy')){
      reDate = /^(\d{2})(\d{2})(\d{2})$/i;
      y = 3; m = 2; d = 1;
      monthNumeric = true;
    }else{
      if (isDate(strDate,'dd/mm/yyyy')){
        reDate = /^(\d{1,2})\/(\d{1,2})\/(\d{4})$/;
        y = 3; m = 2; d = 1;
        monthNumeric = true;
      }else{
        if (isDate(strDate,'dd/mm/yy')){
          reDate = /^(\d{1,2})\/(\d{1,2})\/(\d{2})$/;
          y = 3; m = 2; d = 1;
          monthNumeric = true;
        }else{
          if (isDate(strDate,'ddmmyyyy')){
            reDate = /^(\d{2})(\d{2})(\d{4})$/i;
            y = 3; m = 2; d = 1;
            monthNumeric = true;
          }else{
            if (isDate(strDate,'yyyy/mm/dd')){
              reDate = /^(\d{4})\/(\d{1,2})\/(\d{1,2})$/;
              y = 1; m = 2; d = 3;
              monthNumeric = true;
		    }else{
              if (isDate(strDate,'mm/dd/yyyy')){
                reDate = /^(\d{1,2})\/(\d{1,2})\/(\d{4})$/;
                y = 3; m = 1; d = 2;
                monthNumeric = true;
		      }else{
                if (isDate(strDate,'mm/dd/yy')){
                  reDate = /^(\d{1,2})\/(\d{1,2})\/(\d{2})$/;
                  y = 3; m = 1; d = 2;
                  monthNumeric = true;
                }else{
                  if (isDate(strDate,'mmddyyyy')){
                    reDate = /^(\d{1,2})(\d{1,2})(\d{4})$/;
                    y = 3; m = 1; d = 2;
                    monthNumeric = true;
                  }else{
                    if (isDate(strDate,'mmddyy')){
                      reDate = /^(\d{1,2})(\d{1,2})(\d{2})$/;
                      y = 3; m = 1; d = 2;
                      monthNumeric = true;
                    }else{
                      if (isDate(strDate,'ddmonyyyy')){
                        reDate = /^(\d{2})(\D{3})(\d{4})$/i;
                        y = 3; m = 2; d = 1;
                        monthNumeric = false;
                      }else{
                        if (isDate(strDate,'ddmonyy')){
                          reDate = /^(\d{2})(\D{3})(\d{2})$/i;
                          y = 3; m = 2; d = 1;
                          monthNumeric = false;
                        }else{
                          return strDate;
                        }
                      }    
                    }
                  }
                }
              }  
            }
          }
        }
      }
    }
  }
   
  var dateParts = reDate.exec(strDate)
  var year  = dateParts[y].toString();
  var month = dateParts[m].toString();
  var day   = dateParts[d].toString();

  if (day.length == 1)
	{
	day = "0" + day;
	}
  if (year.length == 2){
    if (year>20){
      year = "19" + year;
    }else{
      year = "20" + year;
    }
  }

  if (monthNumeric) {
	return day+"-"+"JanFebMarAprMayJunJulAugSepOctNovDec".substr((month-1)*3,3)+"-"+year;
  }else{
    return day+"-"+(month.substr(0,1)).toUpperCase()+(month.substr(1,2)).toLowerCase()+"-"+year;
  }
  
}

/**************************************************************************************
 *  Convert a date string from dd-mon-yyyy (Oracle) format into required display format
 *
 *  strDate  Required  String to convert.
 *  strFmt   Optional  Date format required
 *
 **************************************************************************************/
function toDisplay_Date(strDate, strFmt) {
  var strReturn
  var reDate = /^(\d{2})-(\D{3})-(\d{4})$/i;
  var mths = "janfebmaraprmayjunjulaugsepoctnovdec";
  var dateParts = reDate.exec(strDate)
  var year  = dateParts[3].toString();
  var month = dateParts[2].toString();
  var day   = dateParts[1].toString();
  var sMonth
  
  for (var iMonth=0;iMonth<37;iMonth=iMonth+3){
    if (mths.substr(iMonth,3) == month.toLowerCase()) break;
  }
  
  iMonth = (iMonth/3) + 1;
  if (iMonth < 10) sMonth = "0" + iMonth.toString();
  else sMonth =  iMonth.toString();
  
  if (day.length < 2) day = "0" + day;

  switch (strFmt.toLowerCase()) {
    case "yyyy/mm/dd" : 
	  return year+"/"+sMonth+"/"+day;
      break;
    case "dd/mm/yyyy" : 
	  return day+"/"+sMonth+"/"+year;
      break;
    case "mm/dd/yyyy" : 
	  return sMonth+"/"+day+"/"+year;
      break;
    case "ddmmyyyy" : 
	  return day+sMonth+year;
      break;
    case "ddmmyy" : 
	  return day+sMonth+year.substr(2.2);
      break;
    case "dd mmm yyyy" : 
	  return day+" "+month+" "+year;
      break;
  default:
      return ""; // invalid date format specified, return empty string
  }
}

/**************************************************************************************
 * left pad with character 'strPad' to 'intNum' characters altogether
 **************************************************************************************/
function left_pad(strTest,intNum,strPad){
  if (strTest.length >= intNum){ return strTest;}

  var strOut="";
  for (var i=0;i<(intNum-strTest.length);i++){
     strOut += strPad.toString();
  }
  strOut += strTest;
  return strOut; 
}

/**************************************************************************************
 *
 * A JavaScript implementation of the RSA Data Security, Inc. MD4 Message
 * Digest Algorithm, as defined in RFC 1320.
 * Copyright (C) Jerrad Pierce 2000. Distributed under the LGPL.
 *
 **************************************************************************************/
/* Take a string and return the hex representation of its MD4. */
function encrypt(str) 
{
  var x = str2blks_MD5(str);
  var a =  1732584193;
  var b = -271733879;
  var c = -1732584194;
  var d =  271733878;

  for(var i = 0; i < x.length; i += 16) 
  {
    var olda = a;
    var oldb = b;
    var oldc = c;
    var oldd = d;

    a = ffMD4(a, b, c, d, x[i+ 0], 3 );
    d = ffMD4(d, a, b, c, x[i+ 1], 7 );
    c = ffMD4(c, d, a, b, x[i+ 2], 11);
    b = ffMD4(b, c, d, a, x[i+ 3], 19);
    a = ffMD4(a, b, c, d, x[i+ 4], 3 );
    d = ffMD4(d, a, b, c, x[i+ 5], 7 );
    c = ffMD4(c, d, a, b, x[i+ 6], 11);
    b = ffMD4(b, c, d, a, x[i+ 7], 19);
    a = ffMD4(a, b, c, d, x[i+ 8], 3 );
    d = ffMD4(d, a, b, c, x[i+ 9], 7 );
    c = ffMD4(c, d, a, b, x[i+10], 11);
    b = ffMD4(b, c, d, a, x[i+11], 19);
    a = ffMD4(a, b, c, d, x[i+12], 3 );
    d = ffMD4(d, a, b, c, x[i+13], 7 );
    c = ffMD4(c, d, a, b, x[i+14], 11);
    b = ffMD4(b, c, d, a, x[i+15], 19);

    a = ggMD4(a, b, c, d, x[i+ 0], 3 );
    d = ggMD4(d, a, b, c, x[i+ 4], 5 );
    c = ggMD4(c, d, a, b, x[i+ 8], 9 );
    b = ggMD4(b, c, d, a, x[i+12], 13);
    a = ggMD4(a, b, c, d, x[i+ 1], 3 );
    d = ggMD4(d, a, b, c, x[i+ 5], 5 );
    c = ggMD4(c, d, a, b, x[i+ 9], 9 );
    b = ggMD4(b, c, d, a, x[i+13], 13);
    a = ggMD4(a, b, c, d, x[i+ 2], 3 );
    d = ggMD4(d, a, b, c, x[i+ 6], 5 );
    c = ggMD4(c, d, a, b, x[i+10], 9 );
    b = ggMD4(b, c, d, a, x[i+14], 13);
    a = ggMD4(a, b, c, d, x[i+ 3], 3 );
    d = ggMD4(d, a, b, c, x[i+ 7], 5 );
    c = ggMD4(c, d, a, b, x[i+11], 9 );
    b = ggMD4(b, c, d, a, x[i+15], 13);

    a = hhMD4(a, b, c, d, x[i+ 0], 3 );
    d = hhMD4(d, a, b, c, x[i+ 8], 9 );
    c = hhMD4(c, d, a, b, x[i+ 4], 11);
    b = hhMD4(b, c, d, a, x[i+12], 15);
    a = hhMD4(a, b, c, d, x[i+ 2], 3 );
    d = hhMD4(d, a, b, c, x[i+10], 9 );
    c = hhMD4(c, d, a, b, x[i+ 6], 11);
    b = hhMD4(b, c, d, a, x[i+14], 15);
    a = hhMD4(a, b, c, d, x[i+ 1], 3 );
    d = hhMD4(d, a, b, c, x[i+ 9], 9 );
    c = hhMD4(c, d, a, b, x[i+ 5], 11);
    b = hhMD4(b, c, d, a, x[i+13], 15);
    a = hhMD4(a, b, c, d, x[i+ 3], 3 );
    d = hhMD4(d, a, b, c, x[i+11], 9 );
    c = hhMD4(c, d, a, b, x[i+ 7], 11);
    b = hhMD4(b, c, d, a, x[i+15], 15);

    a = add(a, olda);
    b = add(b, oldb);
    c = add(c, oldc);
    d = add(d, oldd);

  }
  return rhex(a) + rhex(b) + rhex(c) + rhex(d);
}

/*
 * Convert a 32-bit number to a hex string with ls-byte first
 */
var hex_chr = "0123456789abcdef";
function rhex(num)
{
  var str = "";
  for(var j = 0; j <= 3; j++)
    str += hex_chr.charAt((num >> (j * 8 + 4)) & 0x0F) +
           hex_chr.charAt((num >> (j * 8)) & 0x0F);
  return str;
}

/*
 * Convert a string to a sequence of 16-word blocks, stored as an array.
 * Append padding bits and the length, as described in the MD5 standard.
 * MD5 here is not a typo - this function is borrowed from the MD5 code.
 */
function str2blks_MD5(str)
{
  var nblk = ((str.length + 8) >> 6) + 1;
  var blks = new Array(nblk * 16);
  for(var i = 0; i < nblk * 16; i++) blks[i] = 0;
  for(i = 0; i < str.length; i++)
    blks[i >> 2] |= str.charCodeAt(i) << ((i % 4) * 8);
  blks[i >> 2] |= 0x80 << ((i % 4) * 8);
  blks[nblk * 16 - 2] = str.length * 8;
  return blks;
}

/*
 * Add integers, wrapping at 2^32. This uses 16-bit operations internally 
 * to work around bugs in some JS interpreters.
 */
function add(x, y)
{
  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
  return (msw << 16) | (lsw & 0xFFFF);
}

/*
 * Bitwise rotate a 32-bit number to the left
 */
function rol(num, cnt)
{
  return (num << cnt) | (num >>> (32 - cnt));
}

/*
 * These functions implement the basic operation for each round of the
 * algorithm.
 */
function cmn(q, a, b, x, s, t) 
{
  return add(rol(add(add(a, q), add(x, t)), s), b);
}
function ffMD4(a, b, c, d, x, s) 
{
  return cmn((b & c) | ((~b) & d), a, 0, x, s, 0);
}
function ggMD4(a, b, c, d, x, s) 
{
  return cmn((b & c) | (b & d) | (c & d), a, 0, x, s, 1518500249);
}
function hhMD4(a, b, c, d, x, s) 
{
  return cmn(b ^ c ^ d, a, 0, x, s, 1859775393);
}


function RoundToPence(N)
{
	var S = new String();
	var T = new Number();

	S = new String(Math.round(N*100));
	S = S.substr(0, T=(S.length-2)) + '.' + S.substr(T, 2);
	
	if ((N < 0) && (N > -1)) S = "-0" + S.substr(1);
	if ((N < 1) && (N >= 0)) S = "0" + S;
	
	return S;
}

/**************************************************************************************
 * Tests string against valid postocde formats:
 * A9 9AA, AA9 9AA, A9A 9AA, A99 9AA, AA9A 9AA, AA99 9AA
 * (2nd half of code may be optional)
 *
 * Returns True or False
 **************************************************************************************/
function isPostcode(strPcode,partialAllowed)
{
  var bPartial;
  if (arguments.length == 1){
    bPartial = false;
  }else{
    if (partialAllowed){
       bPartial = true;
    }else{
       bPartial = false;
    }
  }
  
  var strPcodemask1 = "/^[a-zA-Z]\\d";
  var strPcodemask2 = "/^[a-zA-Z][a-zA-Z]\\d";
  var strPcodemask3 = "/^[a-zA-Z]\\d[a-zA-Z]";
  var strPcodemask4 = "/^[a-zA-Z]\\d\\d";
  var strPcodemask5 = "/^[a-zA-Z][a-zA-Z]\\d[a-zA-Z]";
  var strPcodemask6 = "/^[a-zA-Z][a-zA-Z]\\d\\d";

  if (bPartial){
    strPcodemask1 += "(\\s+\\d[a-zA-Z][a-zA-Z])?$/";
    strPcodemask2 += "(\\s+\\d[a-zA-Z][a-zA-Z])?$/";
    strPcodemask3 += "(\\s+\\d[a-zA-Z][a-zA-Z])?$/";
    strPcodemask4 += "(\\s+\\d[a-zA-Z][a-zA-Z])?$/";
    strPcodemask5 += "(\\s+\\d[a-zA-Z][a-zA-Z])?$/";
    strPcodemask6 += "(\\s+\\d[a-zA-Z][a-zA-Z])?$/";
  }else{
    strPcodemask1 += "\\s+\\d[a-zA-Z][a-zA-Z]$/";
    strPcodemask2 += "\\s+\\d[a-zA-Z][a-zA-Z]$/";
    strPcodemask3 += "\\s+\\d[a-zA-Z][a-zA-Z]$/";
    strPcodemask4 += "\\s+\\d[a-zA-Z][a-zA-Z]$/";
    strPcodemask5 += "\\s+\\d[a-zA-Z][a-zA-Z]$/";
    strPcodemask6 += "\\s+\\d[a-zA-Z][a-zA-Z]$/";
  }
  
  var regPcodemask1 = eval(strPcodemask1);
  var regPcodemask2 = eval(strPcodemask2);
  var regPcodemask3 = eval(strPcodemask3);
  var regPcodemask4 = eval(strPcodemask4);
  var regPcodemask5 = eval(strPcodemask5);
  var regPcodemask6 = eval(strPcodemask6);

  if (regPcodemask1.test(strPcode)||
      regPcodemask2.test(strPcode)||
      regPcodemask3.test(strPcode)||
      regPcodemask4.test(strPcode)||
      regPcodemask5.test(strPcode)||
      regPcodemask6.test(strPcode)){
    return true;
  }else{  
    return false;
  }
}  

/**************************************************************************************
 * Set focus to earliest navigable item in form
 * p_form should be the form name
 * Some systems may originally have used set_focus with no parameters and
 * ensured they included a form called frm1 so second part of function
 * allows for backwards compatibility
 **************************************************************************************/

function set_focus(p_form)
{
if (arguments.length == 1)
	{
	if (typeof(p_form) == "object")
		{
		for (var i=0;i<=p_form.length;i++)
			{
			if (p_form(i).disabled == false && p_form(i).type != "hidden")
				{
				p_form(i).focus();
				return true;
				}
			}
		}
	}
else
	{
	if (document.frm1)
		{
		for (var i=0;i<=document.frm1.length;i++)
			{
			if (document.frm1(i).disabled == false && document.frm1(i).type != "hidden")
				{
				document.frm1(i).focus();
				return true;
				}
			}
		}
	}
}


/**************************************************************************************
 * Set all objects in a form to enabled
 * p_form should be the form name
 * Some systems may originally have used set_enabled with no parameters and
 * ensured they included a form called frm1 so second part of function
 * allows for backwards compatibility
 **************************************************************************************/

function set_enabled(p_form)
{
if (arguments.length == 1)
	{
	if (typeof(p_form) == "object")
		{
		for (var i=0;i<p_form.length;i++)
			{
			if (p_form(i).disabled == true && p_form(i).type != "hidden" && typeof(p_form(i)) == "object")
				{
				p_form(i).disabled = false;
				}
			}
		return true;
		}
	}
else
	{
	if (document.frm1)
		{
		for (var i=0;i<=document.frm1.length;i++)
			{
			if (document.frm1(i).disabled == true && document.frm1(i).type != "hidden")
				{
				document.frm1(i).disabled = false;
				}
			}
		return true;
		}
	}
}
