var CalendarView = new Class({
  model: false,
  name: false,
  element: false,
  elementId: false,
  shown: false,
  currentDay: false,
  currentMonth: false,
  currentYear: false,
  
  initialize: function ( model )
  {
    this.model = model;
  },
  
  run: function ( name )
  {
    if (!name) return;
    this.name = name;
  },
  
  createAll: function ( element )
  {
    if (element && $(element)) this.element = element;
    if (!this.element) return false;
    if (typeof(this.element) == "object") {
      this.elementId = this.element.id;
    } else {
      this.elementId = this.element;
    }
    
    attachEvent(document, 'click', _callback(this,this.documentClick));
    
    this.createTable();
    this.create();
    this.reload();
    this.repaint();
  },
  
  createTable: function ( )
  {
    if (!this.element) return false;
    
    var table = new Element("table");
    var thead = new Element("thead");
    var tbody = new Element("tbody");
    var tfoot = new Element("tfoot");
    
    var tr = new Element("tr");
    
    var th = new Element("th"); th.innerHTML = "Ma"; tr.appendChild(th);
    var th = new Element("th"); th.innerHTML = "Di"; tr.appendChild(th);
    var th = new Element("th"); th.innerHTML = "Wo"; tr.appendChild(th);
    var th = new Element("th"); th.innerHTML = "Do"; tr.appendChild(th);
    var th = new Element("th"); th.innerHTML = "Vr"; tr.appendChild(th);
    var th = new Element("th"); th.innerHTML = "Za"; tr.appendChild(th);
    var th = new Element("th"); th.innerHTML = "Zo"; tr.appendChild(th);
    
    thead.appendChild(tr);    
    table.appendChild(thead);
    table.appendChild(tbody);
    table.appendChild(tfoot);
    
    $(this.element).appendChild(table);
  },
  
  create: function ( )
  {
    if (!this.element) return false;
    
    var tbody = $(this.element).getElement("tbody");
    var tfoot = $(this.element).getElement("tfoot");
    
    if (tbody.childNodes.length > 0)
      while (tbody.lastChild) tbody.removeChild(tbody.lastChild);
    if (tfoot.childNodes.length > 0)
      while (tfoot.lastChild) tfoot.removeChild(tfoot.lastChild);
    
    for (var rowCount = 0; rowCount < 6; rowCount++) {
      var row = new Element("tr");
      for (var cellCount = 0; cellCount < 7; cellCount++) {
        var currentWeekDay = (cellCount+1)%7;
        var cell = new Element("td");
        if (this.model.settings.highlightDays.indexOf(currentWeekDay) >= 0) {
          cell.setProperties( {"class": 'special'} );
        }
        row.appendChild(cell);
      }
      tbody.appendChild(row);
    }
    
    var row = new Element("tr");
    var cell = new Element("td", {'class': 'month'});
    row.appendChild(cell);
    
    var cell = new Element("td", {'id':this.elementId+'MonthSelect', 'colspan': 5, 'class': 'month'});
    row.appendChild(cell);
    
    var cell = new Element("td", {'class': 'month'});
    row.appendChild(cell);
    tfoot.appendChild(row);
  },
  
  reload: function ( )
  {
    var date = new Date();
    date.setTime(this.model.settings.time*1000);

    if (this.model.date != false) {
      date.setFullYear(this.model.date.substring(6,10));
      date.setMonth(parseInt(this.model.date.substring(3,5),10)-1);
      date.setDate(parseInt(this.model.date.substring(0,2),10));
    }
    
    this.currentDay = date.getDate();
    this.currentMonth = date.getMonth()+1;
    this.currentYear = date.getFullYear();

    if (this.model.date == false) {
      this.model.date = lz(this.currentDay)+"-"+lz(this.currentMonth)+"-"+this.currentYear;
    }
  },
  
  repaint: function ( noReload )
  {
    if ( !noReload ) this.reload();
    if (!this.element) return false;
    var start = true;
    var end = false;
    var day = 1;
    var date = new Date();
    date.setTime(this.model.settings.time*1000);

    var todayDay = date.getDate();
    var todayMonth = date.getMonth()+1;
    var todayYear = date.getFullYear();

    if (this.model.date != false) {
      date.setFullYear( this.model.date.substring(6,10),
                        parseInt(this.model.date.substring(3,5),10)-1,
                        parseInt(this.model.date.substring(0,2),10)    
                        );

      var chosenYear = date.getFullYear();
      var chosenMonth = date.getMonth()+1;
      var chosenDay = date.getDate();
    }

    date.setFullYear(this.currentYear, this.currentMonth-1, day);
    
    var weekDay = date.getDay();
   
    date.setMonth(date.getMonth()+1);
    date.setDate(0);
    var endDay = date.getDate();

    var tbody = $(this.element).getElement("tbody");
    var tfoot = $(this.element).getElement("tfoot");

    var rows = tbody.getElements("tr");
    for (var rowCount = 0; rowCount < rows.length; rowCount++) {
      var row = rows[rowCount];
      var cells = row.getElements("td");
      
      for (var cellCount = 0; cellCount < cells.length; cellCount++) {
        var currentWeekDay = (cellCount+1)%7;
        var cell = cells[cellCount];

        if (start && !end && currentWeekDay == weekDay) start = false;
        
        if (!start && !end) {
          cell.date = lz(day)+"-"+lz(this.currentMonth)+"-"+this.currentYear;
          cell.controller = this.name;
          cell.removeEvents();
          cell.addEvents( {
            'mouseover': function() { $(this).addClass('select'); },
            'mouseout': function() { $(this).removeClass('select'); },
            'click': function() { bs.control[this.controller].switchDate(this.date); }
          });
        }
        
        if (!start && !end && (this.model.settings.weekly_closed.indexOf(currentWeekDay) >= 0 ||
            this.model.settings.sporadic_closed.indexOf(cell.date) >= 0 ||
            (day < todayDay && todayMonth == this.currentMonth && todayYear == this.currentYear) ||
            (this.currentMonth < todayMonth && todayYear == this.currentYear) ||
            (this.currentYear < todayYear))) {
          cell.addClass('closed');
          cell.removeEvents();
        } else if (cell.hasClass('closed')) {
          cell.removeClass('closed');
        }

        if (!start && !end && this.currentDay == day && chosenMonth == this.currentMonth && chosenYear == this.currentYear) {
          if (this.model.settings.weekly_closed.indexOf(currentWeekDay) >= 0 ||
              this.model.settings.sporadic_closed.indexOf(cell.date) >= 0) {
            this.currentDay++;
            cell.removeClass('current');
          } else {
            cell.addClass('current');
            this.model.date = lz(this.currentDay)+"-"+lz(this.currentMonth)+"-"+this.currentYear;
            $("date").value = this.model.date;
          }
        } else if (cell.hasClass('current')) {
          cell.removeClass('current');
        }
        
        cell.innerHTML = (start||end?"&nbsp;":lz(day));
        if (!start && !end) day++;
        if (day > endDay) end = true;
      }
    }
    
    var row = tfoot.getElement("tr");
    var cells = row.getElements("td");
    
    cells[0].innerHTML = "&lt;";
    cells[0].date = lz((this.currentMonth+10)%12+1)+"-"+(this.currentYear-(this.currentMonth-2 < 0?1:0));
    cells[0].viewer = this.name;
    cells[0].removeEvents();
    cells[0].addEvents({
      'mouseover': function() { $(this).addClass('select'); },
      'mouseout': function() { $(this).removeClass('select'); },
      'click': function () { bs.view[this.viewer].switchMonth( this.date ); }
    });
    
    if (cells[1].hasClass('select')) cells[1].removeClass('select');
    cells[1].viewer = this.name;
    cells[1].removeEvents();
    cells[1].addEvents({
      'mouseover': function() { $(this).addClass('select'); },
      'mouseout': function() { $(this).removeClass('select'); },
      'click': function () { bs.view[this.viewer].showMonthSelect(); }
    });
    cells[1].innerHTML = this.model.settings.monthsNL[this.currentMonth]+" "+this.currentYear;
    cells[1].appendChild(this.createMonthSelect());
    
    cells[2].innerHTML = "&gt;";
    cells[2].date = lz((this.currentMonth%12)+1)+"-"+(this.currentYear+(this.currentMonth+1 > 12?1:0));
    cells[2].viewer = this.name;
    cells[2].removeEvents();
    cells[2].addEvents({
      'mouseover': function() { $(this).addClass('select'); },
      'mouseout': function() { $(this).removeClass('select'); },
      'click': function () { bs.view[this.viewer].switchMonth( this.date ); }
    });
  },
  
  createMonthSelect: function() 
  {
    var monthContainer = new Element("div", {
      'styles': { 'display': 'none' }, 
      'id': this.elementId+'MonthContainer',
      'class': 'monthContainer'
    });
    var monthSelect = new Element("div");
    var startMonth = (this.currentMonth-6+12)%12;
    
    monthSelect.empty();
    var curYear = this.currentYear - ((this.currentMonth-6)<0?1:0);
    for (var curMonth = startMonth; curMonth < startMonth+12; curMonth++) {
      var month = new Element("span");
      if (curMonth%12 == this.currentMonth-1) {
        month.addClass('select');
      } else {
        month.addEvents({
          'mouseover': function() { $(this).addClass('select'); },
          'mouseout': function() { $(this).removeClass('select'); }
        });
      }
      if (curMonth%12 == 0 && startMonth != curMonth) curYear++; 
      
      month.date = lz(curMonth%12+1)+"-"+curYear;
      month.viewer = this.name;
      month.addEvents({
        'click': function() { bs.view[this.viewer].switchMonth( this.date ); }
      });
      month.innerHTML = this.model.settings.monthsNL[curMonth%12 + 1] + " "+curYear;
      monthSelect.appendChild(month);
    }
    
    monthContainer.appendChild(monthSelect);
    return monthContainer;
  },
  
  showMonthSelect: function ( )
  {
    var container = $(this.elementId+"MonthContainer");
    
    container.style.opacity = "0";
    container.style.display = "";
    $(this.elementId+"MonthSelect").removeEvents('click');
    var fadeIn = new Fx.Style(container, 'opacity',{duration:500});
    fadeIn.start(0,1);
    this.shown = true;
  },
  
  hideMonthSelect: function ( )
  {
    var me = this;
    var container = $(this.elementId+"MonthContainer");
    
    $(this.elementId+"MonthSelect").viewer = this.name;
    var fadeOut = new Fx.Style(container, 'opacity', {
      duration:500,
      onComplete: function() {
        container.style.display = "none";
        $(me.elementId+"MonthSelect").addEvent('click', function () { bs.view[this.viewer].showMonthSelect(); });
      }
    });
    fadeOut.start(1,0);
    this.shown = false;
  },
  
  switchMonth: function ( date )
  {
    this.hideMonthSelect();
    
    month = parseInt(date.substring(0,2),10);
    year = parseInt(date.substring(3),10);
    
    this.currentMonth = month;   
    this.currentYear = year;
    this.repaint(true);
  },
  
  documentClick: function ( event )
  {
    var target;
    if (!event) {
      var event = window.event;
      target = event.srcElement;
    } else {
      target = event.target;
    }
    
    if (this.shown && target.id != this.elementId+"MonthSelect") this.hideMonthSelect();
  }  
});

