function click_link(id)
{
  var onclick_handler = document.getElementById(id).getAttribute('onclick');
  if (onclick_handler != null) {
    eval(onclick_handler);
    return;
  }
  document.location = document.getElementById(id).getAttribute('href');
}

function show_calendar( str_form, str_field, str_date, str_origdate, str_calDivID, date_type )
{
  if ( !date_type || date_type == "BEGINS_ON_WEEK" ) date_type = "BEGINS_ON_DAY";

  var dt_date     = ( !str_date     )? new Date()           : str2dt( str_date );
  var dt_original = ( !str_origdate )? new Date( dt_date )  : str2dt( str_origdate );

  var calDiv = document.getElementById( str_calDivID );
  if ( !str_origdate && calDiv && calDiv.style.display=="inline" )
  {
    hideCalendar( str_calDivID );
    return;
  }

  var result = openTable();
  if ( date_type == "BEGINS_ON_MONTH" )
  {
    result += getMonthHeader( dt_date, dt_original, str_form, str_field, str_calDivID, date_type );
    result += getEmptySpacerRow();
  }
  else if ( date_type == "BEGINS_ON_DAY" )
  {
    result += getMonthHeader( dt_date, dt_original, str_form, str_field, str_calDivID, date_type );
    result += getWeekdayTitleRow();
    result += getCalendarDays( dt_date, dt_original, str_form, str_field, str_calDivID, date_type );
  }
  else if ( date_type == "BEGINS_ON_YEAR" )
  {
    result += getYearHeader( dt_date, dt_original, str_form, str_field, str_calDivID, date_type );
    result += getEmptySpacerRow();
  }
  result += todayCancelRow( dt_date, dt_original, str_form, str_field, str_calDivID, date_type );
  result += closeTable();

  createCalendarWindow( result, str_calDivID );
}

function getNextMonth( dt_date )
{
  var dt_next_month = new Date( dt_date );
  dt_next_month.setDate( 1 );
  dt_next_month.setMonth( dt_date.getMonth()+1 );
  return dt_next_month;
}

function getPrevMonth( dt_date )
{
  var dt_prev_month = new Date( dt_date );
  dt_prev_month.setDate( 1 );
  dt_prev_month.setMonth( dt_date.getMonth()-1 );
  return dt_prev_month;
}

function getNextYear( dt_date )
{
  var dt_next_year = new Date( dt_date );
  dt_next_year.setYear( dt_date.getFullYear()+1 );
  dt_next_year.setMonth( 0 );
  dt_next_year.setDate( 1 );
  return dt_next_year;
}

function getPrevYear( dt_date )
{
  var dt_prev_year = new Date( dt_date );
  dt_prev_year.setYear( dt_date.getFullYear()-1 );
  dt_prev_year.setMonth( 0 );
  dt_prev_year.setDate( 1 );
  return dt_prev_year;
}

function getMonthHeader( dt_date, dt_original, str_form, str_field, str_calDivID, date_type )
{
  var dt_next_month = getNextMonth( dt_date );
  var dt_prev_month = getPrevMonth( dt_date );

  var dt_dayone = new Date( dt_date );
  dt_dayone.setDate( 1 );

  return new String(
      '<tr><td>'+
      '<a href="javascript:' + getShowCalendarHref( dt_prev_month, dt_original, str_form, str_field, str_calDivID, date_type ) + ';" onclick="document.' + str_form + '.' + str_field + '.value=\''+dt2dtstr( dt_prev_month, date_type )+'\';' + onchange( str_form, str_field ) + '" title="Previous month">'+
      '  <img src="images/pointLeft.gif" style="border:0;padding:2px 10px 2px 2px;"></a></td>'+
      '<td colspan="5" style="text-align:center;white-space:nowrap;"><b>'+
      '<a href="javascript:document.' + str_form + '.' + str_field + '.value=\''+dt2dtstr( dt_dayone, date_type )+'\';hideCalendar(\'' + str_calDivID + '\');' + onchange( str_form, str_field ) + '">'+
      '  <span style="font-size:125%;">'+monthName( dt_dayone.getMonth() )+' '+ dt_dayone.getFullYear()+'</span></a></b></td>'+
      '<td style="text-align:right;">'+
      '<a href="javascript:' + getShowCalendarHref( dt_next_month, dt_original, str_form, str_field, str_calDivID, date_type ) + ';" onclick="document.' + str_form + '.' + str_field + '.value=\''+dt2dtstr( dt_next_month, date_type )+'\';' + onchange( str_form, str_field ) + '" title="Next month">'+
      '  <img src="images/pointRight.gif" style="border:0;padding:2px 2px 2px 10px;"></a></td></tr>'
  );
}

