/**
 * Definition von Funktionen, die für die Darstellung und Umrechnung der
 * Datumsfelder bzw. des Kalenders benötigt werden.
 *
 * @package de.otto-freizeit.suchformulare
 * @author Christian Poulter, 17.02.2009, christian.poulter@otto-freizeit.de
 * @version 1.0, 17.02.2009
 */


/**
 * Ermittelt die Anzahl von Tagen im Monat/Jahr
 * @param monat Zahl als Monat
 * @param jahr Zahl als Jahr
 * @return eine Zahl zwischen 28 und 31, je nach Monat/Jahr
 */
function maxTageImMonat(monat, jahr) {
	switch(monat){
		case 2:
			if	(((jahr%4===0) && !(jahr%100===0)) || (jahr%400===0))
				return 29;
			else
				return 28;
		case 4:
		case 6:
		case 9:
		case 11:
			return 30;
		default:
			return 31;
	}
}

/**
 * wählt aus den Selectfelder das angegebene Datum aus
 * @param idTag HTML-Element-ID des Formularfeldes, in das der Tag steht
 * @param idTag HTML-Element-ID des Formularfeldes, in das Monat/Jahr steht
 * @param datum das einzustellende Datum (tt.mm.jjjj)
 */
function setCalendarDateFields(idWochentag, idTag, idMonatJahr, datum) {
	var d = datum.split(".");
	var tag = myParseInt(d[0]);
	var mon = myParseInt(d[1]);
	var jahr = myParseInt(d[2]);

	// setzt das Tagfeld auf den gewünschten Wert
	var options = document.getElementById(idTag);
	for (i = 0; i < options.length; i++) {
		if (myParseInt(options[i].value) == tag)
			options[i].selected = true;
	}

	// setzt das Monat/Jahr-Feld
	var options = document.getElementById(idMonatJahr);
	for (i = 0; i < options.length; i++) {
		var odatum = options[i].value.split(".");
		var omon = myParseInt(odatum[0]);
		var ojahr = myParseInt(odatum[1]);

		if ((omon == mon) && (ojahr == jahr))
			options[i].selected = true;
	}

	if (document.getElementById(idWochentag) != null) wochentagAnpassen(idWochentag, idTag, idMonatJahr);
}

/**
 * Graut Tage aus, die im ausgewählten Monat nicht verfügbar sind (z.B. 31. Feb)
 * @param idTag HTML-Element-ID des Formularfeldes, in das der Tag steht
 * @param idMonatJahr HTML-Element-ID des Formularfeldes, in das Monat/Jahr steht
 * @param ersterTag erster erlaubter Tag (tt.mm.jjjj)
 * @param letzterTag letzter erlaubter Tag (tt.mm.jjjj)
 */
function handleMonatAuswahl(idTag, idMonatJahr, ersterTag, letzterTag) {
	var options = document.getElementById(idMonatJahr);
	var selDate = options[options.selectedIndex].value;

	var d = selDate.split(".");
	var mon = myParseInt(d[0]);
	var jahr = myParseInt(d[1]);
	var maxdays = myParseInt(maxTageImMonat(mon, jahr));
	var mindays = 1;

	var ersterTagd = ersterTag.split(".");
	var ersterTagTag = myParseInt(ersterTagd[0]);
	var ersterTagMon = myParseInt(ersterTagd[1]);
	var ersterTagJah = myParseInt(ersterTagd[2]);

	var letzterTagd = letzterTag.split(".");
	var letzterTagTag = myParseInt(letzterTagd[0]);
	var letzterTagMon = myParseInt(letzterTagd[1]);
	var letzterTagJah = myParseInt(letzterTagd[2]);

	if ((jahr == ersterTagJah) && (mon == ersterTagMon) && (ersterTagTag > mindays)) mindays = ersterTagTag;
	if ((jahr == letzterTagJah) && (mon == letzterTagMon) && (letzterTagTag < maxdays)) maxdays = letzterTagTag;

	var options = document.getElementById(idTag);
	for (i = 0; i < options.length; i++) {
		if (myParseInt(options[i].value) > maxdays) {
			options[i].disabled = true;
			if (options[i].selected == true) {
				options[i].selected = false;
				for (j = 0; j < options.length; j++) {
					if (myParseInt(options[j].value) == maxdays)
						options[j].selected = true;
				}
			}
		} else if (myParseInt(options[i].value) < mindays) {
			options[i].disabled = true;
			if (options[i].selected == true) {
				options[i].selected = false;
				for (j = 0; j < options.length; j++) {
					if (myParseInt(options[j].value) == mindays)
						options[j].selected = true;
				}
			}
		} else {
			options[i].disabled = false;
		}
	}
}

