/**
 * @param string idActive
 * @param string idCal
 * @param string idInput   
 * @param Date minDate
 * @param Date maxDate
 * @param boolean isUSform
 */
function Calendar(idActive, idCal, idInput, minDate, maxDate, isUSform) {
    /*
	 * @var idActive string ID DOM objektu, ktery zobrazi kalendar
	 */
	this.idActive = idActive;
	/*
	 * @var idCal string ID DOM objektu, ktery obaluje kalendar
	 */
	this.idCal = idCal;
	/*
	 * @var idInput string ID DOM objektu, kam se vlozi vybrana hodnota
	 */
	this.idInput = idInput;  
	/*
	 * @var minDate Date Minimalni datum jake je mozne vybrat
	 */	 
	this.minDate = minDate;
	/*
	 * @var maxDate Date Maximalni datum jake je mozne vybrat
	 */
	this.maxDate = maxDate;
	/*
	 * @var isUSform boolean Udava v jake forme vraci datum    	 
	 */
	this.isUSform = isUSform;
	/*
	 * @var viewDate Date Zobrazovane datum
	 */
	this.viewDate = null;
	/*
	 * @var elCal DOMobjekt Obaluje kalendar
	 */
	this.elCal = null;
	/*
	 * @var actualDate Date Aktualni datum
	 */
	this.actualDate = null;
	/*
     * @var activeCalendarPopup ID prave otevreneho kalendare
     */
    this.activeCalendarPopup = '';
}
	
/*
 * Hlavni medota pro zavolani kalendare
 */
Calendar.prototype.setCal = function() {
		var thisObject = this; 
		this.elCal = jQ(this.idCal);
        
		// Nastavuje udalost na zavreni okna
		jQ(jQ(this).elCal).find('a.popup_close').click(function () {
	        thisObject.close();
		});
        
        jQ(this.idCal).click(function(event) {
            event.stopPropagation();        
        });

		// Nastavuje udalost pro zobrazeni kelendare
		jQ(this.idActive).click(function(event) {
		
            // Zavira ostatni kalendare  
            var activeCalendarPopupLoc = thisObject.activeCalendarPopup;
            jQ('body').click();
            event.stopPropagation();
            
            // neotevirat znovu kalendar, ktery je jiz otevreny
            if (activeCalendarPopupLoc === jQ(this).attr('id')) {
                return ;
            } else {
                thisObject.activeCalendarPopup = jQ(this).attr('id'); 
            }
            
            // Pridava zvirazneni ikony
            jQ(this).addClass('active');
            
            // Nastavi zobrazovane datum dne inputu
            thisObject.getViewDate();
            
            // Vykresluje kalendar
            thisObject.printCalendar();
            
            // Zobrazuje kalendar
            //jQ(thisObject.elCal).animate("slide", { direction: "up" }, 600);
            jQ(thisObject.elCal).show("slide", { direction: "up" }, 600); 
            jQ('body').bind('click.closeCalendars', function() {
                thisObject.close();
            });
		});
		
		// Nastavuje udalost na dalsi a predchozi
		thisObject.switchMonth();
}

/**
 * Zavira kalendar
 */
Calendar.prototype.close = function() {
    jQ('body').unbind('click.closeCalendars');
    this.activeCalendarPopup = '';
    
    if (jQ(this.idCal).css('display') == 'block') {
        jQ(this.idCal).hide("slide", { direction: "up" }, 600); 
    }
    
    // Odstranuje zvyrazneni ikony
    jQ(this.idActive).removeClass('active');
}

/**
 * Nastavuje udalosti na DOM objekty, ktere prochzi do jinych mesicu
 */
Calendar.prototype.switchMonth = function() {
  
  var thisObject = this;
  
  var elPreview = jQ(this.elCal).find('thead th:first-child');
  var elNext = jQ(this.elCal).find('thead th:last-child');   
  
  // Posunuje zobrazovane datum na nasledujici mesic
  jQ(elPreview).click(function() {
  
    var akctualMonth = thisObject.viewDate.getMonth();

    thisObject.viewDate.setDate(1);
    if (akctualMonth == 0) {
      thisObject.viewDate.setMonth(11);
      thisObject.viewDate.setFullYear(thisObject.viewDate.getFullYear() -1 );  
    } else {
      thisObject.viewDate.setMonth(akctualMonth - 1);
    }
    
    thisObject.printCalendar();
    
  });
  
  // Posunuje zobrazovane datum na predchozi mesic
  jQ(elNext).click(function() {
    var akctualMonth = thisObject.viewDate.getMonth();
    thisObject.viewDate.setDate(1);
    if (akctualMonth == 11) {
      thisObject.viewDate.setMonth(0);
      thisObject.viewDate.setFullYear(thisObject.viewDate.getFullYear() + 1);  
    } else {
      thisObject.viewDate.setMonth(akctualMonth + 1);
    }
    
    thisObject.printCalendar();
    
  });
}

