/*
Excellent Date route from Dr JR Stockton http://www.merlyn.demon.co.uk/js-date4.htm
Modofied for ComWeb Date entry and authentication
it can handle any type of input, including month names/numbers and days with th/st/rd extensions
input formats can cater for
0  D5+ expects    Y+MMDD   <i>e.g.</i> 20030215          030215
1  ISO expects  Y+_M+_D+   <i>e.g.</i> 2003-2-15    2003 Feb 15
2  EU  expects  D+_M+_Y+   <i>e.g.</i> 15 Okt, 2003    15.02.03
3  NA  expects  M+_D+_Y+   <i>e.g.</i> Feb 15th, 2003   2/15/03
*/

// General Utilities :

function LS(x) {return String(x).replace(/\b(\d)\b/g, '0$1')}

function LZ(x) {return(x<0||x>9?"":"0")+x}

function LZZ(x) {return(x<0||x>99?x:"0"+LZ(x))}

if (String.prototype && !String.prototype.substr) {
  String.prototype.substr =
    new Function("J", "K", "return this.substring(J, J+K)") }
		
		function Sign(y) {return(y>0?'+':y<0?'-':' ')}

function Prfx(Q, L, c) { var S = Q+"" // ??
  // if (!c) var c = ' '
  if (c.length>0) while (S.length<L) { S = c+S } ;
  return S }

function StrU(X, M, N) { // X>=0.0
  var T, S=new String(Math.round(X*Number("1e"+N)))
  if (/\D/.test(S)) { return ''+X }
  with (new String(Prfx(S, M+N, '0')))
    return substring(0, T=(length-N)) + '.' + substring(T) }

function StrT(X, M, N) { return Prfx(StrU(X, 1, N), M+N+2, ' ') }

function StrS(X, M, N) { return Sign(X)+StrU(Math.abs(X), M, N) }

function StrW(X, M, N) { return Prfx(StrS(X, 1, N), M+N+2, ' ') }

if (!Number.toFixed) { // 20030313
  Number.prototype.toFixed = // JL
    new Function('n', '  if (!n) n=0\n  return StrS(this, 1, n)') }


function SigFigNo(X, N) {
  var p = Math.pow(10, N-Math.ceil(Math.log(Math.abs(X))/Math.LN10))
  return isFinite(p) ? Math.round(X*p)/p : X }


function SigFigExp(X, N) { // N<22
  if (X==0) return SigFigExp(1, N).replace(/\+1/, ' 0')
  var p = Math.floor(Math.log(Math.abs(X))/Math.LN10)
  if (!isFinite(p)) return X
  return (X>0?'+':"") + String(
    Math.round(X*Math.pow(10, N-p-1))).replace(/(\d)/, "$1.") +
    (p>=0?"e+":"e-") + LZ(Math.abs(p)) } // All OK?


function Div(a, b) { return Math.floor(a/b) }

function Mod(a, b) { return a-Math.floor(a/b)*b }

//--------------------------------------------------------------------------------------

// Date/Time Utilities :


// Date.prototype.getTimezoneOffset = new Function("with (this) return 0 ")


if (String.prototype && !String.prototype.substr) {
  String.prototype.substr =
    new Function("J", "K", "return this.substring(J, J+K)") }


function DoWstr(DoWk) { // JS & ISO
  return "SunMonTueWedThuFriSatSun".substr(3*DoWk, 3) }

var Mon3 =
  ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']


Date.prototype.ISOlocaltimeStr =
  new Function("  /* Date.ISOlocaltimeStr */ with (this)\n    return " +
    "LZ(getHours())+':'+LZ(getMinutes())+':'+LZ(getSeconds())")


Date.prototype.USlocaltimeStr =
  new Function("  /* Date.USlocaltimeStr */ var H\n" +
    "  with (this) return " +
    "LZ(  1+((H=getHours())+11)%12  )+':'+\n      LZ(getMinutes())+':'+ " +
    "LZ(getSeconds())+[' AM',' PM'][+(H>11)]")


Date.prototype.ISOlocaldateStr =
  new Function("  /* Date.ISOlocaldateStr */ with (this)\n    return " +
    "getFullYear()+'-'+LZ(getMonth()+1)+'-'+LZ(getDate())")


Date.prototype.ISOlocalDTstr =
  new Function("  /* Date.ISOlocalDTstr */  with (this)\n    return " +
    "ISOlocaldateStr()+' '+ISOlocaltimeStr()")


