function classDates(objName) {
	this.daysShort = ['Pn', 'Wt', 'Śr', 'Cz', 'Pt', 'So', 'Ni'];
	this.monthsNames = ['Styczeń','Luty','Marzec','Kwiecień','Maj','Czerwiec','Lipiec','Sierpień','Wrzesień','Październik','Listopad','Grudzień'];
	if (objName) {
		this.objName = objName; // nazwa obiektu
	}
}
classDates.prototype.daysInMonth = function (oDate) {
	return 32 - new Date(oDate.getFullYear(), oDate.getMonth(), 32).getDate();
}

classDates.prototype.islt_ymd = function (oDate1, oDate2) {
	return ((oDate1.getDate() < oDate2.getDate()) && (oDate1.getMonth() == oDate2.getMonth()) && (oDate1.getFullYear() == oDate2.getFullYear()))||
			((oDate1.getMonth() < oDate2.getMonth()) && (oDate1.getFullYear() == oDate2.getFullYear()))||(oDate1.getFullYear() < oDate2.getFullYear());
}
classDates.prototype.isle_ymd = function (oDate1, oDate2) {
	return ((oDate1.getDate() <= oDate2.getDate()) && (oDate1.getMonth() == oDate2.getMonth()) && (oDate1.getFullYear() == oDate2.getFullYear()))||
			((oDate1.getMonth() < oDate2.getMonth()) && (oDate1.getFullYear() == oDate2.getFullYear()))||(oDate1.getFullYear() < oDate2.getFullYear());
}

classDates.prototype.isle_ym = function (oDate1, oDate2) {
	return ((oDate1.getMonth() <= oDate2.getMonth()) && (oDate1.getFullYear() == oDate2.getFullYear()))||(oDate1.getFullYear() < oDate2.getFullYear());
}

classDates.prototype.cloneDate = function (oDate) {
	return new Date(oDate.getFullYear(), oDate.getMonth(), oDate.getDate());
}

function Calendar(objName, paneltarget, daystarget, monthstarget, ocurDate, ostartDate, scalType, orelCal, monthscount) {
	if (objName) {
		classDates.call(this);
		this.objName = objName; // nazwa obiektu
		this.panel = document.getElementById(paneltarget); // obiekt w ktory piszemy panel dni
		this.days = document.getElementById(daystarget); // obiekt w ktory piszemy select z dniami
		this.months = document.getElementById(monthstarget); // obiekt w ktory piszemy select z miesiacami i latami
		this.ocurDate = this.cloneDate(ocurDate); // dzien biezacy
		this.ostartDate = this.cloneDate(ostartDate); // dzien startu
		this.orelCal = orelCal; // kalendarz powiazany
		this.scalType = (scalType==undefined)?'a':scalType; // typ: a-samodzielny, m - glowny, s-zalezny

		this.panelId = objName+'_panel'; // id tworzonego panelu
		this.daysId = objName+'_days'; // id tworzonego selecta dni
		this.monthsId = objName+'_months'; // id tworzonego selecta miesiecy i lat
		this.monthscount = (monthscount==undefined)?12:monthscount; // na ile miesiecy do przodu ma byc select

		this.active = true; // flaga czy kalendarz aktywny
		this.dayShift = (new Date(this.ocurDate.getFullYear(), this.ocurDate.getMonth()).getDay()+1)%7; // ktory dzien tygodnia danego miesiaca

		this.maxDays = this.daysInMonth(this.ocurDate); // ilosc dni w miesacu

		this.otable = this.createPanel();
		this.odays = this.createDays();
		this.omonths = this.createMonths();
	}
}

Calendar.prototype = new classDates();

