var False = false, True = true;
var emailRegex = /^([a-zA-Z0-9_.-])+@(([a-zA-Z0-9_-])+\.)+([a-zA-Z0-9]{1,4})$/;

function get( str ){ return( document.getElementById( str ) ); }

function fixYear( year )
{
  return( year < 1000 ? year + 1900 : year );
}

function fixMonth( month )
{
  return( month < 0 ? month + 12 : ( month > 11 ? month - 12 : month ) );
}

function CreateCalendar( year, month, name, dayClick, monthClick )
{
  var monthNames = new Array( "January", "February", "March", "April", "May", "June", "July",
                             "August", "September", "October", "November", "December" );

  while( month < 0 )
  {
    month += 12;
    year -= 1;
  }
  while( month > 11 )
  {
    month -= 12;
    year += 1;
  }

  var now = new Date();
  now = new Date( now.getFullYear(), now.getMonth(), now.getDate() );
  var table = document.createElement( "TABLE" ), row = null, cell = null;
  table.className = "CalendarTable";
  table.style.width = "100%";
  table.style.height = "100%";
  table.cellSpacing = 0;

  row = table.insertRow( table.rows.length );
  row.style.height = "1%";

  cell = row.insertCell( 0 );
  cell.style.cursor = "pointer";
  cell.align = "center";
  cell.innerHTML = "<<";
  if( monthClick )
    cell.onclick = function()
    {
      var newYear = year;
      var newMonth = month - 1;
      while( newMonth < 0 )
      {
        newMonth += 12;
        newYear -= 1;
      }
      CreateCalendar( newYear, newMonth, name, dayClick, monthClick ); monthClick( newYear, newMonth );
    };
  else
    cell.onclick = function(){ CreateCalendar( year, month - 1, name, dayClick, monthClick ); };
  cell.className = "CalendarTopRow";

  cell = row.insertCell( 1 );
  cell.colSpan = 5;
  cell.align = "center";
  cell.innerHTML = "<b>" + monthNames[month] + " " + year + "</b>";
  cell.className = "CalendarTopRow";

  cell = row.insertCell( 2 );
  cell.style.cursor = "pointer";
  cell.align = "center";
  cell.innerHTML = ">>";
  if( monthClick )
    cell.onclick = function()
    {
      var newYear = year;
      var newMonth = month + 1;
      while( newMonth > 11 )
      {
        newMonth -= 12;
        newYear += 1;
      }
      CreateCalendar( newYear, newMonth, name, dayClick, monthClick ); monthClick( newYear, newMonth );
    };
  else
    cell.onclick = function(){ CreateCalendar( year, month + 1, name, dayClick, monthClick ); };
  cell.className = "CalendarTopRow";

  row = table.insertRow( table.rows.length );
  cell = row.insertCell( 0 );
  cell.innerHTML = "Su";
  cell.className = "CalendarDayNames";
  cell = row.insertCell( 1 );
  cell.innerHTML = "Mo";
  cell.className = "CalendarDayNames";
  cell = row.insertCell( 2 );
  cell.innerHTML = "Tu";
  cell.className = "CalendarDayNames";
  cell = row.insertCell( 3 );
  cell.innerHTML = "We";
  cell.className = "CalendarDayNames";
  cell = row.insertCell( 4 );
  cell.innerHTML = "Th";
  cell.className = "CalendarDayNames";
  cell = row.insertCell( 5 );
  cell.innerHTML = "Fr";
  cell.className = "CalendarDayNames";
  cell = row.insertCell( 6 );
  cell.innerHTML = "Sa";
  cell.className = "CalendarDayNames";

  // The optional spacing on the first week of the month
  var firstDay = new Date( year, month, 1 ).getDay();
  if( firstDay > 0 )
  {
    row = table.insertRow( table.rows.length );
    cell = row.insertCell( row.cells.length );
    cell.colSpan = firstDay;
    cell.innerHTML = "&nbsp;";
  }
  else row = null;

  // The days of the month
  var numDays = getNumberDays( new Date( year, month, 1 ) );
  for( var i = 1 ; i <= numDays ; i++ )
  {
    if( ( ( i + firstDay ) % 7 == 1 && i != 1 ) || row == null )
    {
      row = table.insertRow( table.rows.length );
    }

    var theDate = new Date( year, month, i );
    cell = row.insertCell( row.cells.length );
    cell.style.cursor = "pointer";
    cell.vAlign = "top";
    cell.id = "Day" + i;
    if( dayClick )
    {
      cell.value = ( theDate.getMonth() + 1 ) + "/" + theDate.getDate() + "/" + theDate.getFullYear();
      cell.onclick = function(){ dayClick( this.value ); };
    }
    cell.innerHTML = ( i < 10 ? "&nbsp;" : "" ) + i;
    if( now.valueOf() == theDate.valueOf() )
      cell.className = "CalendarOnDay";
    else
      cell.className = "CalendarOffDay";
  }

  // The optional spacing on the last week of the month
  var endDays = ( 7 - ( ( firstDay + numDays ) % 7 ) ) % 7;
  if( endDays > 0 )
  {
    cell = row.insertCell( row.cells.length );
    cell.colSpan = endDays;
    cell.innerHTML = "&nbsp;";
  }

  var d = get( name );
  while( d.childNodes.length > 0 )
  {
    d.removeChild( d.firstChild );       
  }
  d.appendChild( table );
}

