YAHOO.util.Event.onDOMReady(function() {
  
  YAHOO.util.Connect.asyncRequest('GET', 'feeds/calendar', {success: function(o) {
    
    var Dom = YAHOO.util.Dom,
        Evt = YAHOO.util.Event,
        Con = YAHOO.util.Connect;
    
    var months = ['January','February','March','April','May','June','July','August','September','October','November','December'];
    var data = {};
    var currentMonth, locked = true;
    var calendarFull    = Dom.get('calendar'),
        calendarWrapper = Dom.get('calendar-wrapper'),
        calendarTable   = Dom.get('calendar-table'),
        calendarMonth   = Dom.get('calendar-month'),
        calendarListHdg = Dom.get('calendar-list-heading'),
        calendarList    = Dom.get('calendar-list');
    
    var makeCalendar = function(month) {
      
      calendarMonth.innerHTML = months[parseInt(month.id.substring(4), 10)-1]+' '+month.id.substring(0, 4);
      
      if (currentMonth) calendarTable.removeChild(data[currentMonth].calendar);
      
      var thisMonth = document.createElement('tbody'),
          thisWeek = document.createElement('tr'),
          thisDay, link;
      
      for (var i=0, weekday=0; i<=month.numDays+1; i++) {
        
        thisDay = document.createElement('td');
        
        if (!i) {
          if (month.firstDay) {
            if (month.firstDay > 1) thisDay.colSpan = month.firstDay;
            thisDay.className = 'blank-days';
            weekday = month.firstDay-1;
          } else continue;
        } else if (i > month.numDays) {
          if (weekday) {
            if (weekday < 6) thisDay.colSpan = 7-weekday;
            thisDay.className = 'blank-days';
            weekday = 6;
          } else break;
        } else {
          if (month.events[i]) {
            link = document.createElement('a');
            link.innerHTML = i;
            link.id = 'calendar-day-'+i;
            link.href = '#';
            thisDay.appendChild(link);
            thisDay.className = 'event-day';
          } else {
            thisDay.innerHTML = i;
          }
        }
        
        thisWeek.appendChild(thisDay);
        
        if (weekday == 6) {
          thisMonth.appendChild(thisWeek);
          thisWeek = document.createElement('tr');
          weekday = 0;
        } else weekday++;
      }
      
      month.calendar = thisMonth;
      calendarTable.appendChild(thisMonth);
      currentMonth = month.id;
      locked = false;
      Dom.removeClass(calendarWrapper, 'loading');
    };
    
    var changeMonth = function(year, month) {
      
      month = parseInt(month, 10);
      if (month < 10) month = '0'+month;
      
      if (data[year+''+month]) {
        
        makeCalendar(data[year+''+month]);
        
      } else {
        
        Con.asyncRequest('GET', 'feeds/calendar/'+year+'/'+month, {success: function(o) {
          
          var response = eval("("+o.responseText+")");
          data[response.month.id] = response.month;
          makeCalendar(response.month);
          
        }, failure: function(o) {
          
          locked = false;
          Dom.removeClass(calendarWrapper, 'loading');
          
        }});
      }      
    };
    
    var listEvents = function(day) {
      
      calendarList.innerHTML = '';
      var events, date, datestamp, hour, time, title, link, li;
      
      if (day) {
        calendarListHdg.innerHTML = months[parseInt(currentMonth.substring(4), 10)-1]+' '+day+', '+currentMonth.substring(0, 4);
        events = data[currentMonth].events[day];
      } else {
        calendarListHdg.innerHTML = 'Upcoming Events';
        events = data.upcoming;
      }
      
	  if (!events.length) {
        li = document.createElement('li');
		li.innerHTML = "No upcoming events."
        calendarList.appendChild(li);
	  }
	  
      for (var i=0; i<events.length; i++) {
        hour  = document.createElement('span');
        time  = document.createElement('div');
        title = document.createElement('div');
        link  = document.createElement('a');
        li    = document.createElement('li');
        if (!day) {
          datestamp = events[i].date.split('-');
          date = document.createElement('span');
          date.innerHTML = months[parseInt(datestamp[1], 10)-1]+' '+parseInt(datestamp[2], 10);
          date.className = 'date';
          time.appendChild(date);
        }
        hour.innerHTML = events[i].time;
        hour.className = 'hour';
        time.className = 'time';
        title.innerHTML = events[i].title;
        title.className = 'title';
        link.href = '/calendar/event/'+events[i].id;
        time.appendChild(hour);
        link.appendChild(time);
        link.appendChild(title);
        li.appendChild(link);
        calendarList.appendChild(li);
      }
    };
    
    var response = eval("("+o.responseText+")");
    data[response.month.id] = response.month;
    data.upcoming = response.upcoming;
    
    makeCalendar(response.month);
    listEvents();
    Dom.removeClass(calendarWrapper, 'hidden');
    Dom.removeClass(calendarFull, 'loading');
    
    Evt.addListener('calendar-previous', 'click', function(e) {
      Evt.preventDefault(e);
      if (!locked) {
        
        locked = true;
        Dom.addClass(calendarWrapper, 'loading');
        var year = currentMonth.substring(0, 4),
            month = parseInt(currentMonth.substring(4), 10);
        if (month == 1) {
          month = 12;
          year--;
        } else month--;
        
        changeMonth(year, month);
      }
    });
    
    Evt.addListener('calendar-next', 'click', function(e) {
      Evt.preventDefault(e);
      if (!locked) {
        
        locked = true;
        Dom.addClass(calendarWrapper, 'loading');
        var year = currentMonth.substring(0, 4),
            month = parseInt(currentMonth.substring(4), 10);
        if (month == 12) {
          month = 1;
          year++;
        } else month++;
        
        changeMonth(year, month);
      }
    });
    
    Evt.addListener(calendarTable, 'click', function(e) {
      Evt.preventDefault(e);
      if (!locked) {
        var day = Evt.getTarget(e).id.match(/calendar-day-(\d+)/);
        if (day) listEvents(day[1]);
      }
    });
    
  }, failure: function(o) {
    
  }});
});