function CalendarTable (in_Date) {
  if (in_Date==undefined) in_Date=new Date();
  this.activeYear = in_Date.getFullYear();
  this.activeMonth = in_Date.getMonth();
  this.fromYear = this.activeYear;
  this.fromMonth = this.activeMonth;
  this.monthsShown = 1;
	this.sameHeight = false;
  this.ondraw = null;
  var that = this;
  var parent = undefined;
  var calendarDiv = undefined;
  this.dayOnMouseOverFncName = '';
  this.dayOnMouseOutFncName = '';
  
  this.getMonthDays=function (in_Month,in_Year) {
    if (in_Month!=1) 
      return MonthDays[in_Month];
    else {
      l_result=MonthDays[in_Month];
      if (new Date(in_Year,in_Month,29).getDate()==29) l_result++;
      return l_result;
    }   
  }

  function monthEntry(in_Month,in_Year,in_FirstMonth) {
    var l_prior = (in_FirstMonth?'\n<td onmouseover="calendarTable.showButton(this,1)" onmouseout="calendarTable.showButton(this,0)" onmousedown="calendarTable.showButton(this,2)" onmouseup="calendarTable.showButton(this,1)" onclick="calendarTable.changeMonth(-1)"><img src="images/cal_prev.gif" alt="" title="Previous month"></td>\n':'<td>&nbsp;</td>');
    var l_next = (in_FirstMonth?'\n<td onmouseover="calendarTable.showButton(this,1)" onmouseout="calendarTable.showButton(this,0)" onmousedown="calendarTable.showButton(this,2)" onmouseup="calendarTable.showButton(this,1)" onclick="calendarTable.changeMonth(1)"><img src="images/cal_next.gif" alt="" title="Next month"></td>\n':'<td>&nbsp;</td>');
    var l_Html ='<table summary="" class="calendar" cellspacing="0" cellpadding="0"><tr class="'+(in_FirstMonth?'calFirstMonth':'calNextMonth')+'">'+l_prior+'<td colspan="5"'+(in_FirstMonth?' title="Show current month" onclick="calendarTable.showCurrentMonth()"':'')+'>'+MonthNames[in_Month]+'&nbsp;'+in_Year+'</td>'+l_next+'</tr>\n';
		var l_RowCount = 0;
    l_Html +='<tr class="calDays">\n';
    for(i=0;i<7;i++) l_Html +='<td>'+WeekDays[i]+'</td>';
    l_Html +='</tr>'; 
    l_Day = (new Date(in_Year,in_Month,1)).getDay();
    l_Html +='<tr class="calNumbers">';
    for(i=0;i<l_Day;i++) l_Html+='<td>&nbsp;</td>';
    l_DayCount=that.getMonthDays(in_Month,in_Year);
    l_Day--;
    if (that.dayOnMouseOverFncName) l_OnMouse=' onmouseover="'+that.dayOnMouseOverFncName+'(this);"';
    else l_OnMouse='';
    if (that.dayOnMouseOutFncName) l_OnMouse+=' onmouseout="'+that.dayOnMouseOutFncName+'(this);"'
      
    in_Month++; //real month the the JS number  
    for(i=1;i<=l_DayCount;i++) {
      l_Day++;
      if (l_Day==7) {
        l_Day=0;
        l_Html+='</tr>\n<tr class="calNumbers">';
				l_RowCount++;
      }
      l_Html+='<td id="'+that.dayID(in_Year,in_Month,i)+'"'+l_OnMouse+'>'+i+'</td>';
    } 
		if (that.sameHeight) {
		  while (l_RowCount<5) {
			  l_Html+='</tr><tr><td>&nbsp;</td>\n';
				l_RowCount++;
			}
		}
    l_Html +='</tr>\n</table>\n'; 
    return l_Html;
  }

  this.draw = function(in_Parent) {
    //initial checks;
    if (in_Parent) {
      if (in_Parent!=parent) {
        parent = in_Parent;
        if (calendarDiv) {
          if (calendarDiv.parentNode)
            calendarDiv.parentNode.removeChild(calendarDiv);
          calendarDiv = undefined;
        }  
      }
    }
    else if (!parent) return; //no parent to place the calendar
    //prepare the code
    var l_Holder = document.createElement('div');
    var l_Html = '';
    l_Html += monthEntry(this.activeMonth,this.activeYear,true);
    this.fromYear = this.activeYear;
    this.fromMonth = this.activeMonth;
    for (i=1;i<this.monthsShown;i++) {
      this.fromMonth--;
      if (this.fromMonth<0) {
        this.fromMonth=11;
        this.fromYear--;
      }
      l_Html += monthEntry(this.fromMonth,this.fromYear,false);
    }
    l_Holder.innerHTML = l_Html;
    //show on page
    if (calendarDiv)
      parent.replaceChild(l_Holder,calendarDiv);
    else {
      if (parent.firstChild)
        parent.insertBefore(l_Holder,parent.firstChild);
      else
        parent.appendChild(l_Holder);  
    }  
    //final assignments
    calendarDiv = l_Holder;
    if (this.ondraw) this.ondraw(this);
    return calendarDiv;
  }
  
  this.changeMonth=function (in_Delta) {
    this.activeMonth += in_Delta;
    while (this.activeMonth<0) {
      this.activeMonth+=12;
      this.activeYear--;
    }
    while (this.activeMonth>11) {
      this.activeMonth-=12;
      this.activeYear++;
    }    
    this.draw();
  }
  
  this.showCurrentMonth = function() {
    l_Date=new Date();
    l_ActiveYear =  l_Date.getFullYear();
    l_ActiveMonth = l_Date.getMonth();
    if ((l_ActiveYear!=this.activeYear)||(l_ActiveMonth!=this.activeMonth)) {
      this.activeYear = l_ActiveYear;
      this.activeMonth = l_ActiveMonth; 
      this.draw();
    }  
  }
  
  this.showButton = function (in_Cell, in_State) {
    //States 0 no border, 1 normal button, 2 button pushed
    switch(in_State) {
      case 2 :
        in_Cell.style.borderLeft = 'buttonshadow 1px solid';
        in_Cell.style.borderTop = 'buttonshadow 1px solid';
        in_Cell.style.borderBottom = 'buttonhighlight 1px solid';
        in_Cell.style.borderRight = 'buttonhighlight 1px solid';
        break;
      case 1 : 
        in_Cell.style.borderLeft = 'buttonhighlight 1px solid';
        in_Cell.style.borderTop = 'buttonhighlight 1px solid';
        in_Cell.style.borderBottom = 'buttonshadow 1px solid';
        in_Cell.style.borderRight = 'buttonshadow 1px solid';
        break;
      case 0 :
        in_Cell.style.border = 'buttonshadow 0px none'; 
        break; 
    }
  }
  
  this.dayID = function (in_Year,in_Month,in_Day) {
    return 'd_'+in_Year+'_'+in_Month+'_'+in_Day;
  }

}

var calendarTable = new CalendarTable();

var WeekDays = new Array('S','M','T','W','T','F','S');
var MonthDays = new Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
var MonthNames = new Array('January','February','March','April','May','June','July','August','September','October','November','December');