/**
 * Vykresluje kalendar    
 */ 
Calendar.prototype.printCalendar = function() {

  var thisObject = this;

	var elDays = jQ(this.elCal).find('tbody');
	jQ(elDays).html('');

	// Zjistuje, zda-li se zobrazeny mesic nepatri mezi krajni mezni hodnoty datumu	
	var isCollision = this.isCollisionWithLimit();
	
	var dayInMonth = this.daysInMonth();
	var dayPosition = this.getFirstDayPos();
	
	var elDays = jQ(this.idCal).find('tbody');
  
  // Slouzi k testovani dne v limitu
	var testDate = new Date();
  testDate.setFullYear(this.viewDate.getFullYear());
  testDate.setMonth(this.viewDate.getMonth());          
  
  var rowIndexView = (42-dayInMonth-dayPosition+1) / 7;
  
  // Vytvari bunky kalendare
  var strHtml = '<tr>';
	for (var index=1; index<=42; index++) {
			
		var modIndex = index % 7;
		if (modIndex == 6) {
				strHtml += '<td id="calDay' + index + '" class="weekend"></td>';
		} else if (modIndex == 0) {
				strHtml += '<td id="calDay' + index + '" class="weekend"></td><tr></tr>';
		} else {
				strHtml += '<td id="calDay' + index + '"></td>';
		}
		
		if ( (index == 28 && rowIndexView == 2) || (index == 35 && rowIndexView >= 1) ) {
		    break;
		}
    }
  strHtml += '</tr>';
  jQ(elDays).html(strHtml);
 
  // Nastavuje vsechy bunky kalendare
	for (var index=1; index<=42; index++) {
  		this.createDay(elDays, index, dayPosition, dayInMonth);  
	}
	
	// Vykresluje nazev mesice
	var mounths = new Array('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December');

  jQ(this.elCal).find('thead th:eq(1)').empty().html(
    mounths[this.viewDate.getMonth()] + ' ' + this.viewDate.getFullYear()
  );
}

/**
 * Fce doplnuje obsah pro dny
 * Kod je vyjmity z cyklu, jelikoz se nespravne nastavovat index
 *
 * @param DOMobject elDays Objekt pro dny
 * @param integer index Index dne
 * @param dayPosition Pozice prvniho dne v mesici
 * @param dayInMonth Pocet dni v mesici
 */
Calendar.prototype.createDay = function(elDays, index, dayPosition, dayInMonth) {
		var elDay = jQ(elDays).find('#calDay' + index);
		var thisObject = this;
    // Den v mesici
		if ( dayPosition <= index && index<(dayInMonth+dayPosition) ) {
			var dayValue = index-dayPosition+1;
			
      this.viewDate.setDate(dayValue);
      if (this.isCollisionWithLimit() == true) {
        if (this.actualDate.getDate() == dayValue && this.actualDate.getMonth() == this.viewDate.getMonth()) {
            jQ(elDay).addClass('active');
        }
        jQ(elDay).empty().html('<a href="" onclick="return false;">' + dayValue + '</a>');
        // Nastavuje udalost na predani aktialniho dne do formulare
        jQ(elDay).children('a').click(function () {
          	thisObject.setDateToForm(this, (index-dayPosition+1));
        });
      } else {
      	jQ(elDay).addClass('noactive');
        jQ(elDay).empty().html(dayValue); 
      }
    // Bunky mimo zobrazovany rozsah
		} else {
			jQ(elDay).empty().addClass('noactive');
		}		
}

/**
 * Vraci pozici prvniho dne v mesici
 *
 * @return integer
 */
