    var timeoutDelay = 2000;
    var g_startDay = 1
    
    var imgUp = new Image(8,12);
    imgUp.src = 'imagens/up.gif';
    var imgDown = new Image(8,12);
    imgDown.src = 'imagens/down.gif';
    
    var timeoutId = false;
    
    function Browser(){
      this.dom = document.getElementById?1:0;
      this.ie4 = (document.all && !this.dom)?1:0;
      this.ns4 = (document.layers && !this.dom)?1:0;
      this.ns6 = (this.dom && !document.all)?1:0;
      this.ie5 = (this.dom && document.all)?1:0;
      this.ok = this.dom || this.ie4 || this.ns4;
      this.platform = navigator.platform;
    }
    var browser = new Browser();
        
    
    if (browser.dom || browser.ie4){
        document.writeln('<style>');
        document.writeln('#container_data {');
        document.writeln('position : absolute;');
        document.writeln('left : 100px;');
        document.writeln('top : 100px;');
        document.writeln('width : 170px;');;
        browser.platform=='Win32'?height=140:height=145;
        document.writeln('height : ' + height +'px;');
        document.writeln('clip:rect(0px 170px ' + height + 'px 0px);');
        //document.writeln('overflow : hidden;');
        document.writeln('visibility : hidden;');
        document.writeln('background-color : #ffffff');
        document.writeln('}');
        document.writeln('</style>')
        document.write('<div id="container_data"');
        if (timeoutDelay) document.write(' onmouseout="calendarTimeout();" onmouseover="if (timeoutId) clearTimeout(timeoutId);"');
        document.write('></div>');
    }
    
    var g_Calendar;  // global to hold the calendar reference, set by constructor
    
    function calendarTimeout(){
      if (browser.ie4 || browser.ie5){
        if (window.event.srcElement && window.event.srcElement.name!='month') timeoutId=setTimeout('g_Calendar.hide();',timeoutDelay);
      }
      if (browser.ns6 || browser.ns4){
        timeoutId=setTimeout('g_Calendar.hide();',timeoutDelay);
      }
    }
    

    function Calendar(){
      g_Calendar = this;

      this.daysOfWeek = new Array("Dom","Seg","Ter","Qua","Qui","Sex","Sab");
      this.months = new Array("Janeiro","Fevereiro","Março","Abril","Maio","Junho","Julho","Agosto","Setembro","Outubro","Novembro","Dezembro");
      this.daysInMonth = new Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
      
      if (browser.ns4){
        var tmpLayer = new Layer(127);
        if (timeoutDelay){
          tmpLayer.captureEvents(Event.MOUSEOVER | Event.MOUSEOUT);
          tmpLayer.onmouseover = function(event) { if (timeoutId) clearTimeout(timeoutId); };
          tmpLayer.onmouseout = function(event) { timeoutId=setTimeout('g_Calendar.hide()',timeoutDelay);};
        }
        tmpLayer.x = 100;
        tmpLayer.y = 100;
        tmpLayer.bgColor = "#ffffff";
      }
      if (browser.dom || browser.ie4){
        var tmpLayer = browser.dom?document.getElementById('container_data'):document.all.container_data;
      }
      this.container_dataLayer = tmpLayer;
      if (browser.ns4 && browser.platform=='Win32') {
        this.container_dataLayer.clip.height=134;
        this.container_dataLayer.clip.width=127;
      }

    }
    
    Calendar.prototype.getFirstDOM = function() {
        var thedate = new Date();
        thedate.setDate(1);
        thedate.setMonth(this.month);
        thedate.setFullYear(this.year);
        return thedate.getDay();
    }

    Calendar.prototype.getDaysInMonth = function (){
       if (this.month!=1) {
       return this.daysInMonth[this.month]
       }
       else {
         // is it a leap year
            if (BetterDate.isLeapYear(this.year)) {
              return 29;
            }
            else {
              return 28;
            }
       }
    }
     
    Calendar.prototype.buildString = function(){
      var tmpStr = '<form onSubmit="this.year.blur();return false;"><table width="100%" border="0" cellspacing="0" cellpadding="1" class="calBorderColor"><tr><td valign="top"><table width="100%" border="0" cellspacing="0" cellpadding="1" class="calBgColor">';
      tmpStr += '<tr>';
      tmpStr += '<td width="60%" class="cal" align="left">';
      if (this.hasDropDown) {
        tmpStr += '<select class="month" name="month" onchange="g_Calendar.selectChange();">';
        for (var i=0;i<this.months.length;i++){
          tmpStr += '<option value="' + i + '"' 
          if (i == this.month) tmpStr += ' selected';
          tmpStr += '>' + this.months[i] + '</option>';
        }
        tmpStr += '</select>';
      } else {
        tmpStr += '<table border="0" cellspacing="0" cellpadding="0"><tr><td><a href="javascript: g_Calendar.changeMonth(-1);"><img name="calendar" src="imagens/down.gif" width="8" height="12" border="0" alt=""></a></td><td class="cal" width="100%" align="center">' + this.months[this.month] + '</td><td class="cal"><a href="javascript: g_Calendar.changeMonth(+1);"><img name="calendar" src="imagens/up.gif" width="8" height="12" border="0" alt=""></a></td></tr></table>';
      }
      tmpStr += '</td>';
      /* observation : for some reason if the below event is changed to 'onChange' rather than 'onBlur' it totally crashes IE (4 and 5)!
      */
      tmpStr += '<td width="40%" align="right" class="cal">';
      
      if (this.hasDropDown) { 
        tmpStr += '<input class="year" type="text" size="';
        // get round NS4 win32 lenght of year input problem
        (browser.ns4 && browser.platform=='Win32')?tmpStr += 1:tmpStr += 4;
      tmpStr += '" name="year" maxlength="4" onBlur="g_Calendar.inputChange();" value="' + this.year + '">';
      } else {
      tmpStr += '<table border="0" cellspacing="0" cellpadding="0"><tr><td class="cal"><a href="javascript: g_Calendar.changeYear(-1);"><img name="calendar" src="imagens/down.gif" width="8" height="12" border="0" alt=""></a></td><td class="cal" width="100%" align="center">' + this.year + '</td><td class="cal"><a href="javascript: g_Calendar.changeYear(+1);"><img name="calendar" src="imagens/up.gif" width="8" height="12" border="0" alt=""></a></td></tr></table>'
      }
      tmpStr += '</td>';
      tmpStr += '</tr>';
      tmpStr += '</table>';
      var iCount = 1;
      var iFirstDOM = this.getFirstDOM()-g_startDay; // to prevent calling it in a loop
      if (iFirstDOM < 0 ) iFirstDOM = iFirstDOM + 7;
      //alert(iFirstDOM);
      var iDaysInMonth = this.getDaysInMonth(); // to prevent calling it in a loop
      
      tmpStr += '<table width="100%" border="0" cellspacing="0" cellpadding="1" class="calBgColor">';
      tmpStr += '<tr>';
        for (var i=0;i<7;i++){
          tmpStr += '<td align="center" class="calDaysColor">' + this.daysOfWeek[(g_startDay+i)%7] + '</td>';
        }
      tmpStr += '</tr>';
      var tmpFrom = parseInt('' + this.dateFromYear + this.dateFromMonth + this.dateFromDay,10);
      var tmpTo = parseInt('' + this.dateToYear + this.dateToMonth + this.dateToDay,10);
      var tmpCompare;
      for (var j=1;j<=6;j++){
         tmpStr += '<tr>';
         for (var i=1;i<=7;i++){
           tmpStr += '<td width="16" align="center" '
           if ( (7*(j-1) + i)>=iFirstDOM+1  && iCount <= iDaysInMonth){
             if (iCount==this.day && this.year==this.oYear && this.month==this.oMonth) tmpStr += 'class="calHighlightColor"';
             else {
                if (i==1 || i==7) tmpStr += 'class="calWeekend"';
                else tmpStr += 'class="cal"';
             }
             tmpStr += '>';
             /* could create a date object here and compare that but probably more efficient to convert to a number
               and compare number as numbers are primitives */
             tmpCompare = parseInt('' + this.year + padZero(this.month) + padZero(iCount),10);
             if (tmpCompare >= tmpFrom && tmpCompare <= tmpTo) {
               tmpStr += '<a class="cal" href="javascript: g_Calendar.clickDay(' + iCount + ');">' + iCount + '</a>';
             } else {
               tmpStr += '<span class="disabled">' + iCount + '</span>';
             }
             iCount++;
           } else {
             if  (i==1 || i==7) tmpStr += 'class="calWeekend"'; else tmpStr +='class="cal"';
             tmpStr += '>&nbsp;';
           }
           tmpStr += '</td>'
         }
         tmpStr += '</tr>'
      }
      tmpStr += '</table></td></tr></table></form>'
      return tmpStr;
    }
    
    Calendar.prototype.selectChange = function(){
      this.month = browser.ns6?this.container_dataLayer.ownerDocument.forms[0].month.selectedIndex:this.container_dataLayer.document.forms[0].month.selectedIndex;
      this.writeString(this.buildString());
    }
    
    Calendar.prototype.inputChange = function(){
      var tmp = browser.ns6?this.container_dataLayer.ownerDocument.forms[0].year:this.container_dataLayer.document.forms[0].year;
      if (tmp.value >=1900 || tmp.value <=2100){
        this.year = tmp.value;
        this.writeString(this.buildString());
      } else {
        tmp.value = this.year;
      }
    }
    Calendar.prototype.changeYear = function(incr){
       (incr==1)?this.year++:this.year--;
       this.writeString(this.buildString());
    }
    Calendar.prototype.changeMonth = function(incr){
        if (this.month==11 && incr==1){
          this.month = 0;
          this.year++;
        } else {
          if (this.month==0 && incr==-1){
            this.month = 11;
            this.year--;
          } else {
            (incr==1)?this.month++:this.month--;
          }
        }
        this.writeString(this.buildString());
    }
    
    Calendar.prototype.clickDay = function(day){
       var tmp = eval('document.' + this.target);
       if (this.dateFormat=='dd-mmm-yyyy') tmp.value = day + this.dateDelim + this.months[this.month].substr(0,3) + this.dateDelim + this.year;
       if (this.dateFormat=='dd/mm/yyyy') tmp.value = day + this.dateDelim + (this.month+1) + this.dateDelim + this.year;
       if (this.dateFormat=='mm/dd/yyyy') tmp.value = (this.month+1) + this.dateDelim + day + this.dateDelim + this.year;
       if (this.dateFormat=='yyyy-mm-dd') tmp.value = this.year + this.dateDelim + (this.month+1) + this.dateDelim + day;
       
        if (browser.ns4) this.container_dataLayer.hidden=true;
        if (browser.dom || browser.ie4){
          this.container_dataLayer.style.visibility='hidden'
        }
    }
    
    Calendar.prototype.writeString = function(str){
      if (browser.ns4){
        this.container_dataLayer.document.open();
        this.container_dataLayer.document.write(str);
        this.container_dataLayer.document.close();
      } 
      if (browser.dom || browser.ie4){
        this.container_dataLayer.innerHTML = str;
      }
    }
    
    Calendar.prototype.show = function(event, target, bHasDropDown, dateFormat, dateFrom, dateTo){

    if (dateFrom) this.dateFrom = dateFrom; else this.dateFrom = new Date(1900,0,1);
    this.dateFromDay = padZero(this.dateFrom.getDate());
    this.dateFromMonth = padZero(this.dateFrom.getMonth());
    this.dateFromYear = this.dateFrom.getFullYear();
    if (dateTo) this.dateTo = dateTo; else this.dateTo = new Date(3000,0,1);
    this.dateToDay = padZero(this.dateTo.getDate());
    this.dateToMonth = padZero(this.dateTo.getMonth());
    this.dateToYear = this.dateTo.getFullYear();
    this.hasDropDown = bHasDropDown;
    if (dateFormat) this.dateFormat = dateFormat; else this.dateFormat = 'dd-mmm-yyyy';
    switch (this.dateFormat){
      case 'dd-mmm-yyyy':
      case 'yyyy-mm-dd':
        this.dateDelim = '-';
        break;
      case 'dd/mm/yyyy':
      case 'mm/dd/yyyy':
        this.dateDelim = '/';
        break;
    }
    
      if (browser.ns4) {
        if (!this.container_dataLayer.hidden) {
          this.container_dataLayer.hidden=true;
          return;
        }
       }
      if (browser.dom || browser.ie4){
        if (this.container_dataLayer.style.visibility=='visible') {
          this.container_dataLayer.style.visibility='hidden';
          return;
        }  
      }

      if (browser.ie5 || browser.ie4){
        var event = window.event;
      }
      if (browser.ns4){
        this.container_dataLayer.x = event.x+10;
        this.container_dataLayer.y = event.y-5;
      }
      if (browser.ie5 || browser.ie4){
        var obj = event.srcElement;
        x = 0;
        while (obj.offsetParent != null) {
              x += obj.offsetLeft;
              obj = obj.offsetParent;
        }
        x += obj.offsetLeft;
        y = 0;
        var obj = event.srcElement;
        while (obj.offsetParent != null) {
              y += obj.offsetTop;
              obj = obj.offsetParent;
        }
        y += obj.offsetTop;
        
        this.container_dataLayer.style.left = x+35;
        if (event.y>0)this.container_dataLayer.style.top = y;
      }
      if (browser.ns6){
        this.container_dataLayer.style.left = event.pageX+10;
        this.container_dataLayer.style.top = event.pageY-5;
      }
      this.target = target;
      var tmp = eval('document.' + this.target);
      if (tmp && tmp.value && tmp.value.split(this.dateDelim).length==3){
        var atmp = tmp.value.split(this.dateDelim)
        switch (this.dateFormat){
         case 'dd-mmm-yyyy':
           for (var i=0;i<this.months.length;i++){
             if (atmp[1].toLowerCase()==this.months[i].substr(0,3).toLowerCase()){
               this.month = this.oMonth = i;
               break;
             }
           }
           this.day = parseInt(atmp[0],10);
           this.year = parseInt(atmp[2],10);
           break;
         case 'dd/mm/yyyy':
         case 'dd-mm-yyyy':
           this.month = this.oMonth = parseInt(atmp[1]-1,10); 
           this.day = parseInt(atmp[0],10);
           this.year = parseInt(atmp[2],10);
           break;
         case 'mm/dd/yyyy':
         case 'mm-dd-yyyy':
           this.month = this.oMonth = parseInt(atmp[0]-1,10);
           this.day = parseInt(atmp[1],10);
           this.year = parseInt(atmp[2],10);
           break;
         case 'yyyy-mm-dd':
           this.month = this.oMonth = parseInt(atmp[1]-1,10);
           this.day = parseInt(atmp[2],10);
           this.year = parseInt(atmp[0],10);
           break;
        }
      } else { // no date set, default to today
        var theDate = new Date();
         this.year = this.oYear = theDate.getFullYear();
         this.month = this.oMonth = theDate.getMonth();
         this.day = this.oDay = theDate.getDate();
      }
      this.writeString(this.buildString());
      
       if (browser.ns4) {
       this.container_dataLayer.hidden=false;
       }
      if (browser.dom || browser.ie4){
          this.container_dataLayer.style.visibility='visible';
      }
    }
    
    Calendar.prototype.hide = function(){
      if (browser.ns4) this.container_dataLayer.hidden = true;
      if (browser.dom || browser.ie4){
        this.container_dataLayer.style.visibility='hidden';
      }
    }
    
    function handleDocumentClick(e){
      if (browser.ie4 || browser.ie5) e = window.event;

      if (browser.ns6){
        var bTest = (e.pageX > parseInt(g_Calendar.container_dataLayer.style.left,10) && e.pageX <  (parseInt(g_Calendar.container_dataLayer.style.left,10)+125) && e.pageY < (parseInt(g_Calendar.container_dataLayer.style.top,10)+125) && e.pageY > parseInt(g_Calendar.container_dataLayer.style.top,10));
        if (e.target.name!='imgCalendar' && e.target.name!='month'  && e.target.name!='year' && e.target.name!='calendar' && !bTest){
          g_Calendar.hide(); 
        }
      }
      if (browser.ie4 || browser.ie5){
        // extra test to see if user clicked inside the calendar but not on a valid date, we don't want it to disappear in this case
       var bTest = (e.x > parseInt(g_Calendar.container_dataLayer.style.left,10) && e.x <  (parseInt(g_Calendar.container_dataLayer.style.left,10)+125) && e.y < (parseInt(g_Calendar.container_dataLayer.style.top,10)+125) && e.y > parseInt(g_Calendar.container_dataLayer.style.top,10));
        if (e.srcElement.name!='imgCalendar' && e.srcElement.name!='month' && e.srcElement.name!='year' && !bTest & typeof(e.srcElement)!='object'){
          g_Calendar.hide(); 
        }
      }
      if (browser.ns4) g_Calendar.hide();
    }
    
    function padZero(num) {
      return ((num <= 9) ? ("0" + num) : num);
    }
      function BetterDate(year,month,day){
        this.date = (arguments.length == 3)?new Date(year,month,day):new Date();
      }
      BetterDate.isLeapYear = function(year){ if (year%4==0 && ((year%100!=0) || (year%400==0))) return true; else return false; }
      BetterDate.daysInYear = function(year){ if (BetterDate.isLeapYear(year)) return 366; else return 365;}
      BetterDate.prototype.addDays = function(numDays){

        var accumulate    = new Array(0,31, 59, 90,120,151,181,212,243,273,304,334);
        var accumulateLY  = new Array(0,31, 60, 91,121,152,182,213,244,274,305,335);
        var year = this.date.getFullYear();
        var month = this.date.getMonth();
        var day = this.date.getDate();
        if (BetterDate.isLeapYear(year)) var number = day + accumulateLY[month] + numDays;
        else var number = day + accumulate[month]   + numDays;
        var days = BetterDate.daysInYear(year);
        while (number > days) {
            number -= days;
            days = BetterDate.daysInYear(++year);
        }
        while (number < 1) {
            days = BetterDate.daysInYear(--year);
            number += days;
        }
        month = 0;
        if (BetterDate.isLeapYear(year)) {
            while (number > accumulateLY[month]) { month++; }
            day = number - accumulateLY[--month];
        }
        else {
            while (number > accumulate[month]) { month++; }
            day = number - accumulate[--month];
        }
        return new Date(year,month,day);
      }     /* end of adaptation */
      
    window.onload=function(){ new Calendar(new Date());}