Calendar.prototype.createPanel = function () {
	this.dayShift = ((new Date(this.ocurDate.getFullYear(), this.ocurDate.getMonth(), 1).getDay())+6)%7; // ktory dzien tygodnia danego miesiaca
	if (this.ocurDate.getDate() > this.maxDays)
		this.ocurDate.setDate(this.maxDays);

	var aCalendarTable = new Array; // bufor
	var attribs = {'class' : 'passive', 'onclick' : '', 'onmouseover' : '', 'onmouseout' : ''}; // atrybuty tdka
	var ncols=7, day=0, nday=0; // ilosc dni w tyg, biezacy dzien, dzien z przesunieciem
	var nrows = Math.ceil((this.maxDays+this.dayShift)/ncols);
	var onclickstr = '';
	var onday = new Date(this.ocurDate.getFullYear(), this.ocurDate.getMonth(), 1);
	var today = this.ocurDate.getDate();
	aCalendarTable.push('<table id="'+this.panelId+'" class=calendar><tbody>');

	aCalendarTable.push('<tr>');
	for (var i=0; i<7; i++) {
		aCalendarTable.push('<td class="title">');
		aCalendarTable.push(this.daysShort[i]);
		aCalendarTable.push('</td>');
	}
	aCalendarTable.push('</tr>');

	for (var j=0; j<nrows; j++) {
		aCalendarTable.push('<tr>');
		for(var i=0; i<ncols; i++){
			day = i+7*j;
			nday = day-this.dayShift+1;
			if (nday > 0)
				onday.setDate(nday);
			onclickstr = this.objName+'.setDay('+nday+');';
			if (nday<=0||(this.islt_ymd(onday, this.ostartDate))||!this.active) {
				attribs = {'class' : 'passive'};
			}
			else
				attribs = {'class' : 'active', 'onclick' : onclickstr};
			if (nday == today && this.active)
				attribs = {'class' : 'set'};
			aCalendarTable.push('<td');
			for (var key in attribs) 
				if (attribs[key] != '')
					aCalendarTable.push(' '+key+'="'+attribs[key]+'"');
			aCalendarTable.push('>')
			if (attribs['class']=='active')
// 				aCalendarTable.push('<a href="#">');
				aCalendarTable.push('<a>');
			aCalendarTable.push((nday<=0||!this.active)?'':nday);
			if (attribs['class']=='active')
				aCalendarTable.push('</a>');
			aCalendarTable.push('</td>');

			if (nday>=this.maxDays)
				break;
		}
		aCalendarTable.push('</tr>');
	}
	aCalendarTable.push('</tbody></table>');
	this.panel.innerHTML = aCalendarTable.join('');
	aCalendarTable = null;
	return document.getElementById(this.panelId);
}

Calendar.prototype.setDay = function (curDay) {
	function change(day, sclass) {
		var nrow = Math.floor((day+dayShift-1)/7)+1; // numer wiersza dla okreslonego dnia
		var ncell = ((day+dayShift-1)%7); // numer kolumny dla okreslonego dnia
		otable.rows[nrow].cells[ncell].className = sclass;
		if (sclass=='set'||sclass=='passive'||!this.active)
			otable.rows[nrow].cells[ncell].onclick = null;
		else
			otable.rows[nrow].cells[ncell].onclick = function() {fonclick()};
	}

	function fonclick() {
		eval(objName+'.setDay('+oldDay+');');
	}

	var dayShift = this.dayShift;
	var oldDay = this.ocurDate.getDate();
	var objName = this.objName;
	var otable = this.otable;
	var scalType = this.scalType;

	curDay = parseInt(curDay);
	change(oldDay, 'active');
	change(curDay, 'set');

	this.ocurDate.setDate(curDay);
	this.odays.selectedIndex = this.ocurDate.getDate()-1;
	this.update(false);
	return true;
}

Calendar.prototype.setDays = function(curDay) {
	curDay = parseInt(curDay);
	var oldday = this.ocurDate.getDate();
	var newdate = new Date(this.ocurDate.getFullYear(), this.ocurDate.getMonth(), curDay);

	if (this.islt_ymd(this.ostartDate, newdate)) {
		this.ocurDate.setDate(curDay);
		this.setDay(curDay);
		this.odays.selectedIndex = this.ocurDate.getDate()-1;
	}
	else
		this.odays.selectedIndex = oldday-1;
}

Calendar.prototype.createDays = function() {
	var adaysDrop = new Array;

	if (this.active) {
		adaysDrop.push('<select class="days" id="'+this.daysId+'" onchange="'+this.objName+'.setDays(this.value)">');
		for (var i=1; i<=this.maxDays; i++) {
			adaysDrop.push('<option');

			if (i == this.ocurDate.getDate())
				adaysDrop.push(' value="'+i+'" selected="selected">');
			else
				adaysDrop.push(' value="'+i+'">');

			adaysDrop.push(i+'</value>');
		}
		adaysDrop.push('</select>');
	}
	else
		adaysDrop.push('<select class="days" id="'+this.daysId+'" disabled="disabled"/>');

	this.days.innerHTML = adaysDrop.join('');
	adaysDrop = null;
	return document.getElementById(this.daysId);
}