/**
 * Trägt in das angegebene Formularfeld ein zu den anderen Formularfeldern passenden
 * Wochentag ein.
 * @param idWochentag HTML-Element-ID des Formularfeldes, in das der Wochentag steht
 * @param idTag HTML-Element-ID des Formularfeldes, in das der Tag steht
 * @param idMonatJahr HTML-Element-ID des Formularfeldes, in das Monat/Jahr steht
 */
function wochentagAnpassen(idWochentag, idTag, idMonatJahr) {
	var wochentag = document.getElementById(idWochentag);
	var tag = document.getElementById(idTag);
	var monatJahr = document.getElementById(idMonatJahr);

	if ((wochentag != null) && (tag != null) && (monatJahr != null)) {
		var d = monatJahr.value.split(".");
		var datum = new Date(myParseInt(d[1]), myParseInt(d[0])-1, myParseInt(tag.value));
		wochentag.value = new Array("So", "Mo", "Di", "Mi", "Do", "Fr", "Sa")[datum.getDay()];
	}
}

/**
 * Initialisiert die Datumsfelder eines Formulars, dh. trägt die gewünschten Werte ein.
 * @param idWochentag HTML-Element-ID des Formularfeldes, in das der Wochentag steht
 * @param idTag HTML-Element-ID des Formularfeldes, in das der Tag steht
 * @param idMonatJahr HTML-Element-ID des Formularfeldes, in das Monat/Jahr steht
 * @param departureWeekdayId HTML-Element-ID des Abflugwochentages.
 * @param departureDayId HTML-Element-ID des Abflugtages.
 * @param departureMonthYearId HTML-Element-ID des Abflugmonatjahrs.
 * @param returningWeekdayId HTML-Element-ID des Rückflugwochentages.
 * @param returningDayId HTML-Element-ID des Rückflugwtages.
 * @param returningMonthYearId, HTML-Element-ID des Rückflugmonatjahrs.
 * @param ersterTag erster erlaubter Tag (tt.mm.jjjj)
 * @param letzterTag letzter erlaubter Tag (tt.mm.jjjj)
 * @param ausgewaehlterTag vorausgewählter Tag (tt.mm.jjjj)
 */
function setupCalenderDateFields(idWochentag, idTag, idMonatJahr,
                                 departureWeekdayId, departureDayId, departureMonthYearId,
                                 returningWeekdayId, returningDayId, returningMonthYearId,
                                 ersterTag, letzterTag, ausgewaehlterTag) {

	//warten bis Seite vollständig geladen ist
	YAHOO.util.Event.onDOMReady(function () {

		// Diese Listener sorgen dafür, dass bei Änderungen des Abflugdatums, das Rückflugdatum mit dem Abflugdatum abgeglichen und ggf. angepasst wird.
		YAHOO.util.Event.addListener(idTag,       'change', function() {
			synchronizeDates(departureWeekdayId, departureDayId, departureMonthYearId, returningWeekdayId, returningDayId, returningMonthYearId);
			handleMonatAuswahl(returningDayId, returningMonthYearId, ersterTag, letzterTag);
		} );

		YAHOO.util.Event.addListener(idMonatJahr, 'change', function() {
			synchronizeDates(departureWeekdayId, departureDayId, departureMonthYearId, returningWeekdayId, returningDayId, returningMonthYearId);
			handleMonatAuswahl(returningDayId, returningMonthYearId, ersterTag, letzterTag);
		} );

		// Dieser Listener sorgt dafür, das ungültige Tage ausgegraut werden
		YAHOO.util.Event.addListener(idMonatJahr, 'change', function() {
			handleMonatAuswahl(idTag, idMonatJahr, ersterTag, letzterTag);
		} );
		handleMonatAuswahl(idTag, idMonatJahr, ersterTag, letzterTag);

		// Dieser Listener sorgt dafür, dass der Wochentag (sofern vorhanden) bei Auswahl angepasst wird.
		if (document.getElementById(idWochentag) != null) {
			YAHOO.util.Event.addListener(idTag, 'change', function() {
				wochentagAnpassen(idWochentag, idTag, idMonatJahr);
			} );

			YAHOO.util.Event.addListener(idMonatJahr, 'change', function() {
				wochentagAnpassen(idWochentag, idTag, idMonatJahr);
			} );

			wochentagAnpassen(idWochentag, idTag, idMonatJahr);
		}
	});
}

