/**
 * Diese Klasse wird fuer den Belegungskalender benoetigt und stellt sowohl die
 * Editier- als auch die Markierungsfunktionen zur Verfuegung
 *
 * @author Marco
 * @version 0.9
 * @modified: 23.02.2010
 */
var Calendar = new Class({
	initialize: function () {
		if ($('date_pick') != null) {
			$('date_pick').slide('hide');
		}
		if ($(this.infoField) != null) {
			$(this.infoField).slide('hide');
		}
		if( $('calendar_message') != null) {
			$('calendar_message').slide('hide');
		}
                $$("#new_entry input[type=submit]").addEvent('click', function (e) {
                    e.stop();

                    calendar.save(this.name, this.value);
                });
                if ($('general_settings_message') != null) {
                    $('general_settings_message').slide("hide");
                }

                if ($('arrivaldate') != null) {
                    $('arrivaldate').addEvents({
                        keyup: function() {
                            calendar.checkDate();
                        }
                    });
                }

                if ($('general_settings') != null) {
                    $('general_settings').set('slide', {
                        onComplete: function() {
                            if ($('general_settings_link').get('src') == "/images/button_pfeil_down.gif")
                            {
                                $('general_settings_link').set('src', '/images/button_pfeil_up.gif');
                            } else
                            {
                                $('general_settings_link').set('src', '/images/button_pfeil_down.gif');
                            }
                        }
                    });
                }

                if ($('edit_calendar_options') != null) {
                    $('edit_calendar_options').addEvent('submit', function (e) {
                       calendar.saveOptions();
                       e.stop();
                    });
                }

                if ($('year_backward') != null) {
			$('year_backward').addClass('opaque');
                    //$('year_backward').setStyle('opacity', 0.5);
                }
	}
        /**
         * Info Fenster fuer alle Nachrichten bezueglich des Editierens
         */
	
        ,infoField: 'calendarMessage'

        /**
         * falls true ist der ausgewaehlete Zeitraum anreisbar
         */
         ,isValidVaction: true

        /**
         * ausgewaehlter Anreisetermin bzw Starttermin fuer Selektion
         */
	,startDate: new Object()
	,endDate: new Object()

        /**
         * zum nachladen der Jahr wird dieser Wert gebraucht um die
         * Zeit navigierbar zu machen
         */
	,year: 0

        /**
         * uri_base fuer die Ajax-Requests, muss bei initialisierung gesetzt werden,
         * falls diese Requests gebraucht werden
         */
	,uri_base: ""

        /**
         * falls nur ein Betrachter diese Klasse nutzt, muss dieses Flag auf
         * true gesetzt werden, damit dementsprechend ueberpruefungen des
         * Urlaubzeitraums durchgefuehrt werden und nicht versucht wird
         * Sachen abzuspeichern
         */
	,vacationer: false

        /**
         * erstellt eine ID, die die dementsprechnde Tageszahl im Kalender hat
         *
         * @param month integer monat von 1-12
         * @param day integer Tag von 01-31
         * @param year integer vierstellig
         *
         * @return string passend fuer ID
         */
	,generateId: function(month, day, year) {
		var id = 'day_';
                if (month.length == 1) {
                    month = "0"+month;
                }
                if (day.length == 1) {
                    day = "0"+ day;
                }
                if (year.length == 1) {
                    year = "0"+year;
                }
		return id+year+month+day;
	}

        /**
         * markiert zuerst den Starttermin und danach den Enddtermin, passt
         * dabei die Benutzeroberflaeche an und gibt Rueckmeldungen an den Benutzer
         *
         * @param month integer monat von 1-12
         * @param day integer Tag von 01-31
         * @param year integer vierstellig
         */
	,choose: function(month, day, year) {
		var element = this.generateId(month, day, year);
		if (!$chk(this.startDate["year"]) && !$chk(this.endDate["year"])) {
			$('date_pick').set('html', day+'.'+month+'.'+year+' - ');
			$('date_pick').slide('in');
			this.startDate["year"] = year;
			this.startDate["month"] = month;
			this.startDate["day"] = day;
			this.endDate = new Object();
			
			$(element).addClass("calandar_first_selected_day");
			$(element).setStyle('background-image', 'none');
			$('second_step').setStyle('color', '');
                        $('first_step').setStyle('color', 'gray');
			
		} else if (!$chk(this.endDate["year"])) {
			this.endDate["year"] = year;
			this.endDate["month"] = month;
			this.endDate["day"] = day;
			var end = new Date(year, month-1, day);
			var start = new Date(this.startDate["year"], this.startDate["month"]-1, this.startDate["day"]);

			if (end.getTime() < start.getTime()) {
				var copyDay = this.startDate["day"];
				var copyMonth = this.startDate["month"];
				var copyYear = this.startDate["year"];
				this.startDate["year"] = year;
				this.startDate["month"] = month;
				this.startDate["day"] = day;

				this.endDate["day"] = copyDay;
				this.endDate["month"] = copyMonth;
				this.endDate["year"] = copyYear;
			}

			this.fillBetween();
			
			$('date_pick').set('html', this.startDate["day"]+'.'+this.startDate["month"]+'.'+this.startDate["year"]+' - '+
																	this.endDate["day"]+'.'+this.endDate["month"]+'.'+this.endDate["year"]);

                        $('third_step').setStyle('color', '');
                        $('second_step').setStyle('color', 'gray');
			$('submit_avaible').setStyle('color', '');
			$('submit_avaible').set('disabled', false);
			$('submit_occupied').setStyle('color', '');
			$('submit_occupied').set('disabled', false);
			$('submit_unknown').setStyle('color', '');
			$('submit_unknown').set('disabled', false);

			this.fillForm();
		} else {
			this.cleanup(true);
			this.choose(month, day, year);
		}
	}

        /**
         * resettet alle Eingabefelder des Editors
         */
	,cleanup: function() {
		this.fillBetween(true);
		var id = this.generateId(this.startDate['month'], this.startDate['day'], this.startDate['year']);
                if ($(id) != null) $(id).removeClass('calandar_first_selected_day');

		this.endDate = new Object();
		this.startDate = new Object();
                $('first_step').setStyle('color', '');
		$('second_step').setStyle('color', 'gray');
		$('third_step').setStyle('color', 'gray');
		$('submit_avaible').setStyle('color', 'gray');
		$('submit_avaible').set('disabled', true);
		$('submit_occupied').setStyle('color', 'gray');
		$('submit_occupied').set('disabled', true);
		$('submit_unknown').setStyle('color', 'gray');
		$('submit_unknown').set('disabled', true);
                $('date_pick').set('html','');
	}

        /**
         * wichtigste Methode die alle Tage betrachtet und je nach Editor/Ansicht
         * die passende Auswahl markiert, ruft bei Urlauber auch andere Methoden auf
         * um auf Korrektheit des ausgewaehlten Datums zu achten
         *
         * funtkioniert nur, wenn beide Termine markiert sind
         *
         * @param clean boolean bei true wird der markierte Zeitraum von Markierungen befreit
         */
	,fillBetween: function(clean) {
		clean = clean || false;
		if (!$chk(this.startDate["year"]) || !$chk(this.endDate["year"])) return 0;

		var temp = null;
		var year;
		var month;
		var day;
		var stopDay;
		var startMonth;
                var endMonth;
                
		for (year = parseInt(this.startDate["year"], 10); year <= parseInt(this.endDate["year"], 10); year += 1) {
			if (this.startDate["year"] != this.endDate["year"] && year == parseInt(this.endDate["year"], 10)) {
                            startMonth = 1;
                            endMonth = parseInt(this.endDate["month"], 10);
                        } else if (this.startDate["year"] != this.endDate["year"] && year == parseInt(this.startDate["year"], 10)) {
                            endMonth = 12;
                            startMonth = parseInt(this.startDate["month"], 10);
                        } else {
                            startMonth = parseInt(this.startDate["month"], 10);
                            endMonth = parseInt(this.endDate["month"], 10);
                        }


			
			for (month = startMonth; month <= endMonth; month += 1 ) {
                                if (this.startDate["year"] != this.endDate["year"] && year == parseInt(this.endDate["year"], 10)) {
                                    day = 1;
                                    if (month == parseInt(this.endDate["month"],10)) {
                                        stopDay = parseInt(this.endDate["day"], 10);
                                    } else {
                                        stopDay = 31;
                                    }
                                } else if (this.startDate["year"] != this.endDate["year"] && year == parseInt(this.startDate["year"], 10)) {
                                  if (month == parseInt(this.startDate["month"], 10)) {
                                      day = parseInt(this.startDate["day"], 10);
                                      stopDay = 31; 
                                  } else {
                                      day = 1;
                                      stopDay = 31;
                                  }
                                } else if (this.startDate["month"] == this.endDate["month"]) {
                                    day = parseInt(this.startDate["day"], 10);
                                    stopDay = parseInt(this.endDate["day"], 10);
                                } else if (month == parseInt(this.startDate["month"], 10)) {
                                    day = parseInt(this.startDate["day"], 10);
                                    stopDay = 31;
                                } else if (month == parseInt(this.endDate["month"], 10)) {
                                    day = 1;
                                    stopDay = parseInt(this.endDate["day"], 10);
                                } else {
                                    day = 1;
                                    stopDay = 31;
                                }

				for ( ; day <= stopDay; day += 1) {

					temp = 'day_'+year;
					if (month < 10) {
						temp = temp + '0' + month;
					} else {
						temp = temp + month;
					}

					if (day < 10) {
						temp = temp + '0' + day;
					} else {
						temp = temp + day;
					}

					if ($(temp) != null) {
						if (clean) {
                                                        $(temp).removeClass("calendar_selected");
                                                        $(temp).removeClass("calandar_first_selected_day");
							$(temp).setStyle('background-image', '');
                                                        $(temp).setStyle("background-color",'');
						} else {
							$(temp).addClass("calendar_selected");
							$(temp).setStyle('background-image', 'none');
							if (this.vacationer) {
								this.vacationerCheck(temp);
							} 
						}
					}
				}
			}
		}

	}

        /**
         * ueberprueft fuer den Urlauber ob der Tag bereits belegt ist und gibt
         * dementsprechend Rueckmeldung, falls noetig
         *
         * @param element generatID() String
         */
	,vacationerCheck: function ( element) {
            var text = "";
            if (this.isValidVaction) {
               if ($(element).hasClass('calendarOccupiedArrival')
                || $(element).hasClass('calendarOccupied'))
                {
                    text = 'Sie haben bereits belegte Tage ausgew&auml;hlt.';

                }
                if ($(element).hasClass('calandar_first_selected_day')) {
                    var child = $(element).getElement('span');
                    if (child == null || (child != null && !child.hasClass("traveldays"))) {
                        if (text.length != 0) {
                            text = text + "<br />";
                        }
                        text = text + "Der ausgew&auml;hlte Anreisetermin ist ung&uuml;ltig.";
                    }
                }
                if (text.length != 0) {
                    $(this.infoField).set('html',text);
                    $(this.infoField).slide('in');
                    this.isValidVaction = false;
                }
            }
            
	}

        /**
         * fuellt das Formular des Editors zum Javascript basiertem Speichern
         */
	,fillForm: function() {
		if (!$chk(this.startDate["year"]) || !$chk(this.endDate["year"])) return 0;
		
		var startDate = this.startDate["day"]+'.'+this.startDate["month"]+'.'+this.startDate["year"];
		var endDate = this.endDate["day"]+'.'+this.endDate["month"]+'.'+this.endDate["year"];
		
		$('startDate').set('value', startDate);
		$('endDate').set('value', endDate);
	}

        /**
         * falls der Urlauber auf einen Tag klickt wird diese Methode aufgerufen
         * um den Bereich um diesen Tag zu markieren
         *
         * @param month integer monat von 1-12
         * @param day integer Tag von 01-31
         * @param year integer vierstellig
         * @param clicked boolean nur wenn der Tag angeklickt wurde auf true setzen, da
         *                          hier der Tag automatisch im input-Feld gesetzt wird
         *
         * @return boolean immer false, damit keine Linkweiterleitung stattfindet
         */
	,startMarker: function(day, month, year, clicked) {
            var clk = clicked || false;
            var element = this.generateId(month, day, year);
            if ($(element) == null) return false;
            if (!$chk(this.startDate["year"]) && !$chk(this.endDate["year"])) {
                this.startDate["year"] = year;
                this.startDate["month"] = month;
                this.startDate["day"] = day;
                this.endDate = new Object();

                $(element).addClass("calandar_first_selected_day");
                $(element).setStyle('background-image', 'none');

                if (clicked) {
                    $('arrivaldate').set('value', day+'.'+month+'.'+year);
                }

                var duration = parseInt($('calendar_duration').get('value'),10);
                //millisec
                duration = 24*60*60*1000 * (duration);

                var start = new Date(this.startDate["year"], this.startDate["month"]-1, this.startDate["day"]);

                var end = new Date();
                end.setTime(start.getTime() + duration);

                this.endDate["month"] = end.getMonth()+1;
                this.endDate["day"] = end.getDate();
                this.endDate["year"] = end.getFullYear();


                //reset isValidVaction
                this.isValidVaction = true;
                $(this.infoField).set("html", "");
                $(this.infoField).slide('out');
                this.fillBetween();
            } else {
                //reset isValidVaction
                this.isValidVaction = true;
                $(this.infoField).set("html", "");
                $(this.infoField).slide('out');

                this.fillBetween(true);
                this.startDate = new Object();
                this.endDate = new Object();

                this.startMarker(day, month, year, clk);
            }
            return false;
	}

        /**
         * aendert nach Benutzereingabe der Reisedauer die Auswahl im Kalender selbst
         *
         * @param days die neue Anzahl von Tagen, die markiert werden soll
         */
	,changeDuration: function( days ) {
            if ($chk(this.startDate["year"])) {
                    var copyDay = this.startDate["day"];
                    var copyMonth = this.startDate["month"];
                    var copyYear = this.startDate["year"];

                    this.fillBetween(true);
                    this.startDate = new Object();
                    this.endDate = new Object();

                    this.startMarker(copyDay, copyMonth, copyYear, false);
            }
	}

        /**
         * ueberprueft ob das eingegebene Datum als Anreisetermin gueltig ist
         * und ruft die Markierungsmethoden auf
         */
        ,checkDate: function() {
            if ($('arrivaldate') == null) return false;
            var text = $('arrivaldate').get('value');
            if (text == this.text) return false;

            var date = text.split(".");
            if (date.length == 3) {
                var newdate = new Date(date[2], date[1], date[0]);
                if (newdate instanceof Date && isFinite(newdate)) {
                    this.startMarker(date[0], date[1], date[2], false);
                    return true;
                }
            }
            this.text = text;
            return false;
        }

        /**
         * setzt das Vacationer-Flag
         */
	,setVacationer: function (bool) {
		bool = bool || false;
		this.vacationer = bool;
	}

        /**
         * setzt die Jahrezahl ein
         *
         * @param year integer die neue Jahrezahl
         */
	,setYear: function(year) {
	    if (!year) {
	       var now = new Date();
	       this.year = parseInt(now.getFullYear(),10);
	    } else {
	       this.year = year;
	    }
	    return true;
	}

        /**
         * fuer die Requests die uri Basis setzten
         *
         * @param uri string die Basisurl ohne http/www
         */
	,setUriBase: function (uri) {
		this.uri_base = uri;
	}

        /**
         * ruft im Editor das naechste Jahr auf
         *
         */
	,requestNextYear: function () {
	    var now = new Date();
	    if (!$chk(this.year)) {
	    	this.year = parseInt(now.getFullYear(),10);
	    }
	    if (parseInt(now.getFullYear()) + 2 <= this.year) {
	        $('calendar_message').set('html','Sie k&ouml;nnen nicht weiter als 3 Jahre in der Zukunft planen.');
	 		$('calendar_message').slide('in');
	 		(function () {$('calendarMessage').slide('out');}).delay(3000);
	 		//$('year_forward').setStyle('opacity', '0.5');
			$('year_forward').addClass('opaque');
	    } else {
	    	this.year = this.year + 1;
                this.setYearNavigation();
	    	this.runRequest();
	    	//$('year_backward').setStyle('opacity', '1');
		$('year_backward').removeClass('opaque');
	    }
	    return false;
	}

        /**
         * ruft im Editor das vorherige Jahr auf
         */
	,requestPreviousYear: function() {
		var now = new Date();
		if (!$chk(this.year)) {
			this.year = parseInt(now.getFullYear(), 10);
		}
		if (parseInt(now.getFullYear(),10) >= this.year) {
			$('calendar_message').set('html','Der Belegungskalender ist nur f&uuml;r zuk&uuml;nftige Daten verf&uuml;gbar.');
	 		$('calendar_message').slide('in');
	 		(function () {$('calendar_message').slide('out');}).delay(3000);
                     //$('year_backward').setStyle('opacity', '0.5');
			$('year_backward').addClass('opaque');
		} else {    
			//$('year_forward').setStyle('opacity', '1');
			$('year_forward').removeClass('opaque');
			this.year = this.year - 1;
                        this.setYearNavigation();
			this.runRequest();
		}
		return false;
	}
        
        /*
         * setzt die Jahreszahlen in der Navigation um
         */
        ,setYearNavigation: function() {
            if (this.year != null && this.year != 0) {
                $('nextYear').set('html', 'Jahr '+(this.year+1));
                $('previousYear').set('html', 'Jahr '+(this.year-1));
            }
            var now = new Date();
            if (this.year == parseInt(now.getFullYear(), 10)) {
		  $('year_backward').addClass('opaque');
                //$('year_backward').setStyle('opacity', 0.5);
		  $('year_forward').removeClass('opaque');
                //$('year_forward').setStyle('opacity', 1);
            } else if (this.year >= (parseInt(now.getFullYear(), 10)+2)) {
                //$('year_forward').setStyle('opacity', 0.5);
		  $('year_forward').addClass('opaque');
                //$('year_backward').setStyle('opacity', 1);
		  $('year_backward').removeClass('opaque');
            } else {
		  $('year_forward').removeClass('opaque');
                //$('year_forward').setStyle('opacity', 1);
                //$('year_backward').setStyle('opacity', 1);
		  $('year_backward').removeClass('opaque');
            }

            if ($('year_head') != null) {
                $('year_head').set('html', this.year);
            }
        }

        /**
         * fuehrt im editormodus den Request aus und laedt dies in world_calendar herein
         */
	,runRequest: function() {
            var req = new Request.HTML({
                evalScripts: false,
                update: $('world_calendar'),
                onRequest: function() {
                    calendar.ajaxShow();
                },
                onSuccess: function (responseText, responseXML) {
                    if ($('calendar_message') != null && $('calendar_message').get('html').indexOf('Jahr') != -1) {
                        $('calendar_message').set('html', 'Jahr wurde erfolgreich aktualisiert.');
                        $('calendar_message').slide('in');
                        (function () {$('calendar_message').slide('out');}).delay(1500);
                    }
                }
                ,onComplete: function () {
                    calendar.ajaxHide();
                    calendar.setYearNavigation();
                }
            }).get(this.uri_base + '/' + this.year + '/calendar_year.html');
	}

        /**
         * im Urlaubermodus wird diese Methode genutzt um das vorherige Jahr zu laden
         */
        ,viewPrevious: function() {
            var now = new Date();
            if (!$chk(this.year)) {
                this.year = parseInt(now.getFullYear(), 10);
            }
            if (parseInt(now.getFullYear(), 10) >= this.year) {
                $(this.infoField).set('html','Der Belegungskalender ist nur f&uuml;r zuk&uuml;nftige Daten verf&uuml;gbar.');
                $(this.infoField).slide('in');
                (function() {$(calendar.infoField).slide('out');}).delay(3000);
            } else {
                this.year = parseInt(this.year) - 1;
                this.setYearNavigation();
                new Request.HTML({
                    evalScripts: false,
                    update: $('world_calendar'),
                    onRequest: function() {
                        calendar.ajaxShow();
                    },
                    onSuccess: function() {
                        calendar.ajaxHide();
                    }
                }).get(this.uri_base + '/' + this.year + '/' + object_id + '/calendar_public_year.html');
            }
            
        }

        /**
         * im Urlaubermodus wird damit das naechste Jahr geladen
         */
        ,viewNext: function() {
            var now = new Date();
            if (!$chk(this.year)) {
                this.year = parseInt(now.getFullYear(), 10);
            }
            if (parseInt(now.getFullYear(), 10)+2 <= this.year) {
                $(this.infoField).set('html','Der Belegungskalender ist maximal f&uuml;r die n&auml;chsten 2 Jahre verf&uuml;gbar.');
                $(this.infoField).slide('in');
                (function() {$(calendar.infoField).slide('out');}).delay(3000);
            } else {
                this.year = parseInt(this.year) + 1;
                this.setYearNavigation();
                new Request.HTML({
                    evalScripts: false,
                    update: $('world_calendar'),
                    onRequest: function () {
                        calendar.ajaxShow();
                    },
                    onSuccess: function() {
                        calendar.ajaxHide();
                    }
                }).get(this.uri_base + '/' + this.year + '/' + object_id + '/calendar_public_year.html');
            }
        }

        /**
         * speichert den markierten Zeitraum ab
         *
         * @param name string statuscode
         * @param value string statuscode
         */
        ,save: function(name, value) {
            var req = new Request.HTML({
                evalScripts: false,
                update: $('calendar_message'),
                method: "post",
                data: $('new_entry').toQueryString() + "&" + name + "=" + value,
                url: this.uri_base + "/calendar_save.html",
                onRequest: function() {
                    calendar.ajaxShow();
                },
                onSuccess: function (responseText, responseXML) {
                    $('calendar_message').slide('in');
                    (function () {$('calendar_message').slide('hide');}).delay(1500);
                    calendar.runRequest();
                    (function () {calendar.cleanup();}).delay(1000);
                }
            }).send();
            return false;
        }

        /**
         * speichert die allgemeinen Einstellungen ab
         */
        ,saveOptions: function () {
            $('submit_settings').set('disabled', true);
            $('submit_settings').set('value', 'Speichern ...');
            var req = new Request.HTML({
                evalScripts: false,
                method: "post",
                data: $('edit_calendar_options').toQueryString() + "&" + "submit_settings=true",
                update: $('general_settings_message'),
                url: this.uri_base + "/calendar_save.html",
                onSuccess: function (responseText, responseXML) {
                    $('submit_settings').setStyle('display', 'none');
                    $('general_settings_message').slide('in');
                    (function () {
                        $('general_settings_message').slide('out');
                        $('general_settings').slide('out');
                    }).delay(2000);
                    (function () {
                        $('submit_settings').set('disabled', false);
                        $('submit_settings').setStyle('display', 'block');
                        $('submit_settings').set('value', 'Speichern');
                    }).delay(2500);
                },
                onError: function () {
                    alert("Fehler im Speichervorgang")
                }
            }).send();
            return false;
        }

        /**
         * zeigt das GIF-Bild an
         */
        ,ajaxShow: function() {
            if ($('ajax-loader') != null) {
                $('ajax-loader').setStyle('visibility', 'visible');
            }
        }

        /**
         * laesst das GIF-Bild vershwinden
         */
        ,ajaxHide: function() {
            var loader = $('ajax-loader');
            if (loader != null) {
                (function () {$('ajax-loader').setStyle('visibility', 'hidden')}).delay(700);
            }
        }
});
