var jscal_MONTHS = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ];
var jscal_DAYS = [ "s", "m", "t", "w", "t", "f", "s" ];

var jscal_CALENDARS = new Array();

function jsCalendar( name, initialDate )
{
  this.name        = name;
  this.initialDate = initialDate;
  this.selected    = new Array();
  this.selected[this.selected.length] = initialDate;
  this.currentDate = initialDate;
  this.canMoveYearValue = true;
  this.canMoveMonthValue = true;
  this.canCloseValue = true;
  this.closeOnClickValue = true;
}

function getJsCalendar( name, defaultDate )
{
  if( typeof(jscal_CALENDARS[name])=="undefined" )
  {
    jscal_CALENDARS[name] = new jsCalendar( name, defaultDate );
  }
  else if ( typeof(defaultDate)!="undefined" )
  {
    jscal_CALENDARS[name].currentDate = defaultDate;
    jscal_CALENDARS[name].selected    = new Array();
    jscal_CALENDARS[name].selected[jscal_CALENDARS[name].selected.length] = defaultDate ;
  }
  return jscal_CALENDARS[name];
}

jsCalendar.prototype.setTarget = function( targetFrame )
{
  if ( typeof(targetFrame)!="undefined" && targetFrame!=null )
  {
    this.targetFrame = targetFrame;
  }
}

jsCalendar.prototype.setDisplayFrame = function( displayFrame )
{
  if ( typeof(displayFrame)!="undefined" && displayFrame!=null )
  {
    this.displayFrame = displayFrame;
  }
}

jsCalendar.prototype.setClickFunction = function( clickFunction )
{
  if ( typeof(clickFunction)!="undefined" && clickFunction!=null )
  {
    this.clickFunction = clickFunction;
  }
}

jsCalendar.prototype.setCloseFunction = function( closeFunction )
{
  if ( typeof(closeFunction)!="undefined" && closeFunction!=null )
  {
    this.closeFunction = closeFunction;
  }
}

jsCalendar.prototype.setMoveMonthFunction = function( moveMonthFunction )
{
  if ( typeof(moveMonthFunction)!="undefined" && moveMonthFunction!=null )
  {
    this.moveMonthFunction = moveMonthFunction;
  }
}

jsCalendar.prototype.setMoveYearFunction = function( moveYearFunction )
{
  if ( typeof(moveYearFunction)!="undefined" && moveYearFunction!=null )
  {
    this.moveYearFunction = moveYearFunction;
  }
}

jsCalendar.prototype.canMoveYear = function( canMoveYearValue )
{
  this.canMoveYearValue = canMoveYearValue;
}

jsCalendar.prototype.canMoveMonth = function( canMoveMonthValue )
{
  this.canMoveMonthValue = canMoveMonthValue;
}

jsCalendar.prototype.canClose = function( canCloseValue )
{
  this.canCloseValue = canCloseValue;
}

jsCalendar.prototype.closeOnClick = function( closeOnClickValue )
{
  this.closeOnClickValue = closeOnClickValue;
}

jsCalendar.prototype.create = function( divElement, targetFrame, clickFunction, moveMonthFunction, moveYearFunction, closeFunction )
{
  if ( typeof(divElement)!="undefined" && divElement!=null )
  {
    this.element = divElement;
  }
  if ( typeof(this.element)=="undefined" || this.element==null )
  {
    this.element               = document.createElement("div");
    this.element.id            = "jsCalendar_" + this.name;
    this.element.className     = "jsCalendar";
    this.element.style.display = "none";
    this.element.style.zIndex  = 99;
    document.body.appendChild( this.element );
  }
  this.element.innerHTML = this.name;
  this.setTarget( targetFrame );
  this.setClickFunction( clickFunction );
  this.setMoveMonthFunction( moveMonthFunction );
  this.setMoveYearFunction( moveYearFunction );
  this.setCloseFunction( closeFunction );
}

jsCalendar.prototype.display = function( )
{
  if ( typeof(this.element)=="undefined" || this.element==null )
  {
    this.create( null );
  }
  if ( typeof(this.element)!="undefined" && this.element!=null )
  {
    this.element.style.display = "block";
  }
}