function getDate( e1, e2 )
{
  Hide( get("GetTimeDiv") );
  event.cancelBubble = true;
  with( get("GetDateDiv").style )
  {
    visibility = "visible";
    top = findPosY( e1 ) + "px";
    left = ( findPosX( e1 ) + e1.offsetWidth + 1 ) + "px";
    zIndex = 1000;
  }
  var onclick = function( d )
  {
    e1.value = d;
    if( e2 ) e2.value = d;
    Hide( get("GetDateDiv") );
  }
  var now = ( e1.value != "" ? new Date( e1.value ) : new Date() );
  CreateCalendar( now.getFullYear(), now.getMonth(), "GetDateDiv", onclick, null );
}

function getTime( e1, e2, dt )
{
  Hide( get("GetDateDiv") );
  function GetTime_setTimeHour( dt )
  {
    var getTimeMeridiem = get("GetTimeMeridiem");
    var getTimeHour = get("GetTimeHour");
    var theHour = parseInt( getTimeHour.innerText.replace( /^0/g, "" ) );
    theHour += dt;
    while( theHour < 1 )
    {
      theHour += 12;
      getTimeMeridiem.innerText = ( getTimeMeridiem.innerText == "AM" ? "PM" : "AM" );
    }
    while( theHour > 12 )
    {
      theHour -= 12;
      getTimeMeridiem.innerText = ( getTimeMeridiem.innerText == "AM" ? "PM" : "AM" );
    }
    getTimeHour.innerText = ( theHour < 10 ? "0" : "" ) + theHour;
  }

  function GetTime_setTimeMinute( dt )
  {
    var getTimeMinute = get("GetTimeMinute");
    var theMinute = parseInt( getTimeMinute.innerText.replace( /^0/g, "" ) );
    theMinute += dt;
    while( theMinute < 0 ) theMinute += 60;
    while( theMinute >= 60 ) theMinute -= 60;
    getTimeMinute.innerText = ( theMinute < 10 ? "0" : "" ) + theMinute;
  }

  function GetTime_changeTimeMeridiem()
  {
    var getTimeMeridiem = get("GetTimeMeridiem");
    var theMeridiem = getTimeMeridiem.innerText;
    if( theMeridiem == "PM" )
    {
      theMeridiem = "AM";
    }
    else
    {
      theMeridiem = "PM";
    }
    getTimeMeridiem.innerText = theMeridiem;
  }

  var oldTable = get("GetTimeDiv");
  if( oldTable ) document.body.removeChild( oldTable );
  event.cancelBubble = true;

  var hour = "08", minute = "00", meridiem = "AM";
  if( e1.value != "" )
  {
    var str = e1.value.replace( /[:\s]/g, "," );
    var parts = str.split( "," );
    hour = ( parseInt( parts[0] ) < 10 ? "0" : "" ) + parseInt( parts[0] );
    minute = ( parseInt( parts[1] ) < 10 ? "0" : "" ) + parseInt( parts[1] );
    meridiem = parts[2];
  }

  var table = document.createElement( "TABLE" );
  table.id = "GetTimeDiv";
  table.cellPadding = 0;
  table.cellSpacing = 0;
  table.border = 1;
  table.style.borderCollapse = "collapse";
  table.style.fontSize = "8pt";
  table.style.fontFamily = "Courier New";
  table.style.position = "absolute";
  table.style.width = "220px";
  table.style.height = "125px";
  table.style.backgroundColor = "white";
  table.style.top = findPosY( e1 ) + "px";
  table.style.left = ( findPosX( e1 ) + e1.offsetWidth + 1 ) + "px";
  table.style.zIndex = 1000;
  table.onclick = function(){ event.cancelBubble = true; };

  var row = table.insertRow( table.rows.length ); row.height = "1%";
  ///////////////////////////////////////////////////////////
  var cell = row.insertCell( row.cells.length );
  cell.align = "center";
  cell.style.cursor = "pointer";
  cell.onselectstart = function(){ return( false ); };
  cell.onclick = function(){ GetTime_setTimeHour( 1 ); };
  cell.innerHTML = "<font size=6 color=blue>&#x25B2;</font>";
  ///////////////////////////////////////////////////////////
  cell = row.insertCell( row.cells.length );
  cell.align = "center";
  cell.style.cursor = "pointer";
  cell.onselectstart = function(){ return( false ); };
  cell.onclick = function() { GetTime_setTimeMinute( 10 ) };
  cell.innerHTML = "<font size=6 color=blue>&#x25B2;</font>";
  ///////////////////////////////////////////////////////////
  cell = row.insertCell( row.cells.length );
  cell.align = "center";
  cell.style.cursor = "pointer";
  cell.onselectstart = function(){ return( false ); };
  cell.onclick = function() { GetTime_setTimeMinute( 1 ) };
  cell.innerHTML = "<font size=6 color=blue>&#x25B2;</font>";
  ///////////////////////////////////////////////////////////
  cell = row.insertCell( row.cells.length );
  cell.align = "center";
  cell.style.cursor = "pointer";
  cell.onselectstart = function(){ return( false ); };
  cell.onclick = function(){ GetTime_changeTimeMeridiem(); };
  cell.innerHTML = "<font size=6 color=blue>&#x25B2;</font>";

  row = table.insertRow( table.rows.length ); row.height = "98%";

  cell = row.insertCell( row.cells.length );
  cell.id = "GetTimeHour";
  cell.align = "center";
  cell.style.fontSize = "20pt";
  cell.style.fontWeight = "bold";
  cell.innerText = hour;

  cell = row.insertCell( row.cells.length ); cell.colSpan = 2;
  cell.id = "GetTimeMinute";
  cell.align = "center";
  cell.style.fontSize = "20pt";
  cell.style.fontWeight = "bold";
  cell.innerText = minute;

  cell = row.insertCell( row.cells.length );
  cell.id = "GetTimeMeridiem";
  cell.align = "center";
  cell.style.fontSize = "20pt";
  cell.style.fontWeight = "bold";
  cell.innerText = meridiem;

  row = table.insertRow( table.rows.length ); row.height = "1%";
  ///////////////////////////////////////////////////////////
  cell = row.insertCell( row.cells.length );
  cell.align = "center";
  cell.style.cursor = "pointer";
  cell.onselectstart = function(){ return( false ); };
  cell.onclick = function(){ GetTime_setTimeHour( -1 ); };
  cell.innerHTML = "<font size=6 color=blue>&#x25BC;</font>";
  ///////////////////////////////////////////////////////////
  cell = row.insertCell( row.cells.length );
  cell.align = "center";
  cell.style.cursor = "pointer";
  cell.onselectstart = function(){ return( false ); };
  cell.onclick = function(){ GetTime_setTimeMinute( -10 ); };
  cell.innerHTML = "<font size=6 color=blue>&#x25BC;</font>";
  ///////////////////////////////////////////////////////////
  cell = row.insertCell( row.cells.length );
  cell.align = "center";
  cell.style.cursor = "pointer";
  cell.onselectstart = function(){ return( false ); };
  cell.onclick = function(){ GetTime_setTimeMinute( -1 ); };
  cell.innerHTML = "<font size=6 color=blue>&#x25BC;</font>";
  ///////////////////////////////////////////////////////////
  cell = row.insertCell( row.cells.length );
  cell.align = "center";
  cell.style.cursor = "pointer";
  cell.onselectstart = function(){ return( false ); };
  cell.onclick = function(){ GetTime_changeTimeMeridiem(); };
  cell.innerHTML = "<font size=6 color=blue>&#x25BC;</font>";

  row = table.insertRow( table.rows.length );
  cell = row.insertCell( row.cells.length );
  cell.colSpan = 4;
  cell.align = "center";

  var button = document.createElement( "INPUT" );
  button.type = "button";
  button.value = "Set Time";
  button.style.width = "85%";
  button.style.fontFamily = "Tahoma";
  button.style.fontSize = "12pt";
  button.onclick = function()
  {
    e1.value = get("GetTimeHour").innerText.replace( /^0/g, "" ) + ":" + get("GetTimeMinute").innerText + " " + get("GetTimeMeridiem").innerText;
    if( e2 )
    {
      var h = parseInt( get("GetTimeHour").innerText.replace( /^0/g, "" ) );
      var m = parseInt( get("GetTimeMinute").innerText.replace( /^0/g, "" ) );
      var n = get("GetTimeMeridiem").innerText;
      
      m += parseInt( dt );
      while( m >= 60 )
      {
        m -= 60; h += 1;
      }
      while( h > 12 )
      {
        h -= 12;
        if( n == "AM" ) n = "PM";
        else n = "AM";
      }
      
      e2.value = h + ":" + ( m < 10 ? "0" : "" ) + m + " " + n;
    }
    document.body.removeChild( table );
  };
  cell.appendChild( button );

  document.body.appendChild( table );
}

