// calendar box
function CalendarBox() {
 this.boxid = '#calendarBox'+CalendarBox.uId;
 this.id =  CalendarBox.uId; 
 this.localDate = new Date();
 this.oldDate = null;
 this.localConf = null;
 this.localObject = null;
 var temp = $.template('<div class="calendarBox" id="${boxId}" style="display: none;"></div><div class="calendarShadow" id="calendarShadow${uid}" style="display: none;"></div>');
 $('body').append(temp,{uid: this.id, boxId: this.boxid.replace(/#/,'')});
 CalendarBox.uId += 1;
 obj = this;
 $('#calendarShadow'+this.id).click(function(){ obj.close();});
 $(this.boxid).data('calendarConf', this);  
 this.tableTemplate = $.template('<table cellpadding="0" cellspacing="0"><tr class="calendarFirstLine"><td class="calendarArrowL">${ArrowL}</td><th colspan="5">${Year}</th><td class="calendarArrowR">${ArrowR}</td></tr><tr class="calendarHead"><td>${H1}</td><td>${H2}</td><td>${H3}</td><td>${H4}</td><td>${H5}</td><td>${H6}</td><td>${H7}</td></tr><tr class="calendarLine"><td>${I1}</td><td>${I2}</td><td>${I3}</td><td>${I4}</td><td>${I5}</td><td>${I6}</td><td>${I7}</td></tr><tr class="calendarLine"><td>${I8}</td><td>${I9}</td><td>${I10}</td><td>${I11}</td><td>${I12}</td><td>${I13}</td><td>${I14}</td></tr><tr class="calendarLine"><td>${I15}</td><td>${I16}</td><td>${I17}</td><td>${I18}</td><td>${I19}</td><td>${I20}</td><td>${I21}</td></tr><tr class="calendarLine"><td>${I22}</td><td>${I23}</td><td>${I24}</td><td>${I25}</td><td>${I26}</td><td>${I27}</td><td>${I28}</td></tr><tr class="calendarLine"><td>${I29}</td><td>${I30}</td><td>${I31}</td><td>${I32}</td><td>${I33}</td><td>${I34}</td><td>${I35}</td></tr><tr class="calendarLine"><td>${I36}</td><td>${I37}</td><td>${I38}</td><td>${I39}</td><td>${I40}</td><td>${I41}</td><td>${I42}</td></tr></table>');  
} 

CalendarBox.prototype.show = function(object) {
 if(object == null) return false;
 this.localObject = object;
 this.localConf = object.data('calendarConf');  
 var positionA =  object.offset(); //object.cumulativeOffset();
 var positionR =  {left:0, top:0}; //object.viewportOffset();
 var panel = this.localConf.get('panelToDisplay');
 var windowSize = getPageSize();  
 var x,y;
 var eopen = 'SlideDown';
 if(panel==null) {
	 x = positionA.left;
	 y = positionA.top + object.height() + 5;  
	 // vypocet dynamicke pozice boxu
	 if(this.localConf.get('dynamicPositionBox')) {    
	  if(windowSize[3]-(positionR.top+$(this.boxid).height()+object.height())<0) {  // nastaveni Top   
	   y -= object.height()+$(this.boxid).height();            
	  }
	  if(windowSize[2]-(positionR.left+$(this.boxid).width())<0) {  // nastaveni Left
	   x -= $(this.boxid).width();
	   x += object.width();
	  }
	 }   
	 $(this.boxid).css({top: y+'px', left: x+'px'}); 
 }else{
	 $(this.boxid).appendTo(panel);
 }
 /*
 if(Prototype.Browser.IE) {
  hideSelectBoxes(); hideFlash();
 } 
 */  
 if(!this.localDate.parseByTemplate(object.val(),this.localConf.get('dateFormat'))) {     
  this.localDate = new Date();
  this.oldDate = null;
 }else{  
  this.oldDate = new Date(this.localDate);
 } 
 // Generovani tabulky 
 this.generateTable();
 // zobrazeni kalendare
 if(panel==null) {
	 $('#calendarShadow'+this.id).height(windowSize[1]).show();
 }	 
 $(this.boxid).show();   
}

CalendarBox.uId = 1;

CalendarBox.prototype.testFormatDate = function(date) {
 if(date==null || date.length==0) return true;
 var tmpDate = new Date();
 var rr = tmpDate.parseByTemplate(date,this.localConf.get('dateFormat'));
 if(rr<0) {
  alert(this.localConf.getTrans('errorBadFormat'));
  this.localObject.focus();
  return false;
 }  
 tmpDate.setUTCHours(23,59,59,999);
  // test limitu 
  if(rr==0 ||
     (this.localConf.get('limitFrom')!=null && tmpDate.getTime()-this.localConf.get('limitFrom').getTime()<0) ||
     (this.localConf.get('limitTo')!=null && this.localConf.get('limitTo').getTime()-tmpDate.getTime()<0)){
   alert(this.localConf.getTrans('errorOutRange'));   
   return false;
  } 
 return true;  
}

CalendarBox.prototype.close = function(parm) {
 if(!this.testFormatDate(this.localObject.value)) {
  if(parm==null) {
   this.localObject.focus();
  } 
  return false;
 } 
 $(this.boxid).hide();
 /*
 if(Prototype.Browser.IE) {
  showSelectBoxes(); showFlash();
 } 
 */ 
 $('#calendarShadow'+this.id).hide(); 
 this.localObject = null;
 this.localConf = null;
 return true; 
}

CalendarBox.prototype.generateTable = function() { 

 function testOfWeek(num) {
  if(num%7==0 || (num+1)%7==0) {
   return true; 
  }
  return false;
 }

 function testSelectDate(day,date) {
  if(typeof date != 'object' || date == null) return false;
  return (
   date.getUTCDate()-day ==0 &&
   date.getUTCFullYear()-dateActual.getUTCFullYear() == 0 &&
   date.getUTCMonth()-dateActual.getUTCMonth() == 0);
 }

 var option = {};
 dateActual = new Date(this.localDate); // Aktualni datum
 dateLim = new Date(this.localDate); // Datum pro testovani limitu
 dateFirst =  new Date(this.localDate); // 1. v mesici
 dateFirst.setUTCDate(1);  
 datePrev = new Date(this.localDate);   // Predchozi mesic
 datePrev.changeMonth(-1);  
 
 borderActual = dateActual.getDayBorders();
 fDay = this.localConf.get('firstDayOfWeek');    
 for(var j=1; j<8; j++) {
  var l = fDay+j;
  if(l>7) l-=7;
  option['H'+j] = this.localConf.getTrans('d'+(l-1));
 }
 // Uprava vzhledem k prvnimu radku, aby byl vzdy zobrazen  
 if(borderActual[0]-fDay<0) {
  fDay -= 7;
 } 
 var counterWeek = borderActual[0]; 
 // Aktualni vypis mesice 
 var dateNow = new Date();
 // Limit From
 var limFromDate =  this.localConf.get('limitFrom');
 // limit To
 var limToDate =  this.localConf.get('limitTo');
 // pomocne prom
 var onclick; 
 var dateUTC;
  
 for(var i=1; i<=dateActual.getMonthLength(); i++) {
  // Zjistujeme zda je svatek 
  var holl = this.localConf.getHoliday(dateFirst.dateInYear()-1+i,dateFirst.getUTCFullYear());
  // Nastavujeme udalost kliknuti 
  onclick = 'onclick="$(\''+this.boxid+'\').data(\'calendarConf\').selectDay('+i+',0);"';
  // Vypocet aktualniho Time stamp pro zjisteni zda jsme v intervalu limitu
  dateUTC = Date.UTC(dateLim.getUTCFullYear(),dateLim.getUTCMonth(),i,23,59,59,999);
  // test limitu 
  if((limFromDate!=null && dateUTC-limFromDate.getTime()<0) ||
     (limToDate!=null && limToDate.getTime()-dateUTC<0)){
   onclick = '';
  } 
  option['I'+(i+borderActual[0]-fDay)] = 
   '<div class="calendarLink calendarActiveMonth '+
    (testOfWeek(counterWeek) || holl[1]>0?'calendarWeekDay ':'')+
    (testSelectDate(i,dateNow)?'calendarToday ':'')+
    (testSelectDate(i,this.oldDate)?'calendarSelectDay ':'')+ 
    (onclick==''?'calendarNoLink ':'')+   
   '" '+onclick+' title="'+
   (holl[0]!=null?holl[0]:'')+
   '">'+i+'</div>';
  counterWeek += 1;
 }
  
 // Vypis nasledujiciho mesice
 dateLim.changeMonth(1);
 var startMonth = 1; 
 for(var i=borderActual[0]+dateActual.getMonthLength()+1-fDay; i<=60; i++) {
  // Nastavujeme udalost kliknuti
  onclick = 'onclick="$(\''+this.boxid+'\').calendar.selectDay('+startMonth+',1);"';
  // Vypocet aktualniho Time stamp pro zjisteni zda jsme v intervalu limitu   
  dateUTC = Date.UTC(dateLim.getUTCFullYear(),dateLim.getUTCMonth(),startMonth,23,59,59,999);
  // test limitu 
  if((limFromDate!=null && dateUTC-limFromDate.getTime()<0) ||
     (limToDate!=null && limToDate.getTime()-dateUTC<0)){
   onclick = '';
  } 
  option['I'+i] = 
   '<div class="calendarLink calendarPassiveMonth '+
    (testOfWeek(counterWeek)?'calendarWeekDay ':'')+
    (onclick==''?'calendarNoLink ':'')+
   '" '+onclick+'>'+startMonth+'</div>';
  startMonth += 1;
  counterWeek += 1;
 }
 
 // Vypis predchoziho mesice
 dateLim.changeMonth(-2);
 counterWeek = borderActual[0]-1;
 var endMonth = datePrev.getMonthLength();
 for(var i=borderActual[0]-fDay; i>0; i--) {
  // Nastavujeme udalost kliknuti
  onclick = 'onclick="$(\''+this.boxid+'\').data(\'calendarConf\').selectDay('+endMonth+',-1);"';
  // Vypocet aktualniho Time stamp pro zjisteni zda jsme v intervalu limitu   
  dateUTC = Date.UTC(dateLim.getUTCFullYear(),dateLim.getUTCMonth(),endMonth,23,59,59,999);
  // test limitu 
  if((limFromDate!=null && dateUTC-limFromDate.getTime()<0) ||
     (limToDate!=null && limToDate.getTime()-dateUTC<0)){
   onclick = '';
  } 
  option['I'+i] = 
   '<div class="calendarLink calendarPassiveMonth '+
    (testOfWeek(counterWeek)?'calendarWeekDay ':'')+
    (onclick==''?'calendarNoLink ':'')+
   '" '+onclick+'>'+endMonth+'</div>';
  endMonth -= 1;
  counterWeek -= 1;
 }
 // Vypsani mesice s rokem
 option['Year'] = this.localConf.getTrans('m'+(dateActual.getUTCMonth()+1))+"&nbsp;"+dateActual.getUTCFullYear();
 option['ArrowL'] = '<div class="calendarLink" onclick="$(\''+this.boxid+'\').data(\'calendarConf\').changeMonth(-1);">&laquo;</div>';
 option['ArrowR'] = '<div class="calendarLink" onclick="$(\''+this.boxid+'\').data(\'calendarConf\').changeMonth(1);">&raquo;</div>'; 
 $(this.boxid).empty().append(this.tableTemplate, option);
}


CalendarBox.prototype.changeMonth = function(num) {
 this.localDate.changeMonth(num);
 this.generateTable();
}

CalendarBox.prototype.selectDay = function(day,monthDif) {
 if(monthDif!=0) {
  this.localDate.changeMonth(monthDif);
 } 
 this.localDate.setUTCDate(day);
 this.localObject.val(this.localDate.toStringByTemplate(this.localConf.get('dateFormat')));
 if(this.localConf.get('panelToDisplay')==null) {
	 this.close();
 }else{
	 this.show(this.localObject);
 }
}
