//   ___    ___
//  / _ \  / _ \          (c)2007 Michal Gebauer aka MiSHAK 00_.
//  || ||  || ||          http://www.mishak.net
//  ||_||  ||_||     _    License: volně k použití, ale nechejte 
//  \___/  \___/    / \            copyright na pokoji !!!
//     ____________ \_/
//    |____________|      Pokud mě chcete obdarovat, nebudu se bránit.

// Třída Calendar
function Calendar()
{
 // cesta ke skriptu
 this.path = '';

 // ID prvku do ktereho se má vložit kalendář
 this.parentCtg = '';

 // jména měsíců
 this.months = ['leden', 'únor', 'březen', 'duben', 'květen', 'červen', 'červenec', 'srpen', 'září', 'říjen', 'listopad', 'prosinec'];
 // jména dní (od neděle)
 this.days = ['ne', 'po', 'út', 'st', 'čt', 'pá', 'so'];
 // první den
 this.dayStart = 1;
 this.showDayNames = true;
 this.showPrevNextMonthDays = false;
 this.showPrevNextMonthDaysClickable = false;

 // kolikátého to dneska máme?
 var date = new Date();
 this.date = {year: date.getFullYear(), month: date.getMonth(), day: date.getDate()}
 this.year = this.date.year;
 this.month = this.date.month;

 // První a poslední měsíc {month: mesic, year: rok}
 this.begin = null;
 this.end = {month: this.month, year: this.year};

 // ovládací prvky
 this.ctrlNext = null;
 this.ctrlPrev = null;
 this.ctrlMonthName = null;
 this.ctrlYear = null;
 
 // Kontejnery
 this.ctg = null;
 this.ctgInfo = null;
 this.caption = null;

 // Vlastni hodnoty - N E Š A H A T
 this.normalStyle = '';
 this.daysCache = [];
 this.monthStart = 0;
 
 this.id = 'calendar-' + Calendar.calendars.length + 1 + '';
 Calendar.calendars.push(this);
}

Calendar.calendars = [];

Calendar.get = function (id)
{
 for(var i = 0; i < this.calendars.length; i++)
  if(this.calendars[i].id === id)
   return this.calendars[i];
}

 // Netřeba popisovat X-D
Calendar.error = function(xml, error, exception)
{
 alert("Omlouvám se, kalendář nefunguje.\nNejspíše chyba v komunikaci se serverem nebo v XML.\n" + error);
}

// Zjištění počtu dní v měsíci (!!! 0..11 !!!)
Calendar.getDayCount = function(m, y)
{
 return((m==3)||(m==5)||(m==8)||(m==10))?30:(m!=1?31:(y%4&&(y%100&&!(y%400))?29:28));
}

// Načtení XMLka měsíce
Calendar.parseXML = function(xml)
{
 var calendar = Calendar.get(this.url.substr(this.url.lastIndexOf('calendar=') + 9));
 calendar.daysCache = [];

 var days = $('day', xml);
 var cells = $(calendar.ctg).find('tbody').find('td');
 // Přečteme dny
 for(var i = 0; i < days.length; i++) {
  var
   day = days[i],
   date = parseInt($(day).attr('date')),
   cell = cells[date + calendar.monthStart - 2];

  calendar.daysCache[date] = day;
  $(cell).text('');
  $('<a>').attr({href: '#'+ calendar.year + '-' + (calendar.month > 9 ? calendar.month + 1 : '0' + (calendar.month + 1)) + '-' + (date > 10 ? date : '0' + date), calendar: calendar.id}).appendTo(cell).bind('click', Calendar.loadDate).text(date + '');
 }
}

// Načtení kalendáře
Calendar.prototype.load = function()
{
 var
  date = new Date(this.year, this.month, 1, 0, 0, 0, 0),
  dayCount = Calendar.getDayCount(this.month, this.year);
 
 $(this.ctrlNext).removeAttr('href').unbind('click').addClass('disabled');
 $(this.ctrlPrev).removeAttr('href').unbind('click').addClass('disabled');
 
 this.monthStart = (date.getDay() + 7 - this.dayStart) % 7 + this.dayStart;
 if (this.monthStart + dayCount < 35) this.monthStart += 7;
  
 var prevMonthDayCount = Calendar.getDayCount(this.month > 0 ? this.month - 1 : 12, this.month > 0 ? this.year : this.year - 1);
 
 $(this.ctrlMonthName).text(this.months[this.month]);
 $(this.ctrlYear).text(this.year + '');
 
 this.removeInfo();

 var
  isActualMonth = this.date.year == this.year && this.date.month == this.month,
  tBody = $('<tbody>'),
  day = 0,
  tr;

 for(var h = 1; h <= 42; h++) {
  var Class = [];
  if(h % 7 == this.dayStart)
   tr = $('<tr>').appendTo(tBody);
  var td = $('<td>').attr('calendar', this.id).appendTo(tr ? tr : $('<tr>').appendTo(tBody));

  if(h % 7 == 0 || h % 7 == 6) Class.push('weekend');

  if(h >= this.monthStart && day < dayCount){
   day++;
   if (h % 7 == 1) Class.push('firstDayOfWeek');
   if (h % 7 == 0) Class.push('lastDayOfWeek');

   if (day == dayCount) Class.push('lastDayOfMonth');
   if (day == 1) Class.push('firstDayOfMonth');
   if (day < 8) Class.push('first7Days');
   if (day > dayCount - 7) Class.push('last7Days');

   if(isActualMonth && this.date.day == day) Class.push('today');

   td.text(day + '');
  } else if(this.showPrevNextMonthDays) {
   td.calendar = this;
   if(h < this.monthStart) {
    if(this.showPrevNextMonthDaysClickable) { 
     td.text(prevMonthDayCount - this.monthStart + h + 1 + '').bind('click', Calendar.prevMonth);
    }
    Class.push('prevmonth');
   } else {
    day++;
    td.text(day - dayCount + '');
    if (this.showPrevNextMonthDaysClickable && !isActualMonth)
     td.bind('click', Calendar.nextMonth);
    Class.push('nextmonth');
   }
  }
  td.addClass(Class.join(' '));
 }

 $('tbody', this.ctg).remove();
 $('thead', this.ctg).after(tBody);

 if(this.begin && !(this.begin.year == this.year && this.begin.month == this.month))
  $(this.ctrlPrev).attr('href', '#').bind('click', Calendar.prevMonth).removeClass('disabled');

 if(this.end && !(this.end.year == this.year && this.end.month == this.month))
  $(this.ctrlNext).attr('href', '#').bind('click', Calendar.nextMonth).removeClass('disabled');

 $.ajax({
  type: "GET",
  url: this.path,

  data: {year: this.year, month: this.month + 1, calendar: this.id},
  dataType: "xml",
  global: false,

  success: Calendar.parseXML,
  error: Calendar.error
 });
}