function fDateDiff( part, sDate, eDate )
{
  if( typeof( sDate ) != 'function' )
  {
    sDate = new Date( sDate );
  }
  if( typeof( eDate ) != 'function' )
  {
    eDate = new Date( eDate );
  }
  switch( part )
  {
    case "Y": case "y":
      return( ( eDate - sDate ) / (365.242199*1000*60*60*24) );

    case "D": case "d":
      return( ( eDate - sDate ) / (1000*60*60*24) );

    case "H": case "h":
      return( ( eDate - sDate ) / (1000*60*60) );

    case "N": case "n":
      return( ( eDate - sDate ) / (1000*60) );

    default:
      return( eDate - sDate );
  }
}

function DateDiff( part, sDate, eDate )
{
  return( Math.floor( fDateDiff( part, sDate, eDate ) ) );
}

function DateAdd( part, num, date )
{
  if( typeof( date ) != 'function' )
  {
    date = new Date( date );
  }

  switch( part )
  {
    case "D": case "d":
      return( new Date( date.valueOf() + num * (1000*60*60*24) ) );

    case "H": case "h":
      return( new Date( date.valueOf() + num * (1000*60*60) ) );

    case "N": case "n":
      return( new Date( date.valueOf() + num * (1000*60) ) );

    default:
      return( date );
  }
}