/**
 * Prüft, ob sich das Abflugdatum nach dem Rückflugdatum befindet und ändert ggf. das Rückflugdatum
 * entsprechend.
 * @param departureWeekdayId HTML-Element-ID des Formularfeldes, in das der Wochentag steht
 * @param departureDayId HTML-Element-ID des Formularfeldes, in dem der Tag des Abfluges steht
 * @param departureMonthYearId HTML-Element-ID des Formularfeldes, in dem der Monat+Jahr des Abfluges steht
 * @param returningWeekdayId HTML-Element-ID des Formularfeldes, in das der Wochentag steht
 * @param returningDayId HTML-Element-ID des Formularfeldes, in dem der Tag des Rückfluges steht
 * @param returningMonthYearId HTML-Element-ID des Formularfeldes, in dem der Monat+Jahr des Rückfluges steht
 */
function synchronizeDates (departureWeekdayId, departureDayId, departureMonthYearId, returningWeekdayId, returningDayId, returningMonthYearId) {
	var depday = document.getElementById(departureDayId);
	var depmy = document.getElementById(departureMonthYearId);
	var retday = document.getElementById(returningDayId);
	var retmy = document.getElementById(returningMonthYearId);

	if ((depday != null) && (depmy != null) && (retday != null) && (retmy != null)) {
		var depdatestr = depday.value + "." + depmy.value;
		var depdatestr = depdatestr.replace(/[^0-9^\.]/g, '');
		var depsplit = depdatestr.split(".");
		var depd = parseInt(depsplit[0], 10);
		var depm = parseInt(depsplit[1] || 0, 10);
		var depy = parseInt(depsplit[2] || 0, 10);
		var depdate = new Date(depy, depm - 1, depd);
		
		var retdatestr = retday.value + "." + retmy.value;
		var retdatestr = retdatestr.replace(/[^0-9^\.]/g, '');
		var retsplit = retdatestr.split(".");
		var retd = parseInt(retsplit[0], 10);
		var retm = parseInt(retsplit[1] || 0, 10);
		var rety = parseInt(retsplit[2] || 0, 10);
		var retdate = new Date(rety, retm - 1, retd);
	
		if (depdate.getTime() > retdate.getTime()) {
			setCalendarDateFields(returningWeekdayId, returningDayId, returningMonthYearId, depday.value + "." + depmy.value);
		}
	}
}

/**
 * Erstellt den Kalender und bindet das Yahoo-Framework ein 
 * @param containerId HTML-Element-ID des Containers, in dem der Kalender erscheinen soll
 * @param imageButtonId HTML-Element-ID des Bildes, welches als Button fÃ¼r den Kalender dient
 * @param idWochentag HTML-Element-ID des Formularfeldes, in das der Wochentag geschrieben werden soll
 * @param idTag HTML-Element-ID des Formularelements (z.B. Drop-Down), dass den Tag enthÃ¤lt
 * @param idMonatJahr HTML-Element-ID des Formularelements, dass den Monat und das Jahr enthÃ¤lt
 * @param mindate Erster erlaubter Tag (tt.mm.jjjj)
 * @param maxdate Letzter erlaubter Tag (tt.mm.jjjj)
 * @param exclude ZeitrÃ¤ume, die nicht erlaubt sind (tt.mm.jjjj-tt.mm.jjjj)
 */