function getYearHeader( dt_date, dt_original, str_form, str_field, str_calDivID, date_type )
{
  var dt_next_year = getNextYear( dt_date );
  var dt_prev_year = getPrevYear( dt_date );

  var dt_dayone = new Date( dt_date );
  dt_dayone.setDate( 1 );
  dt_dayone.setMonth( 0 );

  return new String(
      '<tr><td>'+
      '<a href="javascript:' + getShowCalendarHref( dt_prev_year, dt_original, str_form, str_field, str_calDivID, date_type ) + ';" onclick="document.' + str_form + '.' + str_field + '.value=\''+dt2dtstr( dt_prev_year, date_type )+'\';' + onchange( str_form, str_field ) + '" title="Previous year">'+
      '  <img src="images/pointLeft.gif" border="0"></a></td>'+
      '<td colspan="5" align="center"><b>'+
      '<a href="javascript:document.' + str_form + '.' + str_field + '.value=\''+dt2dtstr( dt_dayone, date_type )+'\';hideCalendar(\'' + str_calDivID + '\');' + onchange( str_form, str_field ) + '">'+
      '  <span class="black" style="font-size:120%;">'+ dt_dayone.getFullYear()+'</span></a></b></td>'+
      '<td align="right">'+
      '<a href="javascript:' + getShowCalendarHref( dt_next_year, dt_original, str_form, str_field, str_calDivID, date_type ) + ';" onclick="document.' + str_form + '.' + str_field + '.value=\''+dt2dtstr( dt_next_year, date_type )+'\';' + onchange( str_form, str_field ) + '" title="Next year">'+
      '  <img src="images/pointRight.gif" border="0"></a></td></tr>'
  );
}

function getCalendarDays( dt_date, dt_original, str_form, str_field, str_calDivID, date_type )
{
  var dt_next_month = getNextMonth( dt_date );

  var dt_current_day = new Date( dt_date );
  dt_current_day.setDate( 1 );
  dt_current_day.setDate( 1-( 7+dt_current_day.getDay() )%7 );
  var result = "";
  for ( weekIx=0; weekIx < 6; weekIx++ )
  {
    result += "<tr>";
    for ( var n_current_wday=0; n_current_wday<7; n_current_wday++ )
    {      
      result += getDayCell( dt_current_day, dt_date, dt_original, str_form, str_field, str_calDivID, date_type );
      dt_current_day.setDate( dt_current_day.getDate()+1 );
    }
    result += "</tr>";
  }
  return result;
}

function todayCancelRow( dt_date, dt_original, str_form, str_field, str_calDivID, date_type )
{
  result =
    '<tr>' +
      '<td colspan="3" style="text-align:left;">' +
        '<a href="javascript:document.' + str_form + '.' + str_field + '.value=\''+dt2dtstr( new Date(), date_type )+'\';hideCalendar(\'' + str_calDivID + '\');' + onchange( str_form, str_field ) + '">Today</a>' +
      '</td>' +
      '<td>&nbsp;</td>' +
      '<td colspan="3" style="text-align:right;">' +
        '<a href="javascript:document.' + str_form + '.' + str_field + '.value=\''+dt2dtstr( dt_original, date_type )+'\';hideCalendar(\'' + str_calDivID + '\');' + onchange( str_form, str_field ) + '">Cancel</a>' +
      '</td>' +
    '</tr>';
  return result;
}

function openTable()
{
  return new String(
    '<table cellspacing="0" style="border:1px solid black;">'+
    '<tr><td>'+
    '<table cellspacing="1" cellpadding="1" border="0" style="font-size:80%;">'
  );
}

function closeTable()
{
  return "</table></td></tr></table>";
}