Calendar.prototype.getFirstDayPos = function() {
	
	var testDate = new Date();
	
	testDate.setDate(1);
	testDate.setMonth(this.viewDate.getMonth());
	testDate.setFullYear(this.viewDate.getFullYear());
	
	var dayPosition = (testDate.getDay() * 1);
	if (dayPosition == 0) {
		dayPosition = 7;
	}
	
	return dayPosition;
}

/*
 * Vraci pocet dni v mesici
 *
 * @return integer
 */
Calendar.prototype.daysInMonth = function() {
	return 32 - new Date(this.viewDate.getFullYear(), this.viewDate.getMonth(), 32).getDate();
},


/*
 * Vraci, jestli se v zobrazovanem mesici nachazi mezni datum
 *
 * @return boolean
 */
Calendar.prototype.isCollisionWithLimit = function() {
	
	var isCollision = false;
	if (this.minDate.getTime() <= this.viewDate.getTime() && this.viewDate.getTime() <= this.maxDate.getTime()) {
			isCollision = true;		
	}
	
	return isCollision;
}

/*
 * Vraci, aktualne zobrazovane datum
 *
 * @return Date
 */
Calendar.prototype.getViewDate = function() {
	
	var correctDate = false;
	
	// US format datumu
	if (this.isUSform == true) {
		correctDate = this.checkUSDate();
	} else {
		correctDate = this.checkDate();
	}

	// Neni-li korektni datum, vychozi hodnota je aktualni d.
	var viewDate = null;
	if (correctDate == true) {
		viewDate = this.getTransformDate();
	} else {
		viewDate = new Date(); 
	}
	
	// Pro spravne porovnavani nastavuje vsem objektum Date totozny cas
	/*this.viewDate.setHours(12, 0, 0, 0);
	this.minDate.setHours(12, 0, 0, 0);
	this.maxDate.setHours(12, 0, 0, 0);*/
	
	// Nastavuje aktualni datum pro vyznaceni puvodni hodnoty
	this.actualDate = new Date();
	this.actualDate.setDate(this.viewDate.getDate());
	this.actualDate.setMonth(this.viewDate.getMonth());
    this.actualDate.setFullYear(this.viewDate.getFullYear());	
	
	return viewDate;
}

/**
 * Nastavi datum do formulare
 * 
 * @param elLink DOMobjekt vybraneho elementu pro den
 * @param index integer Odecet pro urceni vybraneho dne 	 
 */
Calendar.prototype.setDateToForm = function (elLink, index) {

	//var strDate = '';

	/*var dayNumber = (jQ(elLink).parent().attr('id'));
	dayNumber = dayNumber.replace('calDay', '');
	dayNumber = dayNumber - 1; */
	this.viewDate.setDate(index);
	
	if (this.isUSform == true) {
		strDate = (this.viewDate.getMonth()+1) + '.' + this.viewDate.getDate() + '.' + this.viewDate.getFullYear()
	} else {
		strDate = this.viewDate.getDate() + '.' + (this.viewDate.getMonth()+1) + '.' + this.viewDate.getFullYear()
	}
	
	jQ(this.idInput).attr('value', strDate);
	
	// Zobrazuje kalendar
	this.close();
	
	// Vyvolava udalost pro testovani formulare
	jQ(this.idInput).change();
}

/**
 * Vraci zobrazovane datum
 *
 * @return Date 
 */
Calendar.prototype.getTransformDate = function() {
	return this.viewDate;
}

/**
 *
 */
Calendar.prototype.checkUSDate = function() {
	
}

/*
 * Kontroluje, zda-li je zadane datum spravne
 *
 * @return boolean
 */
Calendar.prototype.checkDate = function() {
	
	var isCorrect = false;
	var viewDate = new Date();
    	
	var inputValue = jQ(this.idInput).attr('value');

	var parseDate = inputValue.split('.', 3);
	
	if (parseDate.length == 3) {
		for (var index in parseDate) {
				intValue = parseDate[index] * 1;
				index = index * 1;
				switch(index) {
					case 0:
					  viewDate.setDate(intValue);
					  break;
					case 1:
						intValue = intValue - 1; // Index mesice 0..11
					  viewDate.setMonth(intValue);
					  break;
					case 2:
						viewDate.setFullYear(intValue);
					  break;
				}
		}
	}
	if (viewDate != 'Invalid Date') {
		isCorrect = true;
		this.viewDate = viewDate;
	}

	return isCorrect;
}