jsCalendar.prototype.draw = function( )
{
  this.create();

  var popCalLoop         = new Date(this.currentDate);
  var popCalToday        = new Date();
  popCalLoop.setDate(1);
  var loopMonth          = popCalLoop.getMonth();

  if ( this.element.className.indexOf("jsCalendar")==-1 )
  {
    this.element.className += (this.element.className=="" ? "" : " ") + "jsCalendar";
  }

  this.element.innerHTML = "";

  var week = this.append( this.element, "", "" );

  var target = "";

  var loopFrame = this.targetFrame
  if ( typeof(loopFrame)!="undefined" && loopFrame!=null && loopFrame!="" )
  {
    target = loopFrame + ".";
  }

  if ( this.canMoveYearValue )
    this.append( week, "<a href=\"javascript:"+target+"getJsCalendar('"+this.name+"').moveYear(-1);\">&laquo;&laquo;</a>", "monthPrevious" );
  if ( this.canMoveMonthValue )
    this.append( week, "<a href=\"javascript:"+target+"getJsCalendar('"+this.name+"').moveMonth(-1);\">&laquo;</a>", "monthPrevious" );
  if ( this.canMoveYearValue )
    this.append( week, "<a href=\"javascript:"+target+"getJsCalendar('"+this.name+"').moveYear(1);\">&raquo;&raquo;</a>", "monthNext" );
  if ( this.canMoveMonthValue )
    this.append( week, "<a href=\"javascript:"+target+"getJsCalendar('"+this.name+"').moveMonth(1);\">&raquo;</a>", "monthNext" );
  this.append( week, jscal_MONTHS[popCalLoop.getMonth()] + " " + popCalLoop.getFullYear(), "monthTitle" );
  week = this.append( this.element, "", "" );

  var esc = 1;

  week = this.append( this.element, "", "week" );
  for ( d=0; d<7; d++ )
  {
    var i = (d<6) ? d+1 : 0;
    this.append( week, jscal_DAYS[i], "dayhead h"+jscal_DAYS[i] );
  }

  var rows = 0;

  while( rows<6 || popCalLoop.getMonth()==loopMonth )
  {
    rows ++;
    week = this.append( this.element, "", "week" );
    for ( d=0; d<=6; d++ )
    {
      var i = (d<6) ? d+1 : 0;
      if ( popCalLoop.getDay()==i && popCalLoop.getMonth()==loopMonth)
      {
        var click = ""+target+"getJsCalendar('"+this.name+"').click("+popCalLoop.getDate()+")";
        var className = "day"
        if ( popCalLoop.getDate()==this.currentDate.getDate() && popCalLoop.getMonth()==this.currentDate.getMonth() && popCalLoop.getFullYear()==this.currentDate.getFullYear() )
        {
          className += " selected";
        }
        else
        if ( popCalLoop.getDate()==popCalToday.getDate() && popCalLoop.getMonth()==popCalToday.getMonth() && popCalLoop.getFullYear()==popCalToday.getFullYear() )
        {
          className += " today";
        }
        className += " " + jscal_DAYS[popCalLoop.getDay()];
        this.append( week, "<a href=\"javascript:"+click+";\">" + popCalLoop.getDate() + "</a>", className );
        popCalLoop.setDate( popCalLoop.getDate()+1 );
      }
      else
      {
        this.append( week, "&nbsp;", "daynone" );
      }
    }
    esc++;
  }
  this.append( this.element, "", "clear" );
  if ( this.canCloseValue )
    this.append( this.element, "<a href=\"javascript:"+target+"getJsCalendar('"+this.name+"').close();\">x</a>", "close" );
}


jsCalendar.prototype.append = function( outer, txt, style )
{
  var inner = null;
  if ( typeof(this.displayFrame)!="undefined" && this.displayFrame!=null )
  {
    inner = this.displayFrame.document.createElement("div");
  }
  else
  if ( typeof(outer.document)!="undefined" && typeof(outer.document.createElement)!="undefined" )
  {
    inner = outer.document.createElement("div");
  }
  else
  {
    inner = document.createElement("div");
  }
  inner.className = style;
  inner.innerHTML = txt;
  outer.appendChild( inner );
  return inner;
}

jsCalendar.prototype.click = function( day )
{
  this.currentDate.setDate( day );
  this.draw();
  if ( typeof(this.clickFunction)!="undefined" && this.clickFunction!=null )
  {
    this.clickFunction( this.currentDate );
  }
  if ( this.closeOnClickValue )
  {
    this.close();
  }
}

jsCalendar.prototype.moveMonth = function( count )
{
  this.currentDate.setMonth( this.currentDate.getMonth()+count );
  this.draw();
  if ( typeof(this.moveMonthFunction)!="undefined" && this.moveMonthFunction!=null )
  {
    this.moveMonthFunction( this.currentDate );
  }
}

jsCalendar.prototype.moveYear = function( count )
{
  this.currentDate.setFullYear( this.currentDate.getFullYear()+count );
  this.draw();
  if ( typeof(this.moveYearFunction)!="undefined" && this.moveYearFunction!=null )
  {
    this.moveYearFunction( this.currentDate );
  }
}

jsCalendar.prototype.test = function( date )
{
  alert( date );
}

jsCalendar.prototype.close = function( )
{
  this.element.style.display = "none";
  if ( typeof(this.closeFunction)!="undefined" && this.closeFunction!=null )
  {
    this.closeFunction( this.currentDate );
  }
}