Calendar.prototype.removeInfo = function()
{
 if(!this.ctgInfo) return;
 $(this.ctgInfo).remove();
 this.ctgInfo = null;
}

// U D Á L O S T I -- E V E N T S
// Předchozí měsíc
Calendar.prevMonth = function(event)
{
 var calendar = Calendar.get($(this).attr('calendar'));
 if(!calendar.month) {
  calendar.month = 11;
  calendar.year--;
 } else {
  calendar.month--;
 }
 calendar.load();
 event.preventDefault();
}

// Následující měsíc
Calendar.nextMonth = function(event)
{
 var calendar = Calendar.get($(this).attr('calendar'));
 if(calendar.month == 11) {
  calendar.month = 0;
  calendar.year++;
 } else {
  calendar.month++;
 }
 calendar.load();
 event.preventDefault();
}

// "Zavře" informace o dnu
Calendar.closeInfo = function(event)
{
 var calendar = Calendar.get($(this).attr('calendar'));
 calendar.removeInfo();

 event.preventDefault();
}

// Zobrazení informací o dnu (podle ovládacího prvku)
Calendar.loadDate = function(event)
{
 var calendar = Calendar.get($(this).attr('calendar'));
 calendar.removeInfo();

 calendar.ctgInfo = $('<div>').addClass('calendarinfo');
 var
  date = $(this).text();
  day = calendar.daysCache[date];
 (h2 = $('<h2>').appendTo(calendar.ctgInfo)).text(date + '. ' + calendar.months[calendar.month] + ' ');

 $('<a>').appendTo(h2).attr({href: "#", title: "Zavřít", calendar: calendar.id}).bind('click', Calendar.closeInfo).text('zavřít');

 var articles = day.getElementsByTagName('article');
 for(var i = 0; i < articles.length; i++) {
  var article = articles[i];
   title = $('title', article).text(),
   h3 = $('<h3>').appendTo(calendar.ctgInfo);

  $('<a>').appendTo(h3).attr({href: $(article).attr('url'), title: 'Přejít na článek ' + title}).text(title);
  $('<p>').appendTo(calendar.ctgInfo).text($('perex', article).text());
 }

 $(calendar.ctg).after(calendar.ctgInfo);
 event.preventDefault();
}

// Inicializavání objektu, co jiného...
Calendar.prototype.init = function() 
{
 if(this.ctg) return;

 this.ctg = $('<table><caption>Kalendář</caption></table>').attr("summary", "kalendář článků").addClass('calendar');
 this.caption = $('caption', this.ctg);
  
 var 
  thead = $('<thead>').appendTo(this.ctg),
  tr = $('<tr>').appendTo(thead);

 (this.ctrlPrev = $('<a>').attr({href: "#", title: "Předchozí měsíc", calendar: this.id}).appendTo($('<td>').appendTo(tr))).text("\xAB\xAB");
 this.ctrlMonthName = $('<td>').attr("colSpan", "3").appendTo(tr);
 this.ctrlYear = $('<td>').attr("colSpan", "2").appendTo(tr);
 (this.ctrlNext = $('<a>').attr({href: "#", title: "Následující měsíc", calendar: this.id}).appendTo($('<td>').appendTo(tr))).text("\xBB\xBB");
  
 tr = $('<tr>').appendTo(thead);
 if(this.showDayNames)
  for(var i = this.dayStart; i < this.dayStart + 7; i++)
   $('<td>').addClass('dayname' + (i%7==0||i%7==6 ? ' weekend' : '')).appendTo(tr).text(this.days[i < 7 ? i : i - 7]);

 var tbody = $('<tbody>').appendTo(this.ctg);
 $(this.ctg).appendTo($(this.parentCtg).get(0));
 this.normalStyle = 'table';
 this.load();
};

// Tak a teď si vytvoříme kalendář :)
var calendar = new Calendar();

$(document).ready(function(){
 // Adresa k PHP skriptu
 calendar.path = location.protocol +'//'+ location.host +'/blog/calendar-flusher.php';
 // Prvek kam příjde kalendář
 calendar.parentCtg = '#calendar';

 calendar.showPrevNextMonthDays = true;
 calendar.showPrevNextMonthDaysClickable = true;

 calendar.begin = {month: 3, year: 2006};
 calendar.init();
});
