(function(){

	var dayArr = "Mon,Tue,Wed,Thu,Fri,Sat,Sun".split(","),
		monArr = "January,February,March,April,May,June,July,August,September,October,November,December".split(","),
		pax_types = "adults,teenagers,children,infants".split(','),
		pax_types_pre = "adult_,teen_,child_,infant_".split(','),

		avlTbl = 'avl-tbl',
		avlAct = 'ajax-avl',
		inited = false,
		avlError = false,
		frm = null,

		cellFrom = null,
		cellTo = null,

		monthA = null,
		monthB = null,
		yearA = null,
		yearB = null;

		//minStay = 0,
	
	function CalendarDay(dayIndex) {
		this.num = dayIndex;
		this.date = null;
		this.status = null;
		this.ia = null;
		this.ca = null;
		this.ta = null;
		this.minStay = null;
	}

	function cleanup() {
		frm=null;
	}

	function buildSection(tbl) {
		var weeklen = 7, weeksToPaint = 6,
			tBody, row, cell, i=0, j=0;
		
		tbl.appendChild(document.createElement('tbody'));
		tBody = tbl.tBodies[0];

		row = document.createElement('tr');
		tBody.appendChild(row);
		cell = document.createElement('th');
		cell.className = "month";
		cell.colSpan = weeklen;
		row.appendChild(cell);

		row = document.createElement('tr');
		tBody.appendChild(row);
		for ( ; i < weeklen; i++ ) {
			cell = document.createElement('th');
			cell.innerHTML = window.lang[dayArr[i]];
			if ( i >= weeklen-2 ) {
				cell.className = "wkend";
			}
			row.appendChild(cell);
		}

		for ( i = 0; i < weeksToPaint; i++ ) {
			row = document.createElement('tr');
			tBody.appendChild(row);
			for ( j = 0; j < weeklen; j++ ) {
				row.appendChild(document.createElement('td'));
			}
		}
	}

	function init() {
		frm = document.forms.avlFrm;
		Event.on(window, "unload", cleanup);

		var tbl = $(avlTbl);

		buildSection(tbl);
		buildSection(tbl);

		var dayCells = $$('td', tbl);

		Array.forEach(dayCells, function(el, i){
			dom.data(el, 'day', new CalendarDay(i));
		});

		Event.on(dayCells, "click", dayClickHnd);
		if ( Env.legacy ) {
			Event.on(dayCells, "mouseover", dayMouseOver);
			Event.on(dayCells, "mouseout", dayMouseOut);
		}
	}

	if ( Env.legacy ) {
		function dayMouseOver(e) {
			if ( !this.getAttribute('date') ) {
				return;
			}
			dom.classAdd(this, "hover");
		}
	
		function dayMouseOut(e) {
			if ( !this.getAttribute('date') ) {
				return;
			}
			dom.classRemove(this, "hover");
		}
	}

	function firstDayInMonth(date) {
		var day = date.getDay();
		return ( day === 0 ) ? 6 : --day;	// monday is start of week in our calendar !
	}
	
	function buildMonth(dayCells, sectionSize, date, startIndex) {
		var daysInMonth = date.daysInMonth(),
			firstCell = firstDayInMonth(date),
			i=0, cell;

		for ( ; i < sectionSize; i++ ) {
			cell = dayCells[i+startIndex];
			if ( i-firstCell >= daysInMonth || dom.data(cell, 'day').num < firstCell+startIndex ) {
				cell.innerHTML = "";
				cell.className = "inactive";
				dom.data(cell, 'day').date = null;
				continue;
			}

			cell.innerHTML = date.getDate();
			dom.data(cell, 'day').date = date.clone();
			if ( date >= app.today ) {
				cell.className = "";
			} else {
				cell.className = "past";
			}

			date.dayAdd(1);
		}
		cell=null;
	}

	function buildMonths() {
		var tbl = $(avlTbl),
			headers = cssQuery('th.month', tbl),
			dayCells = $$('td', tbl),
			sectionSize = dayCells.length/2;

		headers[0].innerHTML = window.lang[monArr[monthA]] + "&nbsp;" + yearA;
		headers[1].innerHTML = window.lang[monArr[monthB]] + "&nbsp;" + yearB;

		buildMonth(dayCells, sectionSize, (new Date(yearA, monthA, 1)), 0);
		buildMonth(dayCells, sectionSize, (new Date(yearB, monthB, 1)), 42);

		tbl=headers=dayCells=null;
	}

	function avl() {
		var pers_proom = [];

		for ( var rm=1, i, rooms=parseInt(frm.rooms.value, 10); rm <= rooms; rm++ ) {
			for ( i=0; i < pax_types.length; i++ ) {
				pers_proom.push(frm[pax_types_pre[i]+rm].value);
			}
		}
		frm.pers_proom.value = pers_proom.join('^') + '^';
	
		ajax.post(frm, 'htl_code,rm_type,cal_year,cal_month,pers_proom');
		ajax.queue(avlHnd, avlAct);
		ajax.loadXML("htl/htl_bk.cfm?action=avl", avlAct, "Checking availability.");
	}

	function avlHnd() {
		var response = ajax.getXML(avlAct);

		if ( response.getAttribute('flag') ) {
			avlError = true;
			buildMonths();
			return ajax.checkXMLResult(avlAct);
		}
		avlError = false;

		var days = cssQuery('day', response),
			cells = $$('td', avlTbl);

		for ( var i=0, d=0, len=cells.length; i < len; i++ ) {
			var data = dom.data(cells[i], 'day');
			if ( !data.date ) {
				continue;
			}

			if ( data.date >= app.today ) {
				data.status = days[d].getAttribute('status');
				data.ia = parseInt(days[d].getAttribute('ia'), 10);
				data.ca = parseInt(days[d].getAttribute('ca'), 10);
				data.ta = parseInt(days[d].getAttribute('ta'), 10);
				data.minStay = parseInt(days[d].getAttribute('min'), 10);
				
				switch ( data.status ) {
				case "0":
					cells[i].className = "res";
					break;
				case "1":
					cells[i].className = "avl";
					break;
				case "2":
					cells[i].className = "or";
					break;
				case "3":
					cells[i].className = "na";
				}
			}
			d++;
		}
	}

	function dayClickHnd(e) {
		if ( cellTo ) {
			clearSelection();
		}

		var data = dom.data(this, 'day');
		if ( !data.date ) {
			return;
		}

		if ( cellFrom ) {
			if ( data === cellFrom ) {
				return;
			} else if ( data.num < cellFrom.num ) {
				clearSelection();
			} else {
				var dayCells = $$('td', avlTbl),
					i = cellFrom.num-1,
					trg = data.num;

				while ( ++i <= trg ) {
					if ( dom.data(dayCells[i], 'day').date ) {
						dom.classAdd(dayCells[i], "selected");
					}
				}

				cellTo = data;
				return;
			}
		}

		cellFrom = data;
		dom.classAdd(this, "selected");
	}

	function clearSelection() {
		if ( cellFrom ) {
			var dayCells = $$('td', avlTbl);
			if ( cellTo ) {
				for ( var i=cellFrom.num, len=cellTo.num+1; i < len; i++ ) {
					dom.classRemove(dayCells[i], "selected");
				}
			} else {
				dom.classRemove(dayCells[cellFrom.num], "selected");
			}
			cellFrom=cellTo=null;
		}
	}

	calendar = {

		setMonth: function(month, year) {
			monthA = month;
			monthB = month > 11 ? 1 : month+1;
			yearA = year;
			yearB = month > 11 ? year+1 : year;

			if ( !inited ) {
				init();
				inited = true;				
			} else {
				clearSelection();
			}
			buildMonths();
		},

		avl: function() {
			clearSelection();
			avl();
		},

		validate: function() {
			if ( avlError ) {
				dom.console(2, "Please search for available rooms to continue.");
				return false;
			}
			if ( !cellFrom || !cellTo ) {
				dom.console(4, "Please, select check-in and check-out dates to continue.");
				return false;
			}
			if ( cellFrom.minStay > 0 && cellTo.num - cellFrom.num < cellFrom.minStay ) {
				dom.console(4, "At least " + cellFrom.minStay + " nights must be selected in order to book this room.");
				return false;
			}

			$('sum_fromd').innerHTML = frm.fromd.value = cellFrom.date.format();
			$('sum_tod').innerHTML = frm.tod.value = cellTo.date.format();
	 		$('sum_nights').innerHTML = (cellTo.num - cellFrom.num);
			frm.teen_age.value = cellFrom.ta;
			frm.child_age.value = cellFrom.ca;
			frm.infant_age.value = cellFrom.ia;
			return true;
		}

	};

})();