String.prototype.trim = function()
{
  return( this.replace(/^\s+|\s+$/g,"") );
}

String.prototype.ltrim = function()
{
  return( this.replace(/^\s+/,"") );
}

String.prototype.rtrim = function()
{
  return( this.replace(/\s+$/,"") );
}

function findPosX( obj )
{
  var curleft = 0;
  if( obj.offsetParent )
  {
    while( obj.offsetParent )
    {
      curleft += obj.offsetLeft;
      obj = obj.offsetParent;
    }
  }
  else if( obj.x )  curleft += obj.x;
  return( curleft );
}

function findPosY( obj )
{
  var curtop = 0;
  if( obj.offsetParent )
  {
    while( obj.offsetParent )
    {
      curtop += obj.offsetTop;
      obj = obj.offsetParent;
    }
  }
  else if( obj.y ) curtop += obj.y;
  return( curtop );
}

function FormatNumber( num, decimalNum, bolLeadingZero, bolCommas )
{ 
  if( isNaN( parseInt( num ) ) ) num = 0;

  var tmpNum = num, iSign = ( num < 0 ? -1 : 1 );  // Get sign of number

  var pow10 = Math.pow( 10, decimalNum )
  tmpNum = iSign * Math.round( Math.abs( tmpNum ) * pow10 ) / pow10;

  // Create a string object to do our formatting on
  var tmpNumStr = new String( tmpNum );

  // See if we need to strip out the leading zero or not.
  if( !bolLeadingZero && num < 1 && num > -1 && num != 0 )
  {
    if( num > 0 )
      tmpNumStr = tmpNumStr.substring( 1, tmpNumStr.length );
    else
      tmpNumStr = "-" + tmpNumStr.substring( 2, tmpNumStr.length );
  }

  // See if we need to put in the commas
  if( bolCommas && ( num >= 1000 || num <= -1000 ) )
  {
    var iStart = tmpNumStr.indexOf( "." );
    if( iStart < 0 ) iStart = tmpNumStr.length - 3;

    for( ; iStart >= 1 ; iStart -= 3 )
    {
      tmpNumStr = tmpNumStr.substring( 0, iStart ) + "," + tmpNumStr.substring( iStart, tmpNumStr.length )
    }		
  }

  if( decimalNum > 0 )
  {
    if( tmpNumStr.lastIndexOf( "." ) == -1 ) tmpNumStr += ".";
    while( tmpNumStr.length - tmpNumStr.lastIndexOf( "." ) < decimalNum + 1 ) tmpNumStr += "0";
  }

  return( tmpNumStr.replace( ",.", "." ) );
}