function createCalendarWindow( result, str_calDivID )
{
  var calDiv = document.getElementById( str_calDivID );
  if ( !calDiv ) return;
  calDiv.innerHTML = result;
  calDiv.style.display="none";
  calDiv.style.display="inline";
}

function hideCalendar( str_calDivID )
{
  var calDiv = document.getElementById( str_calDivID );
  if ( !calDiv ) return;
  calDiv.innerHTML = "";
  calDiv.style.display="none";
}

function getWeekdayTitleRow()
{
  var result = "<tr>";
  var week_days = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
  for ( var n=0; n<7; n++ )
  {
    result += '  <td bgcolor="#BBCCDD" align="center" style="font-size:110%;width:28px;"><p><b>'+week_days[n%7]+'</b></p></td>';
  }
  result += "</tr>";
  return result;
}

function getEmptySpacerRow()
{
  var result = '<tr style="line-height:1px;">';
  for ( var n=0; n<7; n++ )
  {
    result += '  <td style="width:28px;"><p>&nbsp;</p></td>';
  }
  result += "</tr>";
  return result;
}

function getShowCalendarHref( nextDate, origDate, str_form, str_field, str_calDivID, date_type )
{
  return "show_calendar('"+str_form+"', '" + str_field +"', '"+dt2dtstr( nextDate, date_type )+"', '"+dt2dtstr( origDate, date_type )+"', '" + str_calDivID + "', '"+ date_type +"');";
}

function padNumber( day )
{
  return ( day < 10 )? "&nbsp;&nbsp;"+day+"&nbsp;" : "&nbsp;"+day+"&nbsp;"; 
}

function getDayCell( currDate, monthDate, origDate, str_form, str_field, str_calDivID, date_type )
{
  var result = '<td bgcolor="' + getDayCellColor( currDate, origDate, monthDate ) + '" align="center">';
  if ( currDate.getMonth() == monthDate.getMonth() )
  {
    result += '<p><a href="javascript:document.' + str_form + '.' + str_field + '.value=\''+dt2dtstr( currDate, date_type )+'\';hideCalendar(\'' + str_calDivID + '\');' + onchange( str_form, str_field ) + '"><span class="black">'+padNumber( currDate.getDate() )+'</span></a></p>';
  }
  else
  {
    result += "<p>&nbsp;</p>";
  }
  result += "</td>";
  return result;
}

function getDayCellColor( dt_current_day, dt_original, dt_date )
{
  if ( dt_current_day.getDate()   == dt_original.getDate()  &&
       dt_current_day.getMonth()  == dt_original.getMonth() &&
       dt_current_day.getYear()   == dt_original.getYear()  &&
       dt_current_day.getMonth()  == dt_date.getMonth()
     )
  {
    return "#99AABB";
  }
  return "#eeeeee";
}

function str2dt( str_date )
{
  // pad out to look like a date (worth a shot)
  var re_slashes = /\/.+\//;
  while ( !re_slashes.exec( str_date ) )
  {
    str_date += "/1";
  }

  // parse date
  var re_date = /^(\d{4})\/(\d{1,2})\/(\d{1,2})$/;
  if ( !re_date.exec( str_date ) )
  {
    return new Date();
  }
  var year  = RegExp.$1;
  var month = RegExp.$2;
  var day   = RegExp.$3;
  if ( year > 2200 || year < 1900 || month < 1 || month > 12 || day < 1 || day > 31 )
  {
    return new Date();
  }
  return ( new Date ( year, month-1, day ) );
}
function dt2dtstr ( dt_date, date_type )
{
  if ( date_type == "BEGINS_ON_YEAR" ) {
    return dt_date.getFullYear();
  }
  if ( date_type == "BEGINS_ON_MONTH" ) {
    return dt_date.getFullYear()+"/"+(dt_date.getMonth()+1);
  }
  return dt_date.getFullYear()+"/"+(dt_date.getMonth()+1)+"/"+dt_date.getDate();
}

function monthName( ixMonth )
{
  var arr_months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
  return arr_months[ixMonth];
}

function onchange( str_form, str_field )
{
  return 'if( document.' + str_form + '.' + str_field + '.onchange ){ document.' + str_form + '.' + str_field + '.onchange(); }';
}