Calendar.prototype.createMonths = function() {
	var amonthsDrop = new Array;

	if (this.active) {
		var startYear = this.ostartDate.getFullYear();
		var monthstart = this.ostartDate.getMonth()-1;
		amonthsDrop.push('<select class="months" id="'+this.monthsId+'" onchange="'+this.objName+'.setMonth(this.value)">');
		for (var i=1; i<=this.monthscount; i++) {
			amonthsDrop.push('<option');
			if (((monthstart+i)%12) == (this.ocurDate.getMonth()))
				amonthsDrop.push(' value="'+((monthstart+i)%12+1)+'-'+startYear+'" selected="selected">');
			else
				amonthsDrop.push(' value="'+((monthstart+i)%12+1)+'-'+startYear+'">');
			amonthsDrop.push(this.monthsNames[(monthstart+i)%12]+', '+startYear+'</value>');
			if ((monthstart+i+1)%12 == 0)
				startYear++;
		}
		amonthsDrop.push('</select>');
	}
	else
		amonthsDrop.push('<select class="months" id="'+this.monthsId+'" disabled="disabled"/>');

	this.months.innerHTML = amonthsDrop.join('');
	amonthsDrop = null;
	return document.getElementById(this.monthsId);
}

Calendar.prototype.setMonth = function(curMonth) {
	var curmy = curMonth.split('-');
	var newmaxDays = this.daysInMonth(new Date(curmy[1], curmy[0]-1, 1));
	this.maxDays = newmaxDays;

	if (this.ocurDate.getDate() > newmaxDays)
		this.ocurDate = new Date(curmy[1], (curmy[0]-1), newmaxDays);
	else
		this.ocurDate = new Date(curmy[1], (curmy[0]-1), this.ocurDate.getDate());

	if (this.islt_ymd(this.ocurDate, this.ostartDate))
		this.ocurDate = this.cloneDate(this.ostartDate);

	this.update();
}

Calendar.prototype.update = function(redraw) {
	redraw = (redraw==undefined)?true:redraw;
	switch (this.scalType) {
		case 'm' :
			this.updateDates();
			if (this.orelCal.active)
				this.orelCal.update(redraw);
			break;
		case 's' :
			if (this.active) {
				this.updateDates();
				this.monthscount = this.orelCal.monthscount-this.orelCal.omonths.selectedIndex;
			}
		case 'a' :
		default :
	}

	function delComponent(ocomp, target) {
		ocomp = null;
		target.innerHTML = '';
	}

	delComponent(this.otable, this.panel);
	this.otable = this.createPanel();
	if (redraw) {
		delComponent(this.odays, this.days);
		this.odays = this.createDays();
		delComponent(this.omonths, this.months);
		this.omonths = this.createMonths();
	}
}

Calendar.prototype.setActive = function(active) {
	this.active = active;
	this.update();
}

Calendar.prototype.updateDates = function() {
	switch (this.scalType) {
		case 'm':
			this.orelCal.ostartDate = this.cloneDate(this.ocurDate);
			if (this.islt_ymd(this.orelCal.ocurDate, this.orelCal.ostartDate))
				this.orelCal.ocurDate = this.cloneDate(this.orelCal.ostartDate);
			this.orelCal.maxDays = this.daysInMonth(this.orelCal.ocurDate);
			break;
		case 's':
			this.ostartDate = this.cloneDate(this.orelCal.ocurDate);
			if (this.islt_ymd(this.ocurDate, this.ostartDate))
				this.ocurDate = this.cloneDate(this.ostartDate);
			this.maxDays = this.daysInMonth(this.ocurDate);
			break;
	}
}

function Calendars(objName, daysAhead_d, daysAhead_a, monthscount) {
	daysAhead_d = (daysAhead_d==undefined)?0:daysAhead_d; // ile dni naprzod ma byc ustawiony kalendarz wylotu
	daysAhead_a = (daysAhead_a==undefined)?0:daysAhead_a; // ile dni naprzod ma byc ustawiony kalendarz powrotu
	monthscount = (monthscount==undefined)?4:monthscount; // ile miesiecy ma byc w selecie miesiecy wylotu
	var today = new Date();
	var now = new Date(today.getFullYear(), today.getMonth(), today.getDate()+daysAhead_d);
	var now_a = new Date(now.getFullYear(), now.getMonth(), now.getDate()+daysAhead_a);
	var start_a = new Date(today.getFullYear(), today.getMonth(), today.getDate()+daysAhead_d);

	this.cal_d = new Calendar(objName+'.cal_d', 'calendar_d', 'days_d', 'months_d', now, now, 'm', monthscount);
	this.cal_a = new Calendar(objName+'.cal_a', 'calendar_a', 'days_a', 'months_a', now_a, start_a, 's');

	this.cal_d.orelCal = this.cal_a;
	this.cal_a.orelCal = this.cal_d;
}
