function DpCalendar( id) {
  
  this.date = new Date();
  this.id = id;  

  this.SetDate = function( year, month, day) {
    this.date.setYear( year);
    this.date.setMonth( month);
    this.date.setDate( day);
    this.CalUpdate();
  }
  
  this.CalUpdate = function() {
  
    var field = document.getElementById( "fin_" + this.id);
    var fshow = document.getElementById( "view_" + this.id);
    
    field.value = this.date.getTime() / 1000;
    fshow.innerHTML = this.CalFormat( this.date.getTime() / 1000);
      
  }  
  
  this.CalFormat = function( timestamp) {
    
    var selDate = new Date( timestamp * 1000 );
    
    var hours = "<span id=\"" + this.id + "_view_hours\"\">" + this.CalFill( selDate.getHours(), 2) + "</span>";
    var minutes = "<span id=\"" + this.id + "_view_minutes\">" + this.CalFill( selDate.getMinutes(), 2) + "</span>";

    return selDate.getFullYear() + "-" +
      this.CalFill( selDate.getMonth()+1, 2) + "-" +
      this.CalFill( selDate.getDate(), 2) + " " +
      hours + ":" +
      minutes;
    
  }
    
  this.CalFill = function( str, len) {
    var retstr = String(str);
    for ( i = 0; i < len - String(str).length; i++) {
      retstr = "0" + retstr;
    }
    return retstr;
  }
  
  this.StartDrag = function( event) {

    // IE doesn't pass event object:
    if ( event == null) event = window.event;
    // IE uses srcElement:
    __target = event.target != null ? event.target : event.srcElement;

    switch ( __target.id ) {
      case this.id + "_view_hours":
        __startVal = this.date.getHours();
        break;
      case this.id + "_view_minutes":
        __startVal = this.date.getMinutes();
	break;
      default:
        return true;
    }
    
    __startX = event.clientX;

    var val = this.CalcVal( event.clientX);
    __target.innerHTML = this.CalFill( val, 2);

    document.onmousemove = new Function( 'e', "dpCalendars['" + this.id + "'].Drag( e);");
    document.onmouseup = new Function( 'e', "dpCalendars['" + this.id + "'].StopDrag( e);");
    
    // Prevent text selection in IE:
    document.onselectstart = function() { return false; };
    // Prevent text selection in FF:
    return false;
    
  }
  
  this.Drag = function( event) {

    // IE doesn't pass event object:
    if ( event == null) event = window.event;

    var val = this.CalcVal( event.clientX);
    __target.innerHTML = this.CalFill( val, 2);
  
  }
  
  this.StopDrag = function( event) {

    document.onmousemove = null;
    document.onmouseup = null;
  
    // Enable text selection in IE:
    document.onselectstart = null;
    
    switch ( __target.id) {
      case this.id + "_view_hours":
	this.date.setHours( parseInt( __target.innerHTML));
	break;
      case this.id + "_view_minutes":
	this.date.setMinutes( parseInt( __target.innerHTML));
	break;
    }
    
    this.CalUpdate();
    
    __target = null;
    
  }

  this.CalcVal = function( clientX) {
    var val = parseInt( ( clientX - __startX ) / __interval + __startVal);
    if ( val < 0 ) val = 0;
    if ( __target.id.match( "view_hours") && val > 23) val = 23;
    if ( __target.id.match( "view_minutes") && val > 59) val = 59;
    return val;
  }
  
  this.CalBuild = function( id, showDt) {
  
    var field = document.getElementById( "fin_" + id);
    var selDt = field.value;
  
    var selDate = new Date();
    var nowDate = new Date();
    var showDate = new Date();
  
    if ( typeof( selDt) != "undefined") selDate.setTime( selDt * 1000);
    if ( typeof( showDt) != "undefined") showDate.setTime( showDt * 1000);
  
    var year;
    var month;
  
    year = showDate.getFullYear();
    month = showDate.getMonth();
  
    var firstDay = new Date( year, month, 1);
    year = firstDay.getFullYear();
    month = firstDay.getMonth();
    var lastDay = new Date( firstDay.getFullYear(), firstDay.getMonth() + 1, 0);
    var selDay = new Date( selDate.getFullYear(), selDate.getMonth(), selDate.getDate());
    var nowDay = new Date( nowDate.getFullYear(), nowDate.getMonth(), nowDate.getDate());
    var prevMonth = new Date( showDate.getFullYear(), showDate.getMonth() - 1, 1);
    var nextMonth = new Date( showDate.getFullYear(), showDate.getMonth() + 1, 1);
  
    var data = "";
    data += "<table><tr>";
    
    var iDay = new Date();
    iDay.setDate( iDay.getDate() - iDay.getDay());
    
    var header;
    for ( i = 0; i < 7; i++) {
      header = iDay.toString();
      header = header.split( " ");
      header = header[0];
      data += "<td class=days>" + header + "</td>";
      iDay.setDate( iDay.getDate() + 1);
    }
    
    data += "</tr><tr>";
    
    iDay = firstDay;
    
    for ( i = 0; i < iDay.getDay(); i++) {
      data += "<td></td>";
    }
  
    while ( iDay <= lastDay) {
      var tdClass = "";
      if ( iDay.getTime() == selDay.getTime()) {
	tdClass = " id=\"cal_selected\" class=\"selected\"";
      } else if ( iDay.getTime() == nowDay.getTime()) {
	tdClass = " id=\"cal_now\" class=\"now\"";
      }
      data += "<td" + tdClass + "><a href=\"javascript:dpCalendars['" + id + "'].SetDate( " + year + ", " + month + ", " + iDay.getDate() + ");\">" + iDay.getDate() + "</a></td>";
      iDay.setDate( iDay.getDate() + 1);
      if ( iDay.getDay() == 0) {
	data += "</tr><tr>";
      }
    }
    
    data += "</tr></table>";
    
    // Surround by table
    
    header = lastDay.toString();
    header = header.split( " ");
    
    previous_month = "<a href=\"javascript:dpCalendars['" + id + "'].CalBuild( \'" + id + "\', " + prevMonth.getTime() / 1000 + ");\">&lt;&lt;</a>"
    next_month = "<a href=\"javascript:dpCalendars['" + id + "'].CalBuild( \'" + id + "\', " + nextMonth.getTime() / 1000 + ");\">&gt;&gt;</a>"
    
    data = "<table class=cal><tr>" +
      "<td class=header>" + previous_month + "</td>" +
      "<td class=header>" + header[1].substring( 0, 3) + " " + header[3] + "</td>" +
      "<td class=header>" + next_month + "</td></tr>" +
      "<tr><td colspan=3>" +
      data + "</td></tr></table>";
    
    var popUp = document.getElementById( "cal_" + id);
    popUp.innerHTML = data;
  
  }
  
}

function CalToggle( id, dt) {

  var popUp = document.getElementById( "cal_" + id);

  if ( popUp.style.visibility == "visible") {
    popUp.style.visibility = "hidden";
  } else {
    dpCalendars[id].CalBuild( id, dt);
    popUp.style.visibility = "visible";
  }

  document.onmousedown = new Function( 'e', "dpCalendars['" + id + "'].StartDrag( e);");

}

var __target = null;
var __startX = 0;
var __startVal = 0;
var __interval = 10;

var dpCalendarNames = Array();
var dpCalendars = Array();

function InitCalendars() {
  for ( var i in dpCalendarNames) {
    var name = dpCalendarNames[i];
    dpCalendars[name] = new DpCalendar();
    dpCalendars[name].id = name;
    var eltInput = document.getElementById( "fin_" + name);
    var eltView = document.getElementById( "view_" + name);
    eltView.innerHTML = dpCalendars[name].CalFormat( eltInput.value);
  }
}

onload_functions[onload_functions.length] = 'InitCalendars();';