Date.prototype.UTCstr =
  new Function("  /* Date.UTCstr */ with (this)\n    return " +
    "getUTCFullYear() + '-' + LZ(getUTCMonth()+1) + '-' +\n" +
    "      LZ(getUTCDate()) + ' ' + LZ(getUTCHours()) + ':' +\n" +
    "      LZ(getUTCMinutes()) + ':' + LZ(getUTCSeconds()) ")


Date.prototype.UTCDstr =
  new Function("  /* Date.UTCDstr */ with (this)\n    return " +
    "DoWstr(getUTCDay())+', '+UTCstr()")


Date.prototype.YMDDstr =
  new Function("  /* Date.YMDDstr */ with (this)\n    return " +
    "ISOlocaldateStr() + ' ' + DoWstr(getDay())")


Date.prototype.TZstr = // SIGN SHOULD BE RIGHT
  new Function("  /* Date.TZstr */\n" +
    "  var X, Y, Z ;\n" +
    "  with (this) {\n" +
    "    X = getTimezoneOffset() ; Y = Math.abs(X) ;\n" +
    "    Z = Y % 60 ; Y = (Y-Z)/60 ;\n" +
    "    return (X>0?'-':'+') + LZ(Y) + ':' + LZ(Z) }")

//--------------------------------------------------------------------------------------
//Globals

var Lx=0, Months = new Array(
  ' JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC',
  ' JAN FEB MAR APR MAI JUN JUL AUG SEP OKT NOV DEZ'),
  Suf = new Array('(st|nd|rd|th)', '(te|ste)'),
  Ln = new Array('English', 'German') // optional paragraph, see *

//function DatVal(Q, F){ F is now globally set
function DatVal(Q){
	var Mon, x, Rex, B, Y, ND=0
  Q = Q.trim() // optional line

  if (F==0) { Rex = /(\d+)(\d{2})(\d{2})$/     // D5+ as Y+MMDD
    Q = Q.search(Rex)==-1 ? '' : Q.replace(Rex, '$1 $2 $3') // split
   } // optional paragraph

  Rex = new RegExp(Suf[Lx], 'i') // Remove suffix, see * below
  Q = Q.replace(Rex, ' ')  // optional paragraph

  Rex = /([^A-Z]+)([IVX]{1,4})(.*)/i // Seek Roman (month) : viii IX
  if (Rex.test(Q)) {
    Mon = Q.replace(Rex, '$2').toUpperCase() // 1-4 Chars of month
    x =
     ' I    II   III  IV   V    VI   VII  VIII IX   X    XI   XII '.
      indexOf(' '+Mon)
    Q = Q.replace(Rex, '$1 '+(1+x/5)+' $3') // make numeric
   } // optional paragraph

  Rex = /([^A-Z]*)([A-Z]{1,3})(.*)/i
  // Seek month letters : Au / Aug. Or {3}.
  if (Rex.test(Q)) {
    Mon = Q.replace(Rex, '$2').toUpperCase() // 1-3 Letters of month
    x = Months[Lx].indexOf(' '+Mon) // or next for English only, *
    // x = ' JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC'.
    //   indexOf(' '+Mon)
    Q = Q.replace(Rex, '$1 '+(1+x/4)+' $3').trim() // to numeric
    } // optional paragraph

  Rex = /^(\d+)\D+(\d+)\D+(\d+)$/ // three digit fields
  // if (F==1) Q = Q                       // ISO
  if (F==2) Q = Q.replace(Rex, '$3 $2 $1') // EU
  if (F==3) Q = Q.replace(Rex, '$3 $1 $2') // NA
  B = Rex.test(Q) // Split into $1 $2 $3
  if (B) with (RegExp) { Y = +$1
    if (Y<100) Y += (Y<iCenturyLine?2000:1900)      // optional century line
    with (ND = new Date(Y, $2-1, $3))
      B = ((getMonth()==$2-1) && (getDate()==$3))  } // YMD valid ?
  // For true years 00..99, enter as >2 digits, check $1.length;
  // then increase year by 100 & decrease month by 1200.
  return [B, ND] // [Valid, DateObject]
  // To ban leading zeros in M, D, and Y,
  // alter all \\d+ in last Rex to [1-9]\\d?  untested.
  /* end DatVal */
}

