/**
*
* Booking Engine - JavaScript formCalendar
*
* Created		2007-11-27 10:37:13
* Last Changed	$Date: 2009-05-27 13:13:40 $
*
* @package		booker.kempinski.com
* @author   	$Author: jbradler $
* @copyright	E-Formation GmbH, 2007
* @link			http://www.eformation.de/
* @version  	$Revision: 1.7 $
**/

var _CLASS_NAME			= '.formCal';
var _FIRST_DATE_ID 		= 'checkIn';
var _SECOND_DATE_ID 	= 'checkOut';
var _YEAR_ID			= 'Year';
var _MONTH_ID			= 'Month';
var _DAY_ID				= 'Day';
var _MINIMUM_STAY		= 1;

var formCal = {

	/* init the formCalendar script */
	init: function (options) {

		if ($$('.formCal')[0]) {

			/* init default options */
			this.options = Object.extend({
				className:		_CLASS_NAME,
				firstDateId: 	_FIRST_DATE_ID,
				secondDateId: 	_SECOND_DATE_ID,
				yearId: 		_YEAR_ID,
				monthId: 		_MONTH_ID,
				dayId: 			_DAY_ID,
				minStay:		_MINIMUM_STAY
			}, options || {});


			/* scan xhtml tags for those having the searched class name */
			$A($$(this.options.className)).each(function(el) {
				if(el.getTag() == 'select') {
					/* set event handler */
					el.onchange = this.update.pass(el, this);
					/* reset days of month */
					if (el.id.test(this.options.monthId)) {
						this.resetDays($(el.id.replace(this.options.monthId,this.options.dayId)), el.value, $(el.id.replace(this.options.monthId,this.options.yearId)).value);
					} else
					if (el.id.test(this.options.dayId) && $chk(this.days) == false) {
						this.days = [];
						$A(el.getChildren()).each(function(child) {
							this.days[child.value] = child.innerHTML;
						}, this);
					}
				}
			}, this);

			/* get number of days between first and second date */
			this.duration = this.getDuration();
		}
	},

	/* onchange event handler for date fields */
	update: function(el) {
		if (el.id.test(this.options.dayId)) {
			var type = 'D';
			var pattern = this.options.dayId;
		} else
		if (el.id.test(this.options.monthId)) {
			var type = 'M';
			var pattern = this.options.monthId;
		} else
		if (el.id.test(this.options.yearId)) {
			var type = 'Y';
			var pattern = this.options.yearId;
		}
		if (el.id.test(this.options.firstDateId)) {
			var id = '1st';
		} else
		if (el.id.test(this.options.secondDateId)) {
			var id = '2nd';
		}
		/* switch by type (day/month/year) */
		switch (type) {
			case 'D':
				break;
			case 'M':
			case 'Y':
				/* get todays date */
				var d = new Date();
				var y = d.getYear() < 1900 ? d.getYear() + 1900 : d.getYear();
				var m = d.getMonth() + 1;
				/* check if a month of next year is selected */
				if (type == 'M' && el.value < m && $(el.id.replace(pattern, this.options.yearId)).value == y && $(el.id.replace(pattern, this.options.yearId)).getChildren().getLast().value > y) {
					$(el.id.replace(pattern, this.options.yearId)).value = y + 1;
				}
				/* reset day of month */
				this.resetDays($(el.id.replace(pattern, this.options.dayId)), $(el.id.replace(pattern, this.options.monthId)).value, $(el.id.replace(pattern, this.options.yearId)).value);
				break;
		}

		/* switch by id (first date/second date) */
		switch (id) {
			case '1st':
				var d1 = this.getDateObject(this.options.firstDateId);
				var d2 = new Date(Date.parse(d1) + this.duration*86400000 + 3600000);
				this.resetDays(
					$(this.options.secondDateId + this.options.dayId),
					d2.getMonth().toInt() + 1,
					d2.getYear() < 1900 ? d2.getYear() + 1900 : d2.getYear()
				);
				$(this.options.secondDateId + this.options.dayId).value = d2.getDate();
				$(this.options.secondDateId + this.options.monthId).value = d2.getMonth().toInt() + 1;
				$(this.options.secondDateId + this.options.yearId).value = d2.getYear() < 1900 ? d2.getYear() + 1900 : d2.getYear();
				break;
			case '2nd':
				if (this.getDuration() < 0) {
					var d2 = this.getDateObject(this.options.secondDateId);
					var d1 = new Date(Date.parse(d2) - this.options.minStay*86400000 + 3600000);
					$(this.options.firstDateId + this.options.dayId).value = d1.getDate();
					$(this.options.firstDateId + this.options.monthId).value = d1.getMonth().toInt() + 1;
					$(this.options.firstDateId + this.options.yearId).value = d1.getYear() < 1900 ? d2.getYear() + 1900 : d2.getYear();
					this.duration = this.options.minStay;
				} else {
					this.duration = this.getDuration();
				}
				break;
		}
	},

	/* reset days of month depending on given month and year */
	resetDays: function(el, month, year) {
		var _ = [,31,28,31,30,31,30,31,31,30,31,30,31];
		if (month==2) {
			var days = (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) ? 29 : 28;
		} else {
			var days = _[month];
		}
		/* reset selected option if necessary */
		if (el.value > days) {
			el.value = days;
		}
		/* drop days (if there are too much) */
		while(el.getChildren().getLast().value > days) {
			el.getChildren().getLast().remove();
		}
		/* add days (if there are too less) */
		while(el.getChildren().getLast().value < days) {
			number = el.getChildren().getLast().value.toInt()+1;
			opt = new Element('option').setProperty('value', number).setHTML(this.days[number]).injectAfter(el.getChildren().getLast());
		}
	},

	/* get number of days between first and second date */
	getDuration: function() {
		var first = this.getDateObject(this.options.firstDateId);
		var second = this.getDateObject(this.options.secondDateId);
		return parseInt((second - first)/86400000);
	},

	/* get date of first or second date */
	getDateObject: function(id) {
		return new Date($(id + this.options.yearId).value, $(id + this.options.monthId).value.toInt() - 1, $(id + this.options.dayId).value);
	}

};

// startup
Window.onDomReady(formCal.init.bind(formCal));
