/*
  Copyright 2010 Nick Boughton <nb5@sanger.ac.uk, nicholasboughton@googlemail.com>
        
  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 3 of the License, or
  (at your option) any later version.
        
  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
  http://www.gnu.org/licenses/gpl.html
*/

$(document).ready(function() {
  // jsonSrc is defined in calendar_global_defs.js
  $.getJSON(jsonSrc, function(data) { 
    var now            = new Date();
    var globalFullYear = now.getFullYear();
    var globalMonth    = now.getMonth();
    
    // make sure the dates are parsed as ints properly. All event items MUST 
    // contain the following fields: startDay, startMonth, startYear
    $.each(data, function(i, item) {
      if(i.match(/^\d+/)) {
      // ensure these are interpreted as numbers rather than strings.
        item.startYear     = parseInt(item.startYear);
        item.startMonth    = parseInt(item.startMonth);
        item.startDay      = parseInt(item.startDay);
        item.endYear       = parseInt(item.endYear);
        item.endMonth      = parseInt(item.endMonth);
        item.endDay        = parseInt(item.endDay);
      }
    });
  
    // Draw the calendar and attach the necessary .click methods
    function drawCalendar() {
      var today = new Date();
      // for our purposes we are always dealing with the first day of the month
      today.setDate(1);
      // if year and date aren't defined then we're dealing with the current month/year
      switch ($(this).attr('id')) {
        case 'monthBack':
          today.setMonth( (globalMonth - 1) );
          today.setYear( globalFullYear );
          globalMonth--;
  	break;
        case 'monthForward':
          today.setMonth( (globalMonth + 1) );
          today.setYear( globalFullYear );
          globalMonth++;
  	break;
        case 'yearBack':
          today.setYear( (globalFullYear - 1) );
          today.setMonth( globalMonth );
          globalFullYear--;
  	break;
        case 'yearForward':
          today.setYear( (globalFullYear + 1) );
          today.setMonth( globalMonth );
          globalFullYear++;
  	break;
        case 'calFooter':
          var newDate = new Date();
          today.setFullYear( newDate.getFullYear() );
          globalFullYear = newDate.getFullYear();
          today.setMonth( newDate.getMonth() );
          globalMonth = newDate.getMonth();
      }
      
      // Start building the calendar display code
      var calendarHtml = new String();
      
      // Adjust for leap years with this crude check
      if( today.getMonth() == 1 && today.getFullYear() % 1000 != 0 && today.getFullYear() % 4 == 0 ) {
        daysInMonth[1]++;
      }
  
      // Create the calendar table header
      calendarHtml += '<table id="calendarTable" cellspacing="0">';
      calendarHtml += '  <tr>';
      calendarHtml += '    <td class="calHeader" id="yearBack">&nbsp;&lt;&lt;</td>';
      calendarHtml += '    <td class="calHeader" id="monthBack">&lt;</td>';
      calendarHtml += '    <td class="calHeader" colspan="3"><b>' + month[today.getMonth()].substr(0, 3) + '&nbsp;&nbsp;' + today.getFullYear() + '</b></td>';
      calendarHtml += '    <td class="calHeader" id="monthForward">&gt;</td>';
      calendarHtml += '    <td class="calHeader" id="yearForward">&gt;&gt;&nbsp;</td>';
      calendarHtml += '  </tr>';
      calendarHtml += '  <tr>';
      for( var i = 0; i < week.length; i++ ) { 
        calendarHtml += '    <td>' + week[i].substr(0, 3) + '</td>';
      }
      calendarHtml += '  </tr>';
     
      /* 
       * every cell must have a class="day" and an id for its day number that way we can then run
       * checkEvents next and hilight days with events. All days will have an onclick bind event
       * attached to them but the function needs to be able to process and print multiple events
       * for any given day. Also I'm well aware that the indentation is unnecessary but I like it.
       */
      var firstDay = today.getDay();
      for( var i = 0; i < daysInMonth[today.getMonth()]; i++ ) {
        calendarHtml += '  <tr>'
        for( var j = 0; j < 7; j++ ) {
          if( i < firstDay || i >= daysInMonth[today.getMonth()] ) {
            calendarHtml += '    <td />';
  	  firstDay--;
          } else {
  	  i++;
            calendarHtml += '    <td class="noEvent day" id="' + i + '">' + i + '</td>';
          }
        }
        i--; 
        calendarHtml += '  </tr>';
      }
      calendarHtml += ' <tr><td colspan="7" id="calFooter">Return to Current Month</td></tr>';
      calendarHtml += '</table>';
      
      // Overwrite whatevers currently drawn 
      $('#calendar').html(calendarHtml);
  
      // Hilight and bind the days on which events occur
      checkEvents();
      $('.noEvent').click(noEvents);
      $('.calHeader').click(drawCalendar);
      $('#calFooter').click(drawCalendar);
    }
   
    /*
     * checkEvents is very limited in its scope, it merely has to add an extra class of 'hilight' and bind a click event to the cell
     */
    function checkEvents() {
      $.each(data, function(i, item) {
        if(i.match(/^\d+/)) {
          var limit;
          if( (item.startMonth - 1) == globalMonth && item.startYear == globalFullYear ) {
            if( (item.endMonth - 1) == (item.startMonth - 1) ) { 
              limit = item.endDay; 
            } else if( (item.endMonth - 1) != (item.startMonth - 1) ) { 
              limit = daysInMonth[item.startMonth - 1];
            }
  	  
            for( var j = item.startDay; j <= limit; j++ ) {
              var selector = '#' + j;
              if( !$(selector).hasClass('calHilighted') ) {
  	      $(selector).removeClass('noEvent');
                $(selector).addClass('calHilighted');
                $(selector).click(printEvents);
              }
            }
          }
	}
      });
    }
  
    function noEvents() {
      $(outputDiv).html('<div id="outputContainer">No events listed for this day<br /></div>');
    }

    function printEvents() {
      var generatedHtml = '<div id="outputContainer">';
      var day           = $(this).attr('id');
      outputList        = new Array();
      $.each(data, function(i, item) {
        if(i.match(/^\d+/)) {
          var limit;
          if( (item.endMonth - 1) == (item.startMonth - 1) ) { 
            limit = item.endDay; 
          } else if ( (item.endMonth - 1) != (item.startMonth - 1) ) { 
            limit = daysInMonth[(item.startMonth - 1)]; 
          }
          for( var j = item.startDay; j <= limit; j++ ) {
            if( j == day && (item.startMonth - 1) == globalMonth ) {
    	    // generateOutputHtml is provided by calendar_output.js file
  	    var text = generateOutputHtml(item);
  	    outputList.push(text);
            }
          }
	}
      });
      outputList.sort();
      for(var c = 0; c < outputList.length; c++) {
        generatedHtml += outputList[c];
      }
      generatedHtml += '</div>';
      // outputDiv is set in calendar_global_defs.js and defaults to #content
      $(outputDiv).hide();
      $(outputDiv).text('');
      $(outputDiv).html(generatedHtml);
      $(outputDiv).fadeIn();
    }
    
    // Finally call the initial draw
    drawCalendar();
  });
});