function Show( e )
{
  if( e && e.style )
  {
    e.style.visibility = "visible";
    e.style.position = "relative";
    e.style.left = e.style.top = "";
  }
}

function Hide( e )
{
  if( e && e.style )
  {
    e.style.visibility = "hidden";
    e.style.position = "absolute";
    e.style.left = e.style.top = "-1000px";
  }
}

function ShowHide( e )
{
  if( e.style.visibility == "hidden" ) Show( e );
  else                                 Hide( e );
}

function ShowCenter( e )
{
  with( e )
  {
    style.display = "block";
    style.visibility = "visible";
    style.left = "35%";
    style.top = "50%";
    style.zIndex = 1000;
  }
}

function getNumberDays( theDateInQuestion )
{
  switch( theDateInQuestion.getMonth() + 1 )
  {
    case  1: case  3: case  5: case  7:  case  8: case 10: case 12:
      return( 31 );
    case  4: case  6: case  9: case 11:
      return( 30 );
    case 2:
      return( 28 + ( theDateInQuestion.getYear() % 4 == 0 ? 1 : 0 ) );
  }
}

function getEnding( number )
{
  if( number > 10 && number < 20 ) return( "th" );

  switch( number % 10 )
  {
    case 0: case 4: case 5: case 6: case 7: case 8:
    case 9: return( "th" );
    case 1: return( "st" );
    case 2: return( "nd" );
    case 3: return( "rd" );
  }
}

var HTTP_UNINITIALIZED  = 0;
var HTTP_SETUP_NOTSENT  = 1;
var HTTP_PROCESSING     = 2;
var HTTP_PARTIAL_RESULT = 3;
var HTTP_COMPLETE       = 4;

function createRequest()
{
  var request = null;

  try
  {
    request = new XMLHttpRequest();
  }
  catch( failed_once )
  {
    try
    {
      request = new ActiveXObject( "Msxml2.XMLHTTP" );
    }
    catch( failed_twice )
    {
      try
      {
        request = new ActiveXObject( "Microsoft.XMLHTTP" );
      }
      catch( failed_thrice )
      {
        request = null;
      }
    }
  }

  return( request );
}
