TMonthCalendar = function (container, y, m, startday) {
  var now = new Date();
  this.m = parseInt(m);
  this.y = parseInt(y);
  this.m = isNaN(m) ? now.getMonth()+1 : m;
  this.y = isNaN(y) ? now.getFullYear() : y;
  this.startday = startday || 0;

  var date = new Date(this.y,this.m-1,1);
  this.day_of_week = date.getDay();
  date.setMonth(date.getMonth()+1);
  date.setDate(0);
  this.days_in_month = date.getDate();

  this.selected = {from:-1,to:-1};
  this.container = TDOM.getElement(container);
  this.invalidate();
}

TMonthCalendar.inherits(TEventDispatcher);
TMonthCalendar.days = ['Do','Lu','Ma','Mi','Ju','Vi','Sa'];
TMonthCalendar.months = ['Enero','Febrero','Marzo','Abril','Mayo','Junio','Julio','Agosto','Septiembre','Octubre','Noviembre','Diciembre'];

TMonthCalendar.prototype.select = function(from, to) {
  var fromd = -1, tod = -1;
  if (from && to) {
    if (this.y >= from.getFullYear()) {
      if (this.y == from.getFullYear()) {
        if (this.m >= from.getMonth()+1) {
          fromd = this.m == from.getMonth()+1 ? from.getDate() : 1;
        }
      } else {
        fromd = 1;
      }
    }
    if (this.y <= to.getFullYear()) {
      if (this.y == to.getFullYear()) {
        if (this.m <= to.getMonth()+1) {
          tod = this.m == to.getMonth()+1 ? to.getDate() : this.days_in_month;
        }
      } else {
        tod = this.days_in_month;
      }
    }
  }
  fromd < 1 || tod < 1 ? this.clearSelection() : this._setSelected(fromd,tod);
}

TMonthCalendar.prototype.clearSelection = function() {
  this._setSelected(-1,-1);
}

TMonthCalendar.prototype._setSelected = function(from, to) {
  if (from != this.selected.from || to != this.selected.to) {
    this.selected.from = from;
    this.selected.to = to;
    this.invalidate();
  }
}

TMonthCalendar.prototype.dayClick = function(e) {
  var day = parseInt(e.currentTarget.innerHTML);
  this.dispatch('change',this.y,this.m,day);
}

TMonthCalendar.prototype.invalidate = function() {
  var now = new Date();
  var cal = document.createElement('div');
  cal.className = "month y' + this.y + ' m' + this.m + '";
  while (this.container.childNodes.length > 0) {
    this.container.removeChild(this.container.childNodes[0]);
  }

  var node = document.createElement('div');
  node.className = 'title';
  node.appendChild(document.createTextNode(TMonthCalendar.months[this.m-1] + ' ' + this.y));
  cal.appendChild(node);

  var weeks = document.createElement('div');
  weeks.className = 'weeks';
  cal.appendChild(weeks);

  var week = document.createElement('div');
  week.className = 'week w0';
  weeks.appendChild(week);

  for (var i=0; i < 7; i++) {
    node = document.createElement('div');
    node.className = 'dayname';
    node.appendChild(document.createTextNode(TMonthCalendar.days[(i+this.startday)%7]));
    week.appendChild(node);
  }

  var day = 0;
  var dow = this.day_of_week-this.startday;
  dow = dow < 0 ? 7+dow : (dow == 0 ? 7 : dow);
  for (var w=0; w < 6; w++) {
    week = document.createElement('div');
    week.className = 'week w'+(w+1);
    weeks.appendChild(week);

    for (var d=0; d <= 6; d++) {
      if (dow > 0 || day >= this.days_in_month) {
        node = document.createElement('div');
        node.className = 'day empty';
        week.appendChild(node);
        dow--;
      } else {
        day++;
        var style = ['day'];
        if (this.y >= now.getFullYear()) {
          if (this.y == now.getFullYear()) {
            if (now.getMonth() > this.m-1) {
              style.push('past');
            } else
            if (now.getMonth() == this.m-1) {
              if (now.getDate() == day) {
                style.push('today');
              } else
              if (now.getDate() > day) {
                style.push('past');
              }
            }
          }
        } else {
          style.push('past');
        }
        var diw = d+this.startday;
        if (day >= this.selected.from && day <= this.selected.to) {
          var single = false;
          style.push('selected');
          if (this.selected.from != this.selected.to) {
            if (day == this.selected.from || d == 0) {
              single = true;
              style.push('selstart');
            }
            if (day == this.selected.to || d == 6) {
              style.push(single ? 'selone' : 'selend');
            }
          } else {
            style.push('selone');
          }
        }
        if (diw%6 == 0 || diw%7 == 0) {
          style.push('weekend');
        }
        var daysn = document.createElement('div');
        daysn.className = style.join(' ');
        var wrapn = document.createElement('div');
        daysn.appendChild(wrapn);
        var linkn = document.createElement('a');
        linkn.appendChild(document.createTextNode(day));
        linkn.href = 'javascript:void(0)';
        TEvents.listen(linkn,'click',this.dayClick,this);
        wrapn.appendChild(linkn);
        week.appendChild(daysn);
      }
    }
  }
  this.container.appendChild(cal);
  this.size = TDOM.getSize(this.container);
}