function makeCalendar(containerId, imageButtonId,
                      idWochentag, idTag, idMonatJahr,
                      departureWeekdayId, departureDayId, departureMonthYearId,
                      returningWeekdayId, returningDayId, returningMonthYearId,
                      mindate, maxdate, exclude) {

	/** richtet den Kalender ein */
	YAHOO.util.Event.onDOMReady(function () {
		var imageButton = document.getElementById(imageButtonId);
		var container = document.getElementById(containerId);

		// Kalender verstecken
		container.style.display = 'none';

		// Objekt erzeugen
		var oCalendar = new YAHOO.widget.Calendar("calendar_" + containerId, containerId,
		                                          { LOCALE_WEEKDAYS:"short", LOCALE_MONTHS:"short", START_WEEKDAY: 1, MULTI_SELECT: false, close:true} );

		// Kalender-Parameter einstellen
		oCalendar.cfg.setProperty("DATE_FIELD_DELIMITER", ".");
		oCalendar.cfg.setProperty("MDY_DAY_POSITION", 1);
		oCalendar.cfg.setProperty("MDY_MONTH_POSITION", 2);
		oCalendar.cfg.setProperty("MDY_YEAR_POSITION", 3);
		oCalendar.cfg.setProperty("MD_DAY_POSITION", 1);
		oCalendar.cfg.setProperty("MD_MONTH_POSITION", 2);
		oCalendar.cfg.setProperty("MONTHS_SHORT",   ["Jan", "Feb", "M&auml;r", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"]);
		oCalendar.cfg.setProperty("MONTHS_LONG",    ["Januar", "Februar", "M&auml;z", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"]);
		oCalendar.cfg.setProperty("WEEKDAYS_1CHAR", ["S", "M", "D", "M", "D", "F", "S"]);
		oCalendar.cfg.setProperty("WEEKDAYS_SHORT", ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"]);
		oCalendar.cfg.setProperty("WEEKDAYS_MEDIUM",["Son", "Mon", "Die", "Mit", "Don", "Fre", "Sam"]);
		oCalendar.cfg.setProperty("WEEKDAYS_LONG",  ["Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"]);
		oCalendar.cfg.setProperty("PAGEDATE", YAHOO.util.Dom.get(idMonatJahr).value);
		oCalendar.cfg.setProperty("SELECTED", YAHOO.util.Dom.get(idTag).value + "." + YAHOO.util.Dom.get(idMonatJahr).value);
		oCalendar.cfg.setProperty("MINDATE", mindate);
		oCalendar.cfg.setProperty("MAXDATE", maxdate);
		oCalendar.cfg.setProperty("EXCLUDE", exclude);
		oCalendar.render();

		/** versteckt den Kalender */
		function hideCalendar() {
			YAHOO.util.Event.removeListener(document, "click", clickedOutside);
			container.style.display = 'none';
		}

		/** zeigt bzw. versteckt den Kalender, je nach aktuellem Zustand */
		function toggleShow() {
			var element = container;

			if( element.style.display == 'block' ) {
				hideCalendar();
			} else {

				// wenn Kalender gezeigt wird, Datum aus Formularfeldern holen und in Kalender anzeigen
				oCalendar.cfg.setProperty("PAGEDATE", YAHOO.util.Dom.get(idMonatJahr).value);
				oCalendar.cfg.setProperty("SELECTED", YAHOO.util.Dom.get(idTag).value + "." + YAHOO.util.Dom.get(idMonatJahr).value);
				oCalendar.render();
				element.style.display = 'block';
				YAHOO.util.Event.addListener(document, "click", clickedOutside);
			}
		};

		/**
		 * Diese Funktion wird bei jedem Klick auf die Seite aufgerufen. Wenn der Klick ausserhalb
		 * des Kalenderobjektes erfolgt, den Kalender verstecken.
		 */
		function clickedOutside(ev) {
			var oTarget = YAHOO.util.Event.getTarget(ev);
			var oMenuElement1 = imageButton;
			var oMenuElement2 = container;

			if (oTarget != oMenuElement1 && !YAHOO.util.Dom.isAncestor(oMenuElement1, oTarget) &&
			    oTarget != oMenuElement2 && !YAHOO.util.Dom.isAncestor(oMenuElement2, oTarget))
				hideCalendar();
			
		}

		/**
		 * Diese Listenerfunktion wird an das Kalenderobjekt gebunden und trägt dafür Sorge,
		 * dass bei jeder Auswahl, das Datum auch in die Formularfelder übertragen und der
		 * Kalender dann wieder ausgeblendet wird.
		 */
		oCalendar.selectEvent.subscribe(function (p_sType, p_aArgs) {
			if (p_aArgs) {
				var aDate = p_aArgs[0][0];
				setCalendarDateFields(idWochentag, idTag, idMonatJahr, aDate[2] + "." + aDate[1] + "." + aDate[0]);
				synchronizeDates(departureWeekdayId, departureDayId, departureMonthYearId, returningWeekdayId, returningDayId, returningMonthYearId);
				handleMonatAuswahl(idTag, idMonatJahr, mindate, maxdate);
			}
			toggleShow();
		});

		// ???
		oCalendar.changePageEvent.subscribe(function () {
			window.setTimeout(function () {
				oCalendar.show();
			}, 0);
		});
		
		// Listener auf Button setzen, um den Kalender bei einem Klick zu öffnen.
		YAHOO.util.Event.addListener(imageButton, "click", toggleShow);

	});
}