/* **********************************************************************************
 * Das Modul stellt Funktionen, Eventhandler und Variablen und einen Background 
 * Worker für die automatische	Berechnung zur Verfügung. Das Modul wird in der
 * HTML Datei und Hauptprogramm "Zeitberechnung.html" aus dem Verzeichnis 
 * "Sonne-Mond" geladen.
 *
 * The module provides functions, event handlers and variables and a background 
 * Worker available for automatic calculation. The module is available in the
 * HTML file and main program “Time Calculation.html” from the directory 
 * “Sun-Moon” loaded.
 ********************************************************************************** */

var VELOSITY = 0;					// Geschwindigkeit mit der der nächste Wert berechnet wird.
												// Speed with which the next value is calculated.
var TIMELAPS = 0.0;				// Zeitsprung für Zeitraffer, für die Iterationen in der Berechnung der Werte.
												// Time jump for time lapse, for the iterations in the calculation of the values.
var TIMEZONE = 0;					// Zeitzone und DST bei automatischer Berechnung
												// Time zone and DST with automatic calculation
var DELAY = 0;						// Variable für die Wartezeit bei den Berechnungen (Hier Ausgabe)
												// Variable for the waiting time for the calculations (Here Output) 
var da = "";								// Variable für das aktuelle Datum der automatischen Berechnungen.
												// Variable for the current date of the automatic calculations.
var wAutomaticTime;				// Background Worker Variable für das Overlay.
												// Background Worker Variable for the overlay.
var channel = null;					// Variable des Broadcast Channel zum Hauptprogramm und back.
												// Variable of the Broadcast Channel to the main program and back.
var channelExtern  = null;		// Variable des Bradcast Channel zum Ausgabefenster und back.
												// Variable of the Bradcast channel to the output window and back.
var checkboxUntilDateIsClicked = 0;// "Bis zu Datum" ist markiert oder demarkiert
												// “Until date” is marked or marked
var workerActualEndless;		// Zeigt an das der Worker "Mit aktuellem Datum" aktiv ist
												// Shows that the worker “With current date” is active
var workerChoiceEndless;		// Zeigt an das der Worker "Ab gewähltem Datum" aktiv ist
												// Shows that the worker “With current date” is active
var popup = null;						// Objekt des externen Daten Ausgabefenster
												// Object of external data Output window
// Einen neuen Broadcast Channel erstellen.
// Nachrichtenkanal Zum Hauptprogramm "Zeitberechnung.html"
// Create a new broadcast channel.
// Message channel To the main program “Time calculation.html”
channel = new BroadcastChannel ("com");
// Nachrichtenkanal Zum Textausgabefenster "Output.html"
// Message 4 Go to text output window “Output.html”
channelExtern = new BroadcastChannel ("comExtern");

/* ******************************************************
	Die Funktion öffnet ein neues Bowserfenster das
	extern ist. Es handelt sich um keinen Tab.
	
	Übergabewert:
	--------------------
		url					=	Der Pfad relativ oder absolut zur
									HTML Quelldatei als String
		windowName	=	Beliebiger Name als String
		width				= Breite des Fensters in Pixel und Integer
		height				= Höhe des Fensters in Pixel und Integer
	
	Rückgabewert:
	---------------------
		popup				=	Objekt auf das Fenster. Dient zum Schliessen.
	----------------------------------------------------------------
	The function opens a new bowser window which
	is external. It is not a tab.
	
	Transfer value:
	--------------------
		url    = The path relative or absolute to the
									HTML source file as string
		windowName = arbitrary name as string
		width    = Width of the window in pixels and integer
		height    = Height of the window in pixels and integer
	
	Return value:
	---------------------
		popup    = Object on the window. It’s for closing.
   *************************************************** */
var browserX;
var browserY = (screen.height / 2) - 130;			
var popup_window;
function openNew(url, windowName, width, height){
	browserX = (screen.width / 2) - (width / 2);
	browserY = (screen.height / 2) - (height / 2);
	popup_window = false;

	if ( (popup_window == false) || (popup_window.closed == true) ){
		popup_window = window.open(url ,windowName, "screenx=" + browserX + ", screeny=" + browserY + ", toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width=" + width + ", height=" + height + "" );
		if (popup_window == null)
			alert("Pop-up Blocker ist eingeschaltet! \n Bitte füge diese Seite zur Erlaubtliste des Browsers hinzu!");
		else
			popup_window.document.title = windowName;
	}
	popup_window.focus();
	return popup_window;
	
}// End of openNew()

			

//	Objekte automatische Berechnung "Mit aktuellem Datum" im Overlay.	
//	Objects automatic calculation “With current date” in the overlay.
//	Radio Button ...
var objCalcActualDate = document.getElementById("calcActualDateAutomatic");
// Startdatum - Start date... 
var objCalcActualDateAutomatic = document.getElementById("dateAutomatic");
// Stunde und Minute - Hour and minute ...
var objCalcActualTimeAutomatic = document.getElementById("timeAutomatic");
// Sekunde - Second ...
var objCalcActualSecondAutomatic = document.getElementById("secondAutomatic");
// Millisekunde - Millisecond ...
var objCalcActualMSecondAutomatic = document.getElementById("msecondAutomatic");


// Objekt automatische Berechnung "Ab gewähltem Datum" Overlay.	
//
// Object automatic calculation “From selected date” Overlay.	
//
var objCalcChoiceDateAutomatic = document.getElementById("calcChoiceDateAutomatic");
var objChoiceDateAutomatic = document.getElementById("choiceDateAutomatic");
var objCalcChoiceTimeAutomatic = document.getElementById("choiceTimeAutomatic");
var objCalcChoiceSecondAutomatic = document.getElementById("choiceSecondAutomatic");
var objCalcChoiceMSecondAutomatic = document.getElementById("choiceMsecondAutomatic");


// Objekt automatische Berechnung "Bis gewähltem Datum" Overlay.	
// 
// Object automatic calculation “Until selected date” Overlay.	
//
var objCalcUntilDateAutomatic = document.getElementById("calcUntilDateAutomatic");
var objUntilDateAutomatic = document.getElementById("untilDateAutomatic");
var objCalcUntilTimeAutomatic = document.getElementById("untilTimeAutomatic");
var objCalcUntilSecondAutomatic = document.getElementById("untilSecondAutomatic");
var objCalcUntilMSecondAutomatic = document.getElementById("untilMsecondAutomatic");


// Objekt automatische Berechnung "Zeitsprung"
//	
// Object automatic calculation “Time jump”
//
// Stunden - Hours
var objCalcActualDateHour = document.getElementById("calcActualDateHour");
// Minuten - Minutes
var objCalcActualDateMinute = document.getElementById("calcActualDateMinute");
// Sekunden - Seconds
var objCalcActualDateSecond = document.getElementById("calcActualDateSecond");
// Millisekunden - Milliseconds
var objCalcActualDateMillisecond = document.getElementById("calcActualDateMillisecond");


// Objekt automatische Berechnung Geschwindigkeit der nächsten Berechnung.
//
// Object automatic calculation Speed of the next calculation.
var objVelosity = document.getElementsByClassName("velosity")[0];


 // Objekte der beiden Buttons "Abbrechen" und "Berechnen der automatischen Berchnung
 // bei Klick auf den Radio Button "Automatisch".
 //
 // Objects of the two buttons “Cancel” and “Calculate the automatic calculation
 // by clicking on the radio button “Automatic.”
var objAutoCancel = document.getElementById("autoCancel");	
var objAutoCalc = document.getElementById("autoCalc");


// Klick auf den Radio Knopf "Abgewähltem Datum".
// Click on the radio button “Selected date.”
objCalcChoiceDateAutomatic.addEventListener("click", function(){
	// Aktuelles Datum in den Date Picker einlesen ...
	// Read the current date in the Date Picker ...
	objChoiceDateAutomatic.valueAsDate = new Date() ;
	// ... und bedienbar machen ...
	// ... and make it usable ...
	objChoiceDateAutomatic.disabled = false;
});

//	Event Listener automatische Berechnung "Mit aktuellem Datum".
//	Ausgelöst bei einem Klick auf den Radio Button.
//
// Event Listener automatic calculation “With current date.”
// Triggered by clicking on the radio button.
objCalcActualDate.addEventListener ("click", function () {
	// Die Geschwindigkeit auf Startwert setzen.
	// Set the speed to start value.
	objVelosity.value = 500;
	// Alle Eingabeboxen "Ab gewähltem Datum" zurücksetzen
	// Reset all input boxes “From selected date”
	objCalcChoiceDateAutomatic.checked = false;
	objCalcChoiceDateAutomatic.value = "";
	objCalcChoiceTimeAutomatic.value = "00:00";
	objCalcChoiceSecondAutomatic.value = "0";
	objCalcChoiceMSecondAutomatic.value = "0";
	// Alle Eingabeboxen "Ab gewähltem Datum" unbedienbar gemacht ...
	// All input boxes “From selected date” made unusable ...
	objChoiceDateAutomatic.disabled = true;
	objCalcChoiceTimeAutomatic.disabled = true;
	objCalcChoiceSecondAutomatic.disabled = true;
	objCalcChoiceMSecondAutomatic.disabled = true;
	// Alle Eingabeboxen "Bis zum Datum" Zurücksetzen ...
	// All input boxes “To date” Reset ...
	objCalcUntilDateAutomatic.checked = false;
	objUntilDateAutomatic.value = "";
	objCalcUntilTimeAutomatic.value = "00:00";
	objCalcUntilSecondAutomatic.value = "0";
	objCalcUntilMSecondAutomatic.value = "0";
	// Alle Eingabeboxen "Bis zum Datum" unbedienbar machen ...
	// Make all input boxes “Until date” unusable ...
	objUntilDateAutomatic.disabled = true;
	objCalcUntilTimeAutomatic.disabled = true;
	objCalcUntilSecondAutomatic.disabled = true;
	objCalcUntilMSecondAutomatic.disabled = true;
	// Datenfelder für den Zeitsprung zugänglich machen 
	// Make data fields accessible for the time jump
	// Stunden - Hours
	objCalcActualDateHour.disabled	= true;
	// Minuten - Minutes
	objCalcActualDateMinute.disabled	= true;
	// Sekunden - Seconds
	objCalcActualDateSecond.disabled	= true;
	// Millisekunden - milliseconds
	objCalcActualDateMillisecond.disabled	= true;
	// Den Worker "worker-automatic-actauldate-endless.js" für Datum ab Aktuellem des Overlays starten
	// Start the worker  "worker-automatic-actauldate-endless.js" for date from the current of the overlay
	startWorker();
	
});// End of objCalcActualDate.addEventListener ()



// Event Listener automatische Berechnung "Ab Gewähltem Datum"
// Event Listener Automatic Calculation “From Selected Date”
objCalcChoiceDateAutomatic.addEventListener ("click", function () {
	// Radio Button "Ab aktuellem Datum" demarkieren
	// Demark radio button “From current date”
	objCalcActualDate.checked = false;
	// Alle Eingabeboxen bedienbar machen
	// Make all input boxes operable
	objCalcChoiceDateAutomatic.disabled = false;
	objCalcChoiceTimeAutomatic.disabled = false;
	objCalcChoiceSecondAutomatic.disabled = false;
	objCalcChoiceMSecondAutomatic.disabled = false;
	// Datenfelder für den Zeitsprung zugänglich machen 
	// Make data fields accessible for the time jump
	// Stunden - Hours
	objCalcActualDateHour.disabled = false;
	// Minuten - Minutes
	objCalcActualDateMinute.disabled = false;
	// Sekunden - Seconds
	objCalcActualDateSecond.disabled = false;
	// Millisekunden - milliseconds
	objCalcActualDateMillisecond.disabled = false;
	
});// End of objCalcChoiceDateAutomatic.addEventListener()



//	Event Listener Overlay automatische Berechnung "Bis Gewähltem Datum"
//	Event Listener Overlay Automatic Calculation “Until Selected Date”
objCalcUntilDateAutomatic.addEventListener ("click", function () {
		// Den Datums Picker "Bis zum Datum" mit aktuellem Datum versorgen ...
		// Provide the date picker “Until Date” with the current date ...
		objUntilDateAutomatic.valueAsDate = new Date();
		// Checkbox ist markiert ...
		// Checkbox is marked ...
		if (objCalcUntilDateAutomatic.checked == true){
			//	Alle Eingabeboxen "Bis gewähltem Datum" BEDIENBAR machen und Löschen
			//	Make all input boxes “Until selected date” OPENABLE and delete
			objUntilDateAutomatic.disabled = false;
			objCalcUntilTimeAutomatic.disabled = false;
			objCalcUntilSecondAutomatic.disabled = false;
			objCalcUntilMSecondAutomatic.disabled = false;
		// Checkbox ist nicht markiert ...
		// Checkbox is not marked ...
		}else{
			//	Alle Eingabeboxen "Bis gewähltem Datum" UNBEDIENBAr machen und Löschen ...
			//	Make and delete all input boxes “Until selected date” ...
			objUntilDateAutomatic.disabled = true;
			objCalcUntilTimeAutomatic.disabled = true;
			objCalcUntilSecondAutomatic.disabled = true;
			objCalcUntilMSecondAutomatic.disabled = true;
			objUntilDateAutomatic.value = "";
			objCalcUntilTimeAutomatic.value = "00:00";
			objCalcUntilSecondAutomatic.value = "0";
			objCalcUntilMSecondAutomatic.value = "0";
		}

}); // End of objCalcUntilDateAutomatic.addEventListener()



//	Eventhandler für Klick auf "Abbrechen" im Overlay
//	Event handler for click on “Cancel” in the overlay
objAutoCancel.addEventListener("click", function () {
	// Wenn der Worker für die Berchnung "Ab aktuellem Datum" endlos läuft,
	// dann stoppe Ihn
	// If the worker for the calculation “From current date” runs endlessly,
	// then stop him
	if (workerActualEndless) stopWorkerActualDateEndless();
	if (workerChoiceEndless) stopWorkerChoiceDateEndless();
	// Wert für die Markierung der Checkbox "Bis zum Datum" auf 0 setzen ...
	// Set the value for the marking of the checkbox “Until Date” to 0 ...
	checkboxUntilDateIsClicked = 0;
	checkboxUntilDateIsClicked = 0;
	// "Ab gewähltem Datum" alles Löschen
	// “From selected date” delete all
	if (objCalcChoiceDateAutomatic.checked == true){
		objCalcChoiceDateAutomatic.checked = false;
		objCalcActualDateAutomatic.checked = true;
	}
	// Radio Knopf "Automatisch" im Hauptprogramm Löschen
	// Radio button “Automatic” in the main program Delete
	if (objCalcAutomatic.checked == true){
		objCalcAutomatic.checked = false;
	}
	// "Bis zum Datum" alles Löschen
	// “Until date” delete all
	if (objCalcUntilDateAutomatic.checked){
		objCalcUntilDateAutomatic.value = "";
		objUntilDateAutomatic.disabled = true;
		objCalcUntilTimeAutomatic.disabled = true;
		objCalcUntilSecondAutomatic.disabled = true;
		objCalcUntilMSecondAutomatic.disabled = true;
		objCalcUntilDateAutomatic.checked = "";
		objUntilDateAutomatic.value = "";
		objCalcUntilTimeAutomatic.value = "00:00";
		objCalcUntilSecondAutomatic.value = "0";
		objCalcUntilMSecondAutomatic.value = "0";		
	}
	// Datenfelder für den Zeitsprung Löschen und unbedienbar machen
	// Data fields for the time jump Delete and make them unusable
	// Stunden - Hours
	objCalcActualDateHour.disabled = true;
	objCalcActualDateHour.value = "0";
	// Minuten - Minutes
	objCalcActualDateMinute.disabled = true;
	objCalcActualDateMinute.value = "0";
	// Sekunden - Seconds
	objCalcActualDateSecond.disabled = true;
	objCalcActualDateSecond.value = "0";
	// Millisekunden - milliseconds
	objCalcActualDateMillisecond.disabled = true;
	objCalcActualDateMillisecond.value = "0";
	objShowAnimation.disabled = true;				// Checkbox "Animation" unbedienbar machen
																		// Make “Animation” checkbox unoperable
	objShowDataOutput.disabled = false;			// Checkbox "Datenausgabe" bedienbar machen
																		// Make “Datenausgabe” checkbox unoperable
	objCalcStop.disabled = true;						// Stop Button für die automatische Berechnung deaktivieren
	objCalcManual.checked = "checked";			// Radio Button Manuelle Berechnung aktivieren.
	objCalcAutomatic.checked = "";					// Radio Button Automstiach berechnung deaktivieren.
	divAutomatic.style.visibility = "hidden";			// Auswahl Div automatische Berechnung wegschalten.
	objCalc.disabled = false;								// Button Manuell "Berechnen" aktivieren.
	eraseOutputFields();									// Die Ausgabefelder löschen.
	enableDateTimePicker();								// Datums und Zeitpicker einschalten.
	setActualDateAndTime();								// Aktuelles Datum und Uhrzeit als Startdatum setzen.
	if (wAutomaticTime) stopWorker();				// Stopt den Worker für das Datum Overlay.
	
}); // End of objAutoCancel.addEventListener()




/*	*********************************************************************************************************
	Eventhandler für Klick auf "Berechnen" im Overlay.
	Hier wird über die Funktion  "startWorkerActualEndless(TIMELAPS, VELOSITY, TIMEZONE, startDate, endDate)" der 
	Webworker "worker-automatic-actualdate-endless.js" gestopt und gestartet. Der Webworker
	für das Overlay "worker-automatictime.js" wird hier erstellt und über die Funktion "stopWorker()"
	gestoppt, wenn auf den Button "Berechnen" geklickt wird.
	Ebenso die Funktion "startWorkerChoiceEndless(TIMELAPS, VELOSITY, TIMEZONE, valueVirtualDateJD, 0);",
	die eine simultierte Berechnung ab einem gewählten Datum und bis zu einem gewählten Datum ermöglicht.
	---------------------------------------------------------------------------------------------------------------------------------
	Event handler for click on “Calculate” in the overlay.
	Here the function “startWorkerActualEndless (TIMELAPS, VELOSITY, TIMEZONE, startDate, endDate) “ 
	Webworker “worker-automatic-actualdate-endless.js” stopped and started. The Webworker
	for the overlay “worker-automatictime.js” is created here and via the function “stopWorker () “
	stopped when the “Calculate” button is clicked.
	Also the function “startWorkerChoiceEndless (TIMELAPS, VELOSITY, TIMEZONE, valueVirtualDateJD, 0);”,
	which allows a simulated calculation from a selected date up to a selected date.
	******************************************************************************************************* */
objAutoCalc.addEventListener("click", function () {
	eraseOutputFields();							// Alle Ausgabefelder Löschen.
	divAutomatic.style.visibility = "hidden";	// Auswahl Div automatische Berechnung wegschalten.
	setActualDateAndTime();						// Aktuelles Datum und Uhrzeit als Startdatum setzen.
	objCalcManual.disabled = true;			// Radio Button "Manuell" bedienbar machen
																// Make radio button “Manuell” unoperable
	objCalcAutomatic.disabled = true;		// Radio Button "Automatisch" bedienbar machen
																// Make radio button “Automatisch” unoperable
	// Neues aktuelles MS Datumsobjekt  erstellen ...
	// Create a new current MS Date Object ...
	var d = new Date();
	// ... und dies in das Julianische Startdatum konvertieren ...
	// ... and convert this to the Julian start date ...
	var jdStartdate = calcJD(d.getDate(), d.getMonth(), d.getYear(), d.getHours(), d.getMinutes(), d.getSeconds(), d.getMilliseconds(),  0, 0);
	// Mit aktuellem PC Datum soll berechnet werden ...
	// ohne ein Enddatum endlos
	// With current PC date should be calculated ...
	// endless without an end date
	if (objCalcActualDate.checked == true && (objCalcUntilDateAutomatic.checked == false) ){	
		VELOSITY = objVelosity.value;
		document.getElementById("msvelosity").value = VELOSITY;
		document.getElementById("mstimelaps").value = "N/A";
		// Stop Button der automatischen Berechnung enablen
		// Stop button of automatic calculation enablen
		objCalcStop.disabled = false;
		// Stoppt den Worker für das Datum Overlay.
		// Stops the worker for the date overlay.
		if (wAutomaticTime) stopWorker();
		// Popup Fenster für Datenausgabe beim Laden des primären Fensters öffnen ...
		// Open popup window for data output when loading the primary window ...
		if (objShowDataOutput.checked == true)  popup = openNew("./outputData.html", "outputData", 970, 820);
		// Checkbox "Datenausgabe" unbedienbar machen
		// Make “Datenausgabe” checkbox unoperable
		objShowDataOutput.disabled = true;	
		// Den Background Worker für die Berechnung über die aktuelle Uhrzeit erstellen und starten
		// Create and start the background worker for the calculation about the current time
		startWorkerActualEndless(TIMELAPS, VELOSITY, TIMEZONE,  jdStartdate, 0);
	// Mit aktuellem PC Datum soll berechnet werden
	// bis zu einem Enddatum, das natürlich größer sein muss als das aktuelle Datum ...
	// With current PC date should be calculated
	// up to an end date, which of course must be greater than the current date ...
	}else if( (objCalcActualDate.checked == true) && (objCalcUntilDateAutomatic.checked == true) ){
		document.getElementById("mstimelaps").value = "N/A";
		// Das Startdatum in Millisekunden seit dem 1.1.1970 ...
		// Start date in milliseconds since 1.1.1970 ...
		var startDate = jdStartdate;
		// Das Enddatum in Millisekunden seit dem 1.1.1970 ...
		// End date in milliseconds since 1.1.1970 ...
		var endDate = 0;
		// Das Date Picker "Bis zum Datum" muss einen gültigen Datumswert haben, ebenso der Zeitpicker für Stunde:Minute,
		// die Sekundeneingabe und Millisekundeneingabe ...
		// The date picker “To Date” must have a valid date value, as must the time picker for hour:Minute,
		// the second and millisecond input ...
		if (objUntilDateAutomatic.value != "" && objCalcUntilTimeAutomatic.value != "" &&
			objCalcUntilSecondAutomatic.value != "" && objCalcUntilMSecondAutomatic.value != ""){
			// ... und dann das Enddatum in Millisekunden berechnen ...
			// ... and then calculate the end date in milliseconds ...
			endDate = objUntilDateAutomatic.valueAsNumber + objCalcUntilTimeAutomatic.valueAsNumber + 
							(objCalcUntilSecondAutomatic.valueAsNumber * 1000)  + objCalcUntilMSecondAutomatic.valueAsNumber;
			// ... und da die Datums/Zeit Eingabeelemente die Zeitzone und Sommer/Winterzeit
			// beim Auslesen der Werte mit berücksichtigen, müssen diese auf die angezeigte
			// Zeit korregiert werden ...
			// ... and since the date/time input elements the time zone and summer/winter time
			// when reading the values, they must be taken into account on the displayed
			// Time to be corrected ...
			endDate += (TIMEZONE * (3600 * 1000));
			var ed = new Date(endDate);
			var jdEndDate = calcJD(ed.getDate(), ed.getMonth(), ed.getFullYear(), ed.getHours(), ed.getMinutes(), ed.getSeconds(), ed.getMilliseconds(),  0, 0);
			// ... das Enddatum muss natürlich größer sein als das Startdatum ...
			// ... the end date must of course be larger than the start date ...
			if (jdEndDate > jdStartdate){
				VELOSITY = objVelosity.value;
				document.getElementById("msvelosity").value = VELOSITY;
				document.getElementById("mstimelaps").value = "N/A";
				// ... Stop Button der automatischen Berechnung enablen ...
				// ... Stop button of automatic refraction enablen ...
				objCalcStop.disabled = false;
				// ... Stoppt den Worker für das Datum Overlay, wenn er aktiv ist ...
				// ... Stops the worker for the date overlay when active ...
				if (wAutomaticTime) stopWorker();
				// ... Popup Fenster für Datenausgabe beim Laden des primären Fensters öffnen ...
				// ... Open popup window for data output when loading the primary window ...
				if (objShowDataOutput.checked == true) popup = openNew("./outputData.html", "outputData", 970, 820);
				// Checkbox "Datenausgabe" unbedienbar machen
				// Make “Datenausgabe” checkbox unoperable
				objShowDataOutput.disabled = true;																			
				// ... dann den Background Worker "worker-automatic-actualdate-endless.js" 
				// für die Berechnung über die aktuelle Uhrzeit erstellen und starten.
				//
				// ... then the background worker “worker-automatic-actualdate-endless.js” 
				// create and start the calculation about the current time.
				startWorkerActualEndless(TIMELAPS, VELOSITY, TIMEZONE, jdStartdate, jdEndDate);
			// ... wenn Enddatum kleiner ist als Startdatum dann eine Meldung ausgeben.
			// ... if end date is smaller than start date then output a message.
			}else{
				alert("Keine Berechnungen, da das Enddatum vor dem Startdatum liegt!");
			}
		// ... Es muss ein Datum im Picker "Bis zum Datum" ausgewählt werden ... ansonsten wird eine Fehlermeldung ausgegeben ...
		// ... A date must be selected in the picker “Until Date” ... otherwise an error message will be displayed ...
		}else{
			alert("Error bei der Datumseingabe:\nEs ist kein Datum vorhanden!\nBitte wählen Sie ein gültiges Datum.");
		}
	// Ab gewähltem Datum soll simuliert endlos berechnet werden ...
	// From the selected date, simulated endless calculation should be performed ...
	}else if ( (objCalcChoiceDateAutomatic.checked == true) && (objCalcActualDate.checked == false) && (objCalcUntilDateAutomatic.checked == false) ){	
		// Wenn der Date Picker, Time Picker, Sekunden Eingabe und Millisekunden Eingabe nicht leer sind ...
		// If the Date Picker, Time Picker, Seconds input and Millisecond input are not empty ...
		if (objChoiceDateAutomatic.value != "" && objCalcChoiceTimeAutomatic.value != "" &&
			objCalcChoiceSecondAutomatic.value != "" && objCalcChoiceMSecondAutomatic.value != ""){
			VELOSITY = objVelosity.value;
			document.getElementById("msvelosity").value = VELOSITY;
			document.getElementById("mstimelaps").value = "N/A";
			// Dann die Zeit für den Zeitsprung ermitteln. Dies ist die Zeit, die nach jedem Delay zum aktuellen
			// Uhrzeitwert hinzugezählt wird, um die Animation zu beschleunigen. Dies wird als Teil an einem
			// Tag = 24 h berechnet. Ermöglicht das rechnen mit dem Julianischen Datum.
			// Then determine the time for the time jump. This is the time after each delay to the current
			// Time value is added to speed up the animation.This is done as part of a
			// day = 24 hours calculated. Allows you to calculate with the Julian date.
			if ( objCalcActualDateHour.value >= 0 ) TIMELAPS += Math.abs(objCalcActualDateHour.value/24);
			if ( objCalcActualDateMinute.value >= 0 ) TIMELAPS += Math.abs(objCalcActualDateMinute.value/1440);
			if ( objCalcActualDateSecond.value >= 0 ) TIMELAPS += Math.abs(objCalcActualDateSecond.value/86400);
			if ( objCalcActualDateMillisecond.value >= 0 ) TIMELAPS += Math.abs(objCalcActualDateMillisecond.value/86400000);
			document.getElementById("mstimelaps").value = TIMELAPS;
			// ... und dann vom Date Picker das Startdatum in Jahr, Monat und Tag aufsplitten ...
			// Index [0] =	Jahr
			// Index [1] =	Monat
			// Index [2] =	Tag...
			//
			// ... and then split the start date into year, month and day from the date picker ...
			// Index [0] = year
			// Index [1] = month
			// Index [2] = day..
			var yearMonthDay = objChoiceDateAutomatic.value.split("-");
			// ... sowie vom Time Picker Stunde und Minute aufsplitten ...
			// Index [0] =	Stunde
			// Index [1] =	Minute
			//
			// ... and split hour and minute from the Time Picker ...
			// Index [0] = hour
			// Index [1] = minute
			var hourMinute = objCalcChoiceTimeAutomatic.value.split(":");
			var second = objCalcChoiceSecondAutomatic.value;
			var msecond = objCalcChoiceMSecondAutomatic.value;
			// ... und dann das Julianische Datum der Lokalzeit für den Starttermin aus den Eingabeelementen:
			// Ganzahlanteil sind die Tage und der Nachkommaanteil die Uhrzeit des Tages ...
			//
			// and then the Julian date of the local time for the start date from the input elements:
			// Whole fraction is the days and the decimal fraction is the time of the day ...
			var valueVirtualDateJD = calcJD(Number(yearMonthDay[2]),Number(yearMonthDay[1]),
																Number(yearMonthDay[0]), Number(hourMinute[0]), Number(hourMinute[1]),
																Number(second), Number(msecond),  0, 0);
			// ... Stop Button der automatischen Brechnung bedienbar machen ...
			// ... Stop button of automatic calculation operable ...
			objCalcStop.disabled = false;
			// ... Stoppt den Worker für das Datum Overlay, wenn er aktiv ist ...
			// ... Stops the worker for the date overlay when active ...
			if (wAutomaticTime) stopWorker();
			// ... Popup Fenster für Datenausgabe beim Laden des primären Fensters öffnen ...
			// ... Open popup window for data output when loading the primary window ...
			if (objShowDataOutput.checked == true)  popup = openNew("./outputData.html", "outputData", 970, 820);
			// Checkbox "Datenausgabe" unbedienbar machen
			// Make “Datenausgabe” checkbox unoperable
			objShowDataOutput.disabled = true;
			// ... dann den Background Worker "worker-automatic-choicedate-endless.js" 
			// für die Berechnung über die aktuelle Uhrzeit erstellen und starten.
			//
			// ... then the background worker “worker-automatic-choicedate-endless.js” 
			// create and start the calculation about the current time.
			startWorkerChoiceEndless(TIMELAPS, VELOSITY, TIMEZONE, valueVirtualDateJD, 0);
		// ... Es muss ein Datum mit Uhrzeiten im Picker "Ab gewähltem  Datum" ausgewählt werden ... ansonsten wird eine Fehlermeldung ausgegeben ...
		// ... A date with times must be selected in the picker “From selected date” ... otherwise an error message will be displayed ...
		}else{
			alert("Error bei der Datumseingabe:\nEs ist kein Datum vorhanden!\nBitte wählen Sie ein gültiges Datum.");
		}
	// Ab gewähltem Datum bis zu einem Enddatum soll simuliert endlos berechnet werden ...
	// From selected date up to an end date simulated endless calculation should be performed ...
	}else if ((objCalcChoiceDateAutomatic.checked == true) && (objCalcUntilDateAutomatic.checked == true) && (objCalcActualDate.checked == false) ){
		// Wenn die Date Picker, Time Picker, Sekunden Eingabe und Millisekunden Eingabe von "Ab gewähltem Datum" und "Bis zum Datum" 
		// nicht leer sind berechne ...
		// If the Date Picker, Time Picker, Seconds Input and Milliseconds Input of “From Selected Date” and “To Date” 
		// not empty are calculated ...
		if ( (objUntilDateAutomatic.value != "" && objCalcUntilTimeAutomatic.value != "" &&
			objCalcUntilSecondAutomatic.value != "" && objCalcUntilMSecondAutomatic.value != "")  &&
			(objChoiceDateAutomatic.value != "" && objCalcChoiceTimeAutomatic.value != "" &&
			objCalcChoiceSecondAutomatic.value != "" && objCalcChoiceMSecondAutomatic.value != "") ){
				VELOSITY = objVelosity.value;
				document.getElementById("msvelosity").value = VELOSITY;
				document.getElementById("mstimelaps").value = "N/A";
				/* **************************************** Startdatum ********************************************* */
				// ... und dann vom Date Picker das Startdatum in Jahr, Monat und Tag aufsplitten ...
				// Index [0] =	Jahr
				// Index [1] =	Monat
				// Index [2] =	Tag...
				//
				// ... and then split the start date into year, month and day from the date picker ...
				// Index [0] = year
				// Index [1] = month
				// Index [2] = day..
				var yearMonthDay = objChoiceDateAutomatic.value.split("-");
				// ... sowie vom Time Picker Stunde und Minute aufsplitten ...
				// Index [0] =	Stunde
				// Index [1] =	Minute
				//
				// ... and split hour and minute from the Time Picker ...
				// Index [0] = hour
				// Index [1] = minute
				var hourMinute = objCalcChoiceTimeAutomatic.value.split(":");
				var second = objCalcChoiceSecondAutomatic.value;
				var msecond = objCalcChoiceMSecondAutomatic.value;
				// und dann das Julianische Datum der Lokalzeit für den Starttermin aus den Eingabeelementen:
				// Ganzahlanteil sind die Tage und der Nachkommaanteil die Uhrzeit des Tages ...
				// and then the Julian date of the local time for the start date from the input elements:
				// Whole fraction is the days and the decimal fraction is the time of the day ...
				var valueVirtualStartDateJD = calcJD(Number(yearMonthDay[2]),Number(yearMonthDay[1]),
																			 Number(yearMonthDay[0]), Number(hourMinute[0]), Number(hourMinute[1]),
																			 Number(second), Number(msecond),  0, 0);
				/* **************************************** Ende Startdatum ********************************************* */
				// ... und dann vom Date Picker das Bis Datum in Jahr, Monat und Tag aufsplitten ...
				// Index [0] =	Jahr
				// Index [1] =	Monat
				// Index [2] =	Tag...
				//
				// ... and then split the start date into year, month and day from the date picker ...
				// Index [0] = year
				// Index [1] = month
				// Index [2] = day..
				var yearMonthDay2 = objUntilDateAutomatic.value.split("-");
				// ... sowie vom Time Picker Stunde und Minute aufsplitten ...
				// Index [0] =	Stunde
				// Index [1] =	Minute
				//
				// ... and split hour and minute from the Time Picker ...
				// Index [0] = hour
				// Index [1] = minute
				var hourMinute2 = objCalcUntilTimeAutomatic.value.split(":");
				var second2 = objCalcUntilSecondAutomatic.value;
				var msecond2 = objCalcUntilMSecondAutomatic.value;
				// und dann das Julianische Datum der Lokalzeit für den Starttermin aus den Eingabeelementen:
				// Ganzahlanteil sind die Tage und der Nachkommaanteil die Uhrzeit des Tages ...
				//
				// and then the Julian date of the local time for the start date from the input elements:
				// Whole fraction is the days and the decimal fraction is the time of the day ...
				var valueVirtualEndDateJD = calcJD(Number(yearMonthDay2[2]),Number(yearMonthDay2[1]),
																		 Number(yearMonthDay2[0]), Number(hourMinute2[0]), Number(hourMinute2[1]),
																		 Number(second2), Number(msecond2),  0, 0);
				if (valueVirtualStartDateJD >= 0 && valueVirtualEndDateJD >= 0){
					// ... es macht nur Sinn die Berechnung zu beginnen, wenn das Enddatum größer dem Startdatum ist...
					// ... it only makes sense to start the calculation if the end date is greater than the start date...					
					if (valueVirtualEndDateJD > valueVirtualStartDateJD){
						// Dann die Zeit für den Zeitsprung ermitteln. Dies ist die Zeit, die nach jedem Delay zum aktuellen
						// Uhrzeitwert hinzugezählt wird, um die Animation zu beschleunigen. Dies wird als Teil an einem
						// Tag = 24 h berechnet. Ermöglicht das rechnen mit dem Julianischen Datum.
						//
						// Then determine the time for the time jump. This is the time after each delay to the current
						// Time value is added to speed up the animation.This is done as part of a
						// day = 24 hours calculated. Allows you to calculate with the Julian date.
						if ( objCalcActualDateHour.value >= 0 ) TIMELAPS += Math.abs(objCalcActualDateHour.value/24);
						if ( objCalcActualDateMinute.value >= 0 ) TIMELAPS += Math.abs(objCalcActualDateMinute.value/1440);
						if ( objCalcActualDateSecond.value >= 0 ) TIMELAPS += Math.abs(objCalcActualDateSecond.value/86400);
						if ( objCalcActualDateMillisecond.value >= 0 ) TIMELAPS += Math.abs(objCalcActualDateMillisecond.value/86400000);
						document.getElementById("mstimelaps").value = TIMELAPS;	
						// ... und den "Stop" Button im Hauptprogramm bedienbar machen ...
						// ... and make the “Stop” button operable in the main program ...
						objCalcStop.disabled = false;
						// ... Stoppt den Worker für das Datum Overlay, wenn er aktiv ist ...
						// ... Stops the worker for the date overlay when active ...
						if (wAutomaticTime) stopWorker();
						// ... Popup Fenster für Datenausgabe beim Laden des primären Fensters öffnen ...
						// ... Open popup window for data output when loading the primary window ...
						if (objShowDataOutput.checked == true)  popup = openNew("./outputData.html", "outputData", 970, 820);
						// Checkbox "Datenausgabe" unbedienbar machen
						// Make “Datenausgabe” checkbox unoperable
						objShowDataOutput.disabled = true;
						// ... dann den Background Worker "worker-automatic-choicedate-endless.js" 
						// für die Berechnung "Ab gewähltem Datum"  "Bis zum Datum" erstellen und starten.
						//
						// ... then the background worker “worker-automatic-choicedate-endless.js” 
						// for the calculation “From selected date” create and start “To date.”
						startWorkerChoiceEndless(TIMELAPS, VELOSITY, TIMEZONE, valueVirtualStartDateJD, valueVirtualEndDateJD);
					// ... ansonsten hier die Fehlermeldung, wenn das Endedatum kleiner als das Startdatum ...
					// ... otherwise here the error message if the end date is smaller than the start date ...
					}else{
						alert("Das Julianische Enddatum: " + valueVirtualEndDateJD + "\n" + "         ist kleiner oder gleich als\ndas Julianische Startdatum: " + valueVirtualStartDateJD);
					}// End of if (valueVirtualEndDateJD > valueVirtualStartDateJD) ...
					
				// ... Startdatum und/oder Enddatum sind kleiner 0, also liegen vor dem 0.5 Januar -4712
				// ... Start date and/or end date are less than 0, i.e. before 0.5 January -4712
				}else{
					if (valueVirtualStartDateJD < 0) alert("Das Julianische Startdatum: " + valueVirtualStartDateJD + "\n" + "         liegt vor dem 0.5 Januar -4712! ");
					if (valueVirtualEndDateJD < 0) alert("Das Julianische Enddatum: " + valueVirtualEndDateJD + "\n" + "         liegt vor dem 0.5 Januar -4712! ");
				}// End of if (valueVirtualStartDateJD >= 0 && valueVirtualEndDateJD >= 0) ...
				
			// Fehlermeldung, wenn ein oder mehr Eingabefelder leer sein sollten.
			// Error message if one or more input fields should be empty.
			}else{
				alert("Error: Einer der Datenfelder ist leer!");
			}// End of if (objUntilDateAutomatic.value != "".....)
				
	}// End of Ab gewähltem Datum bis zu einem Enddatum soll simuliert

});// End of objAutoCalc.addEventListener()



/* *******************************************************************************************************
	Hier wird der Worker für die automatische Berechnungen "Ab gewähltem Datum"
	erstellt. Er befindet sich in der Datei "worker-automatic-choicedate-endless.js". Da die Funktion
	sleep(x) hier Verwendung findet muss sie als "async function ..." definiert sein.
	
	Sie empfängt die berechneten Daten von "worker-automatic-choiceldate-endless.js"
	und gibt sie im Hauptfenster aus.
	
	Aufgerufen wird die Funktion vom Eventhandler "objAutoCalc.addEventListener" 
	des Button "Berechnen" im Overlay.
	
	Übergabewert:
	--------------------
		timelaps	= Der Integer Wert für einen eventuellen Zeitsprung bei Zeitraffung
		velosity		= Die Pause zwischen den Berechnungen, also DELAY
		timezone	= Die Zeitzone + DST
		startDate	= Dient der Berechnung von Starttermin bis Endtermin bei automatischer Berechnung
		
	Rückgabewert:
	---------------------
						Keiner
	-----------------------------------------------------------------------------------------------------------------------------

	Here the worker for the automatic calculations “From selected date”
	created. It is located in the file “worker-automatic-choicedate-endless.js.” As the function
	sleep (x) is used here it must be defined as “async function “....
	
	It receives the calculated data from “worker-automatic-choiceldate-endless.js”
	and displays it in the main window.
	
	The function is called by the event handler “objAutoCalc.addEventListener” 
	the “Calculate” button in the overlay.
	
	Transfer value:
	--------------------
		timelaps = The integer value for a possible time jump on timelaps
		velosity  = The pause between the calculations, i.e. DELAY
		timezone = The time zone + DST
		startDate = Serves the calculation from start date to end date with automatic calculation
		
	Return value:
	---------------------
						None
   ******************************************************************************************************* */
async function startWorkerChoiceEndless(timelaps, velosity, timezone, startdate, enddate){
	var dat = null;								// Datumsobjekt des aktuellen Datums und Uhrzeit
														// Date object of the current date and time
	var startProgressTime = 0;			// Startzeit für die Verarbeitungsdauer Ausgabe
														// Start time for processing time output
	var stopProgressTime = 0;			// Stopzeit für die Verarbeitungsdauer Ausgabe
														// Stop time for processing time output
	var diffProgressTime = 0;				// Die Zeitdifferenz der Verarbeitung Ausgabe
														// The time difference of processing output
	// Wenn der modern Browser einen Web Worker kennt....
	// If the modern browser knows a Web Worker ...
	if(typeof(Worker) !== "undefined") {
		// ... und der Web Worker noch nicht installiert wurde ...
		// ... and the Web Worker has not yet been installed ...
		if(typeof(workerChoiceEndless)== "undefined") {		
			// ... ein neues WebWorker Objekt generiert aus der JavaScript Datei.
			// Achtung: Bei lokalen Dateien muss der Browser mit dem
			// Kommandline Parameter: "allow-file-access-from-files" gestartet
			// werden. Andernfalls unter einem Webserver starten ...
			//
			// ... a new WebWorker object is generated from the JavaScript file.
			// Attention: In case of local files, the browser must use the
			// Commandline parameter: “allow-file-access-from-files” started
			//. Otherwise start under a webserver ...
			workerChoiceEndless = new Worker("../../Bibliotheken/Sonne-Mond/worker-automatic-choicedate-endless.js" );			
		}
		// ... und hat die vorhergehende Installation des Web Workers geklappt ...
		// ... and the previous installation of the Web worker worked ...
		if (workerChoiceEndless){
			// Benötigte Daten aus der Hauptseite "Zeitberechnungen.html" an den
			// Web Worker "worker-automatic-actualdate-endless.js" senden ...
			//
			// Required data from the main page “Time Calculations.html” to the
			// Web Worker send “worker-automatic-actualdate-endless.js” ...
			//
			// ... und sende an den Webworker "worker-automatic-choicedate-endless.js" Startzeitpunkt ...
			// ... and send to the webworker “worker-automatic-actualdate-endless.js” start time ...
			workerChoiceEndless.postMessage("startdate=" + startdate);
			// ... und sende an den Webworker "worker-automatic-choicedate-endless.js" Endzeitpunkt ...
			// ... and send to the webworker “worker-automatic-actualdate-endless.js” end time ...
			workerChoiceEndless.postMessage("enddate=" + enddate);
			// Auswahl der Zeitzone aus der Auswahl Box ...
			// Selection of the time zone from the selection box ...
			workerChoiceEndless.postMessage("OptionTimezone=" + objTimezone.value);
			// Auswahl des Längengrades aus der Text Box ...
			// Selection of the longitude from the text box ...
			workerChoiceEndless.postMessage("OptionLongitude=" + objLongitude.value);
			// Auswahl der Dämmerungsart aus der Auswahl Box ...
			// Selection of the twilight type from the selection box ...
			workerChoiceEndless.postMessage("OptionTwilightkind=" + objTwilightkind.value);
			// Auswahl der Sommer/Winterzeit (DST) aus der Auswahl Box ...
			// Selection of summer/winter time (DST) from the selection box ...
			workerChoiceEndless.postMessage("OptionDST=" + (objDST.value - 1));
			// Auswahl des Breitengrades aus der Text Box ...
			// Selection of the latitude from the text box ...
			workerChoiceEndless.postMessage("OptionLatitude=" + objLatitude.value);
			// Endlose Berechnung in der Animation ab einem Startdatum
			// Endless calculation in the animation from a start date
			if ( startdate > 0 && enddate == 0 ){
				workerChoiceEndless.postMessage("Header="+ "\n\t\t\t\t\t\tDatenerhebungsbericht - " + ( julianDate2Date(startdate)[0]  - decPart(julianDate2Date(startdate)[0]) ) + "."
																						+ julianDate2Date(startdate)[1] + "." 
																						+ julianDate2Date(startdate)[2] + " - "
																						+ percentageOfDecimal2Time(decPart(julianDate2Date(startdate)[0]), "string") + ".\n"
																						+	"\t\t\t\t\t\t\t\tSonne- und Monddaten"
																						+ "\n" +	"\t\t\t\t\t\t________________________________________\n\n"
																		);
			// Endlose Berechnung bis zu einem Enddatum
			// Endless calculation up to an end date
			}else if ( startdate > 0 && enddate > 0 ){
				workerChoiceEndless.postMessage("Header="+ "\n\t\tDatenerhebungsbericht - " + ( julianDate2Date(startdate)[0] - decPart(julianDate2Date(startdate)[0]) ) + "." 
																						+ julianDate2Date(startdate)[1] + "." 
																						+ julianDate2Date(startdate)[2] + " - " 
																						+ percentageOfDecimal2Time(decPart(julianDate2Date(startdate)[0]), "string") + " - "
																						+ ( julianDate2Date(enddate)[0] - decPart(julianDate2Date(enddate)[0]) ) + "." 
																						+ julianDate2Date(enddate)[1] + "." 
																						+ julianDate2Date(enddate)[2] + " - "
																						+ percentageOfDecimal2Time(decPart(julianDate2Date(enddate)[0]), "string") + "\n"
																						+	"\t\t\t\t\t\t\tSonne- und Monddaten"
																						+ "\n" +	"\t\t______________________________________________________________\n\n"
																		);
			}
			// ... dann lasse dem Worker noch 100 ms Zeit um an den Start zu gehen ...
			// ... then let the worker still 100 ms time to go to the start ...
			await Sleep(200);
			workerChoiceEndless.postMessage("workeruntil=" + workerChoiceEndless);
			// ... und sende an den Webworker "worker-automatic-actualdate-endless.js" die Pause und den Zeitsprung ...
			// ... and send to the webworker “worker-automatic-actualdate-endless.js” the pause and the time jump ...
			workerChoiceEndless.postMessage("timelaps=" + timelaps);
			workerChoiceEndless.postMessage("delay=" + velosity);
			// ... in init.js liegt die Funktion zur Berechnung der Zeitzone und DST. Dort ist auch die Variable
			// TIMEZONE deklariert
			// ... und hier DST und Zeitzoneninfo senden ...
			// ... in init.js is the function to calculate the time zone and DST. There is also the variable
			// TIMEZONE declared
			// ... and send DST and time zone info here ...
			workerChoiceEndless.postMessage("timezone=" + TIMEZONE);
			// ... das Textfeld "Kontrolldatum" in der Hauptseite hat bei automatischer Berechnung
			// keinen Wert, nur bei Manueller Berechnung ...
			// ... the text field “Check date” in the main page has been automatically calculated
			// no value, only for manual calculation ...
			output.value = "N/A";
			// Die Event Queue über die alle Daten vom WebWorker eintreffen.
			// The event queue where all data from the WebWorker arrives.
			workerChoiceEndless.onmessage = function (event) {
				// Ermittelt die Anfangszeit der Verarbeitung in Millisekunden für die Berechnung
				// der gesamten Verarbeitungszeit eines Durchlaufs ...
				// Determines the start time of the processing in milliseconds for the calculation
				// the total processing time of a run ...
				startProgressTime = new Date();
				// Im Array splitData findet man zwei Werte als Key=Value.
				// Sie sind durch "=" getrennt ...
				// In the splitData array you find two values as Key=Value.
				// They are separated by “=.”
				splitData = event.data.split("=");
				// Wenn vom Worker "../../Bibliotheken/Sonne-Mond/worker-automatic-choicedate-endless.js" die Nachricht 
				// über das Ende der Berechnung kommt ...
				// If from the worker .”./../Libraries/Sun-Moon/worker-automatic-choicedate-endless.js” the message 
				// over the end of the calculation comes ...
				if (splitData[0] == "workerChoiceEndlessUntil"){
					// ... den Hintergrundprocess "../../Bibliotheken/Sonne-Mond/worker-automatic-choicedate-endless.js"
					// beenden.
					// ... the background process .”./../Libraries/Sun-Moon/worker-automatic-choicedate-endless.js”
					// exit.
					stopWorkerChoiceDateEndless();
					// ... und den Button "Stop" unbedienbar machen.
					// ... and make the button “Stop” unusable.
					objCalcStop.disabled = true;
					objCalcAutomatic.disabled = false;
					objCalcManual.disabled = false;
				// Hier, nach dem Key, die einzelnen Ergebnisse den Ausgabebereichen
				// zuweisen ...
				// ... zuerst das aktuelle Berechnungs Datum und die Uhrzeit holen ...
				// ... first get the current calculation date and time ...
				}else if (splitData[0] == "DateAndTime"){
					// Das Julianische Datum vom Web Worker empfangen, um es im Hauptprogramm
					// in die Picker Datum, Uhrzeit, Sekunden und Millisekunden einzutragen ...
					// Receive the Julian date from the Web Worker to put it in the main program
					// enter date, time, seconds and milliseconds in the picker ...
					var jd = Number(splitData[1]);
					// ... und aus dem Julianischen Datum ein Gregorianisches Datum zu berechnen ...
					// ... and calculate a Gregorian date from the Julian date ...
					var dateJDUTC =  julianDate2Date(jd);
					// ... aus dem Gregorianischen Datum die einzelnen Daten extrahieren ...
					// ... extract the individual data from the Gregorian date ...
					var HMSMS = percentageOfDecimal2Time(decPart(dateJDUTC[0]), "array");
					var day		= Number(dateJDUTC[0] - decPart(dateJDUTC[0]));
					var month	= Number(dateJDUTC[1]);
					var year		= Number(dateJDUTC[2]);
					var hour		= Number(HMSMS[0]);
					var minute	= Number(HMSMS[1]);
					var second	= Number(HMSMS[2]);
					var msecond= Number(HMSMS[3]);
					// ... und daraus ein neues Datumsobjekt erstellen, da dies nicht über
					// einen Kanal gesendet werden kann ...
					// ... and create a new date object from it, as this does not
					// a channel can be sent ...
					document.getElementById("date").valueAsDate = new Date (year , month - 1, day + 1);
					// ... danach die Uhrzeit in der Hauptseite unter "Uhrzeit:" im Time Picker ausgeben ...
					// ... then display the time in the main page under “Uhrzeit:” in the Time Picker ...
					document.getElementById("time").value = LPad(hour, 2, "0") + ":" + LPad(minute, 2, "0");
					// Die Sekunden im Number Picker "Sekunden"  ...
					// The seconds in the number picker “Sekunden” ...
					document.getElementById("second").value = LPad(second, 2, "0");
					// ... und die Millisekunden in "Milli-Sek" auch noch.
					// ... and the milliseconds in the number picker “Milli-Sek.” ...
					document.getElementById("msecond").value = LPad(msecond, 3, "0");
				// Die vom Backround Worker berechneten Daten, die in einem Textfeld ausgegeben werden sollen
				// an outputData.html senden.
				// The data calculated by the Backround Worker to be output in a text field
				// Send to outputData.html.
				}else if (splitData[0] == "sendedChoiceWholeDataAsString"){
					channelExtern.postMessage("dataOutput=" +  String(splitData[1]) );
				// Die normale Uhrzeit ausgeben
				// Output the normal time
				}else if (splitData[0] == "UTC"){
					document.getElementById("LT").value = splitData[1];
				// Universal Time = UT ausgeben
				}else if (splitData[0] == "UT"){
					document.getElementById("UT").value = splitData[1];
				// Das Julianische Datum ausgeben
				// Output the Julian date
				}else if (splitData[0] == "JD"){
					document.getElementById("JD1").value = splitData[1];
				// Datum und Uhrzeit berechnet aus dem Julianischen Datum ausgeben
				// Output date and time calculated from Julian date
				}else if (splitData[0] == "JDDate"){
					document.getElementById("DateJD1").value = splitData[1];
				// Das modifizierte Julianische Datum ausgeben
				// Output the modified Julian date
				}else if (splitData[0] == "MJD"){
					document.getElementById("MJD").value = splitData[1];
					document.getElementById("MJD").title = "Das Modified Julianisches Datum (MJD) aus dem UT aus Grundlagen der Orbitmechanik - von Volker Maiwald, Dominik Quantius, Benny Rievers - MJD wird nur ab dem Jahr1900 berechnet!";
				// Die Rückrechnung von Datum und Uhrzeit aus dem MJD
				// The recalculation of date and time from the MJD
				}else if (splitData[0] == "MJDDate"){
					document.getElementById("DateMJD").value = splitData[1];
					document.getElementById("DateMJD").title = "Das errechnete Datum aus dem Modifizierten Julianischen Datum der UT - MJD wird nur ab dem Jahr1900 berechnet!";
				// Das Julianische Datum des UTC, also der Berechnungszeit am Ort
				// The Julian date of the UTC, that is, the calculation time at the location
				}else if (splitData[0] == "JDUTC"){
					document.getElementById("LTJD").value = splitData[1];
				// Das zurückgerechnete Julianische Datum des UTC, also der Berechnungszeit am Ort,
				// in ein formatiertes Datum
				// The back-calculated Julian date of the UTC, i.e. the calculation time at the location,
				// into a formatted date
				}else if (splitData[0] == "dateJDUTC"){
					document.getElementById("JDLT").value = splitData[1];
				// Das Modifizierte Julianische Datum des UTC, also der Berechnungszeit am Ort
				// The Modified Julian Date of the UTC, i.e. the calculation time at the location
				}else if (splitData[0] == "MJDUTC"){
					document.getElementById("MJDUTC").value = splitData[1];
					document.getElementById("MJDUTC").title = "Das Modifizierte Julianische Datum der Uhrzeit - MJD wird nur ab dem Jahr1900 berechnet!";
				// Das zurückgerechnete Modifizierte Julianische Datum des UTC, also der Berechnungszeit am Ort,
				// in ein formatiertes Datum
				// The back-calculated Modified Julian Date of the UTC, i.e. the calculation time at the location,
				// into a formatted date
				}else if (splitData[0] == "dateMJDUTC"){
					document.getElementById("DATEMJD").value = splitData[1];
					document.getElementById("DATEMJD").title = "Das errechnete Datum aus dem Modifizierten Julianischen Datum der Uhrzeit  - MJD wird nur ab dem Jahr1900 berechnet!";
				// Die Verarbeitungsgeschwindigkeit der Berechnung der Werte
				// The processing speed of the calculation of the values
				}else if (splitData[0] == "Progress"){
					document.getElementById("msprogresstime").value = (Number(splitData[1]) + diffProgressTime);
					DELAY = (Number(splitData[1]) + diffProgressTime);
				// Die Zeit des Sonnenaufgangs bei automatischer Berechnung in Textfeld eintragen 
				// Enter the time of sunrise with automatic calculation in text field
				}else if (splitData[0] == "automaticSunrise"){
					document.getElementById("tsunrise").value = dectime2Time(splitData[1],"string");
				// Der Status des Sonnenaufgangs
				// Status of sunrise
				}else if (splitData[0] == "automaticStatSunrise"){
					document.getElementById("statsunrise").value = splitData[1];
				// Die Zeit des Sonnenuntergangs bei automatischer Berechnung in Textfeld eintragen 
				// Enter the time of sunset with automatic calculation in text field
				}else if (splitData[0] == "automaticSunset"){
					document.getElementById("tsunset").value = dectime2Time(splitData[1],"string");
				// Der Status des Sonnenauntergangs
				// Status of sunset
				}else if (splitData[0] == "automaticStatSunset"){
					document.getElementById("statsunset").value = splitData[1];
				// Der Dämmerungsaufgang
				// Twilight rise
				}else if (splitData[0] == "automaticTwilightSunrise"){
					document.getElementById("ttwlsunrise").value = dectime2Time(splitData[1], "string");
				// Status der Dämmerungsaufgang
				// Twilight rise status
				}else if (splitData[0] == "automaticTwilightStatSunrise"){
					document.getElementById("statttwlsunrise").value = splitData[1];
				// Der Dämmerungsuntergang
				// Twilight set
				}else if (splitData[0] == "automaticTwilightSunset"){
					document.getElementById("ttwlsunset").value = dectime2Time(splitData[1], "string");
				// Status des Dämmerungsuntergang
				// Twilight set status
				}else if (splitData[0] == "automaticTwilightStatSunset"){
					document.getElementById("statttwlsunset").value = splitData[1];
				// Der Azimuth des Sonnenaufgangs
				// The azimuth of sunrise
				}else if (splitData[0] == "automaticAZSunrise"){
					document.getElementById("azsunrise").value = splitData[1];
				// Der Status des Azimuth des Sonnenaufgangs
				// The status of azimuth of sunrise
				}else if (splitData[0] == "automaticAZStatSunrise"){
					document.getElementById("statazsunrise").value = splitData[1];
				// Der Azimuth des Sonnenuntergangs
				// The azimuth of sunset
				}else if (splitData[0] == "automaticAZSunset"){
					document.getElementById("azsunset").value = splitData[1];
				// Der Status des Azimuth des Sonnenuntergangs
				// The status of azimuth of sunset
				}else if (splitData[0] == "automaticAZStatSunset"){
					document.getElementById("statazsunset").value = splitData[1];
				// Das Julianische Datum des Sonnenaufgangs
				// Julian date of sunrise
				}else if (splitData[0] == "jdSunrise"){
					document.getElementById("jdsunrise").value = splitData[1];
				// Das Julianische Datum des Sonnenuntergangs
				// Julian date of sunset
				}else if (splitData[0] == "jdSunset"){
					document.getElementById("jdsunset").value = splitData[1];
				// Aus dem JD des höchsten Punkts am Himmel wieder ein Datum berechnen
				// Calculate a date from the JD of the highest point in the sky
				}else if (splitData[0] == "highNoonDate"){
					document.getElementById("timehighnoon").value = splitData[1];
				// Abstand Erde - Sonne in Km
				// Distance Earth – Sun in Km
				}else if (splitData[0] == "sunDiameter"){
					document.getElementById("distancesunearth").value = splitData[1];
				// Durchmesser der Sonne am Himmel Dezimal
				// Diameter of the Sun in the Sky Decimal
				}else if (splitData[0] == "sunDiameterSkyDec"){
					document.getElementById("diasundez").value = splitData[1];
				// Winkeldurchmesser der Sonne in Grad, Minute, Sekunde
				// Angular size as degree, minute and second
				}else if (splitData[0] == "sunDiameterSkyDeg"){
					document.getElementById("diasundeg").value = decDegrees2AngleOfHours(splitData [1]);
				// Der Azimuth des Sonnenhöchststand genau in dez. Grad
				// The azimuth of the sun’s elevation exactly in dec. Degree
				}else if (splitData[0] == "sunAZHigh"){
					document.getElementById("azhighsundez").value = splitData [1];
				// Sonnenhöchstand im Azimuth in Grad
				// Sun’s elevation in azimuth in degrees
				}else if (splitData[0] == "sunHighHigh"){
					document.getElementById("azhighsundeg").value = splitData [1];
				// Der Azimuth des aktuellen Sonnenstandes
				// The azimuth of the current position of the sun
				}else if (splitData[0] == "automaticAZ"){
					document.getElementById("actualazsun").value = splitData[1];
				// Die Höhe des aktuellen Sonnenstandes im Horizontalsystem
				// The level of the current position of the sun in the horizontal system
				}else if (splitData[0] == "automaticHigh"){
					document.getElementById("actualhighsun").value = splitData[1];
					if (splitData[1] < 0.0){
						document.getElementById("actualazsun").style.color = "red";
						document.getElementById("actualazsun").title = "Der geozentrische Azimuth des Mondes von N->W im horizontalen Koordinatensystem" + " - Mond ist unter dem Horizont!";
						document.getElementById("actualhighsun").style.color = "red";
						document.getElementById("actualhighsun").title = "Die geozentrische Höhe des Mondes über dem Horizont im horizontalen Koordinatensystem" + " - Mond ist unter dem Horizont!";
					}else{
						document.getElementById("actualazsun").style.color = "green";
						document.getElementById("actualazsun").title = "Der geozentrische Azimuth des Mondes von N->W im horizontalen Koordinatensystem" + " - Mond ist ueber dem Horizont!";
						document.getElementById("actualhighsun").style.color = "green";
						document.getElementById("actualhighsun").title = "Die geozentrische Höhe des Mondes über dem Horizont im horizontalen Koordinatensystem" + " - Mond ist ueber dem Horizont!";
					}
				// Die Rektaszension des aktuellen Sonnenstandes im Äquatorialsystem
				// The recaszension of the current position of the sun in the equatorial system
				}else if (splitData[0] == "automaticRA"){
					document.getElementById("actualrasun").value = splitData[1];
				// Die Deklination des aktuellen Sonnenstandes im Äquatorialsystem
				// The declination of the current position of the sun in the equatorial system
				}else if (splitData[0] == "automaticDEC"){
					document.getElementById("actualdecsun").value = splitData[1];
				// Den Mondaufgang im Textfeld "tmoonrise" ausgeben ...
				// Display the moonrise in the text field “tmoonrise” ...
				}else if (splitData[0] == "moonrise"){
					document.getElementById("tmoonrise").value = splitData[1];
				// Den Status des Mondaufgang im Textfeld "statmoonrise" ausgeben ...
				// Display the state of the moonrise in the text field “statmoonrise” ...
				}else if (splitData[0] == "statemoonrise"){
					document.getElementById("statmoonrise").value = splitData[1];
				// Den Azimuth des Mondaufgangs im Textfeld "moonriseaz" ausgeben ...
				// Display the azimuth of the moonrise in the text field “moonriseaz” ...
				}else if (splitData[0] == "azimuthmoonrise"){
					document.getElementById("moonriseaz").value = splitData[1];
				// Die Höhe des Mondaufgangs im Textfeld "moonriseazh" ausgeben ...
				// Display the altitude of the moonrise in the text field “moonriseazh” ...
				}else if (splitData[0] == "altitudemoonrise"){
					if ( (splitData[1] == "Immer Sichtbar") || (splitData[1] == "Nie Sichtbar") )
						document.getElementById("moonriseazh").value = splitData[1];
					else
						document.getElementById("moonriseazh").value = decDegrees2AngleOfHours(splitData[1]);
				// Den Azimuth des Monduntergangs im Textfeld "moonsetaz" ausgeben ...
				// Display the azimuth of the moonset in the text field “moonsetaz” ...
				}else if (splitData[0] == "azimuthmoonset"){
					document.getElementById("moonsetaz").value = splitData[1];
				// Die Höhe des Monduntergangs im Textfeld "moonsetazh" ausgeben ...
				// Display the altitude of the moonset in the text field “moonsetazh” ...
				}else if (splitData[0] == "altitudemoonset"){
					if ( (splitData[1] == "Immer Sichtbar") || (splitData[1] == "Nie Sichtbar") )
						document.getElementById("moonsetazh").value = splitData[1];
					else
						document.getElementById("moonsetazh").value = decDegrees2AngleOfHours(splitData[1]);
				// Den Monduntergang im Textfeld "tmoonset" ausgeben ...
				// Display the moonset in the text field “tmoonset” ...
				}else if (splitData[0] == "moonset"){
					document.getElementById("tmoonset").value = splitData[1];
				// Den Status des Monduntergang im Textfeld "tmoonset" ausgeben ...
				// Display the state of the moonset in the text field “tmoonset” ...
				}else if (splitData[0] == "statemoonset"){
					document.getElementById("statmoonset").value = splitData[1];
				// Den Status des Monduntergang im Textfeld "tmoonset" ausgeben ...
				// Display the state of the moonset in the text field “tmoonset” ...
				}else if (splitData[0] == "moonhigh"){
					document.getElementById("moonhighdate").value = splitData[1];
				// Den Azimuth des Höchststand des Mondes im Textfeld "moonhighaz" ausgeben ...
				// Display the azimuth of the the maximum of the moon in the text field "moonhighaz" ...
				}else if (splitData[0] == "moonhighaz"){
					document.getElementById("moonhighaz").value = splitData[1];
				// Den Azimuth des Höchststand des Mondes im Textfeld "moonhighaz" ausgeben ...
				// Display the azimuth of the the maximum of the moon in the text field "moonhighaz" ...
				}else if (splitData[0] == "moonhighdeg"){
					document.getElementById("moonhighdeg").value = splitData[1];
				// Die Entfernung Erde-Mond im Textfeld "distmoon" ...
				// Display the distance Earth-Moon in the text field "distmoon"  ...
				}else if (splitData[0] == "moondist"){
					document.getElementById("distmoon").value = splitData[1];
				// Durchmesser des Mondes am Himmel in Grad im Textfeld "diamoon" ausgeben ...
				// Send the Diameter of the Moon in the Sky in degrees to text field "diamoon" ...
				}else if (splitData[0] == "moondia"){
					document.getElementById("diamoon").value = splitData[1];
				// Die aktuelle Höhe des Mondes in Grad
				// The actual altitude of the Moon in degrees ...
				}else if (splitData[0] == "moonh"){
					document.getElementById("hmoon").value = splitData[1];
					if (splitData[1] < 0.0){
						document.getElementById("azmoon").style.color = "red";
						document.getElementById("hmoon").style.color = "red";
						document.getElementById("azmoon").title = "Der geozentrische Azimuth des Mondes von N->W im horizontalen Koordinatensystem" + " - Mond ist unter dem Horizont!";
						document.getElementById("hmoon").title = "Die geozentrische Höhe des Mondes über dem Horizont im horizontalen Koordinatensystem" + " - Mond ist unter dem Horizont!";
					}else{
						document.getElementById("azmoon").style.color = "green";
						document.getElementById("hmoon").style.color = "green";
						document.getElementById("azmoon").title = "Der geozentrische Azimuth des Mondes von N->W im horizontalen Koordinatensystem" + " - Mond ist ueber dem Horizont!";
						document.getElementById("hmoon").title = "Die geozentrische Höhe des Mondes über dem Horizont im horizontalen Koordinatensystem" + " - Mond ist ueber dem Horizont!";
					}
				// Der aktuelle Azimuth des Mondes in Grad
				// The actual azimuth of the Moon in degrees ...
				}else if (splitData[0] == "moonaz"){
					document.getElementById("azmoon").value = splitData[1];
				// Ermittelt die Endzeit der Verarbeitung in Millisekunden für das Julianische Datum
				// Determines the end time of processing in milliseconds for the Julian date
				}		
				stopProgressTime = Date.now();
				// Wenn die neue Verarbeitungszeit größer ist als die letzte ... 
				// If the new processing time is longer than the last ...
				if ( (Number(stopProgressTime) - Number(startProgressTime)) > diffProgressTime){
					// dann speichere die neue Verarbeitungszeit als die Höhere ...
					// then save the new processing time as the Higher ...
					diffProgressTime = Number(stopProgressTime) - Number(startProgressTime);
					// und ist die neue Verarbeitungszeit größer als die Wartezeit ...
					// and is the new processing time greater than the waiting time ...
					if ( diffProgressTime > DELAY){
						// dann passe die Wartezeit an plus eine kleine Sicherheit
						// then adjust the waiting time plus a small security
						DELAY = DELAY + diffProgressTime + 10;
					}				
				}
				
			};// End of workerChoiceEndless.onmessage
		
		}// End of if (workerChoiceEndless)
		
	// Der Browser kennt den WebWorker nicht und gibt eine Fehlermeldung aus.
	// The browser does not know the WebWorker and gives an error message.
	} else {
		alert("Sorry, your browser does not support Web Workers...");
	}// End of if(typeof(Worker) !== "undefined") 
	
}// End of async function startWorkerChoiceEndless()




/* *******************************************************************************************************
	Hier wird der Worker für die automatische Berechnungen "Mit aktuellen Datum"
	erstellt. Er befindet sich in der Datei "worker-automatic-actualdate-endless.js". Da die Funktion
	sleep(x) hier Verwendung findet muss sie als "async function ..." definiert sein.
	
	Sie empfängt die berechneten Daten von "worker-automatic-actualdate-endless.js"
	und gibt sie im Hauptfenster aus.
	
	Aufgerufen wird die Funktion vom Eventhandler "objAutoCalc.addEventListener" 
	des Button "Berechnen" im Overlay.
	
	Übergabewert:
	--------------------
		timelaps	= Der Integer Wert für einen eventuellen Zeitsprung bei Zeitraffung
		velosity		= Die Pause zwischen den Berechnungen, also DELAY
		timezone	= Die Zeitzone + DST
		startDate	= Dient der Berechnung von Starttermin bis Endtermin bei automatischer Berechnung
		endDate	= Dient der Berechnung von Starttermin bis Endtermin bei automatischer Berechnung
		
	Rückgabewert:
	---------------------
						Keiner
	-----------------------------------------------------------------------------------------------------------------------------
	Here the worker for the automatic calculations “With current date”
	created. It is located in the file “worker-automatic-actualdate-endless.js.” As the function
	sleep (x) is used here it must be defined as “async function “....
	
	It receives the calculated data from “worker-automatic-actualdate-endless.js”
	and displays it in the main window.
	
	The function is called by the event handler “objAutoCalc.addEventListener” 
	the “Calculate” button in the overlay.
	
	Transfer value:
	--------------------
		timelaps = The integer value for a possible time jump on timelaps
		velosity  = The pause between the calculations, i.e. DELAY
		timezone = The time zone + DST
		startDate = Serves the calculation from start date to end date with automatic calculation
		endDate = Serves the calculation from start date to end date with automatic calculation
		
	Return value:
	---------------------
						None
   ******************************************************************************************************* */
async function startWorkerActualEndless(timelaps, velosity, timezone, startdate, enddate){
	var dat = null;								// Datumsobjekt des aktuellen Datums und Uhrzeit
														// Date object of the current date and time
	var startProgressTime = 0;			// Startzeit für die Verarbeitungsdauer Ausgabe
														// Start time for processing time output
	var stopProgressTime = 0;			// Stopzeit für die Verarbeitungsdauer Ausgabe
														// Stop time for processing time output
	var diffProgressTime = 0;				// Die Zeitdifferenz der Verarbeitung Ausgabe
														// The time difference of processing output
	// Wenn der modern Browser einen Web Worker kennt....
	// If the modern browser knows a Web Worker ...
	if(typeof(Worker) !== "undefined") {
		// ... und der Web Worker noch nicht installiert wurde ...
		// ... and the Web Worker has not yet been installed ...
		if(typeof(workerActualEndless)== "undefined") {		
			// ... ein neues WebWorker Objekt generiert aus der JavaScript Datei.
			// Achtung: Bei lokalen Dateien muss der Browser mit dem
			// Kommandline Parameter: "allow-file-access-from-files" gestartet
			// werden. Andernfalls unter einem Webserver starten ...
			//
			// ... a new WebWorker object is generated from the JavaScript file.
			// Attention: In case of local files, the browser must use the
			// Commandline parameter: “allow-file-access-from-files” started
			//. Otherwise start under a webserver ...
			workerActualEndless = new Worker("../../Bibliotheken/Sonne-Mond/worker-automatic-actualdate-endless.js" );			
		}
		// ... und hat die vorhergehende Installation des Web Workers geklappt ...
		// ... and the previous installation of the Web worker worked ...
		if (workerActualEndless){
			// Auswahl der Zeitzone aus der Auswahl Box ...
			// Selection of the time zone from the selection box ...
			workerActualEndless.postMessage("OptionTimezone=" + objTimezone.value);
			// Auswahl des Längengrades aus der Text Box ...
			// Selection of the longitude from the text box ...
			workerActualEndless.postMessage("OptionLongitude=" + objLongitude.value);
			// Auswahl der Dämmerungsart aus der Auswahl Box ...
			// Selection of the twilight type from the selection box ...
			workerActualEndless.postMessage("OptionTwilightkind=" + objTwilightkind.value);
			// Auswahl der Sommer/Winterzeit (DST) aus der Auswahl Box ...
			// Selection of summer/winter time (DST) from the selection box ...
			workerActualEndless.postMessage("OptionDST=" + (objDST.value - 1));
			// Auswahl des Breitengrades aus der Text Box ...
			// Selection of the latitude from the text box ...
			workerActualEndless.postMessage("OptionLatitude=" + objLatitude.value);
			// ... dann lasse dem Worker noch 100 ms Zeit um an den Start zu gehen ...
			// ... then let the worker still 100 ms time to go to the start ...
			// Endlose Berechnung in der Animation ab aktuellem Startdatum
			// Endless calculation in the animation from a actual start date
			if ( startdate > 0 && enddate == 0 ){
				workerActualEndless.postMessage("Header="+ "\n\t\t\t\t\t\tDatenerhebungsbericht - " + ( julianDate2Date(startdate)[0]  - decPart(julianDate2Date(startdate)[0]) ) + "."
																						+ julianDate2Date(startdate)[1] + "." 
																						+ julianDate2Date(startdate)[2] + " - "
																						+ percentageOfDecimal2Time(decPart(julianDate2Date(startdate)[0]), "string") + ".\n"
																						+	"\t\t\t\t\t\tSonne- und Monddaten nach aktuellem Datum Endlos"
																						+ "\n" +	"\t\t\t\t\t\t_____________________________________________\n\n"
																		);
			// Endlose Berechnung bis zu einem Enddatum
			// Endless calculation up to an end date
			}else if ( startdate > 0 && enddate > 0 ){
				workerActualEndless.postMessage("Header="+ "\n\t\tDatenerhebungsbericht - " + ( julianDate2Date(startdate)[0] - decPart(julianDate2Date(startdate)[0]) ) + "." 
																						+ julianDate2Date(startdate)[1] + "." 
																						+ julianDate2Date(startdate)[2] + " - " 
																						+ percentageOfDecimal2Time(decPart(julianDate2Date(startdate)[0]), "string") + " - "
																						+ ( julianDate2Date(enddate)[0] - decPart(julianDate2Date(enddate)[0]) ) + "." 
																						+ julianDate2Date(enddate)[1] + "." 
																						+ julianDate2Date(enddate)[2] + " - "
																						+ percentageOfDecimal2Time(decPart(julianDate2Date(enddate)[0]), "string") + "\n"
																						+	"\t\t\t\t\tSonne- und Monddaten nach aktuellem Datum bis Enddatum"
																						+ "\n" +	"\t\t_____________________________________________________________________________\n\n"
																		);
			}
			// Warte 200 ms
			// Wait 200 ms
			await Sleep(200);
			// ... und sende an den Webworker "worker-automatic-actualdate-endless.js" die Pause und den Zeitsprung ...
			// ... and send to the webworker “worker-automatic-actualdate-endless.js” the pause and the time jump ...
			workerActualEndless.postMessage("timelaps=" + timelaps);
			workerActualEndless.postMessage("delay=" + velosity);
			// ... und sende an den Webworker "worker-automatic-actualdate-endless.js" Start- und Endzeitpunkt ...
			// ... and send to the webworker “worker-automatic-actualdate-endless.js” start and end time ...
			workerActualEndless.postMessage("startdate=" + startdate);
			workerActualEndless.postMessage("enddate=" + enddate);
			// ... in init.js liegt die Funktion zur Berechnung der Zeitzone und DST. Dort ist auch die Variable
			// TIMEZONE deklariert
			// ... und hier DST und Zeitzoneninfo senden ...
			// ... in init.js is the function to calculate the time zone and DST. There is also the variable
			// TIMEZONE declared
			// ... and send DST and time zone info here ...
			workerActualEndless.postMessage("timezone=" + TIMEZONE);
			// ... das Textfeld "Kontrolldatum" in der Hauptseite hat bei automatischer Berechnung
			// keinen Wert, nur bei Manueller Berechnung ...
			// ... the text field “Check date” in the main page has been automatically calculated
			// no value, only for manual calculation ...
			output.value = "N/A";
			// Die Event Queue über die alle Daten vom WebWorker eintreffen.
			// The event queue where all data from the WebWorker arrives.
			workerActualEndless.onmessage = function (event) {
				// Ermittelt die Anfangszeit der Verarbeitung in Millisekunden für die Berechnung
				// der gesamten Verarbeitungszeit eines Durchlaufs ...
				// Determines the start time of the processing in milliseconds for the calculation
				// the total processing time of a run ...
				startProgressTime = new Date();
				// Im Array splitData findet man zwei Werte als Key=Value.
				// Sie sind durch "=" getrennt ...
				// In the splitData array you find two values as Key=Value.
				// They are separated by “=.”
				splitData = event.data.split("=");
				// Hier, nach dem Key, die einzelnen Ergebnisse den Ausgabebereichen
				// zuweisen ...
				// ... zuerst das aktuelle Berechnungs Datum und die Uhrzeit holen ...
				// ... first get the current calculation date and time ...
				if (splitData[0] == "DateAndTime"){
					// ... und daraus ein neues Datumsobjekt erstellen, da dies nicht über
					// einen Kanal gesendet werden kann ...
					// ... and create a new date object from it, as this does not
					// a channel can be sent ...
					dat = new Date(splitData[1]);
					// Das Datum der Hauptseite unter "Datum:" im Kalender Picker ausgeben ...
					// Display the date of the main page under “Date:” in the calendar picker ...
					document.getElementById("date").valueAsDate = dat;
					// ... danach die Uhrzeit in der Hauptseite unter "Uhrzeit:" im Time Picker ausgeben ...
					// ... then display the time in the main page under “Uhrzeit:” in the Time Picker ...
					document.getElementById("time").value = LPad(dat.getHours(), 2, "0") + ":" + LPad(dat.getMinutes(), 2, "0");
					// Die Sekunden im Number Picker
					// The seconds in the number picker
					document.getElementById("second").value = LPad(dat.getSeconds(), 2, "0");
					dat = null;
				// Die Millisekunden im Number Picker
				// The milli seconds in the number picker
				}else if (splitData[0] == "DateAndTimeMilliseconds"){
					document.getElementById("msecond").value = splitData[1];
				// Alle empfangenen berechneten Werte im Sendestring, vom Webworker gesendet, an das Datenausgabefenster senden
				// Send all received calculated values in the transmit string, sent by the webworker, to the data output window
				}else if (splitData[0] == "sendedActualWholeDataAsString"){
					channelExtern.postMessage("dataOutput=" +  String(splitData[1]) );
				// Die normale Uhrzeit ausgeben
				// Display the normal time
				}else if (splitData[0] == "UTC"){
					document.getElementById("LT").value = splitData[1];
				// Universal Time = UT ausgeben
				// Display the universal time
				}else if (splitData[0] == "UT"){
					document.getElementById("UT").value = splitData[1];
				// Das Julianischhe Datum ausgeben
				// Display the julian date
				}else if (splitData[0] == "JD"){
					document.getElementById("JD1").value = splitData[1];
				// Datum und Uhrzeit berechnet aus dem Julianischen Datum ausgeben
				// Display date and time calculated from the Julian date
				}else if (splitData[0] == "JDDate"){
					document.getElementById("DateJD1").value = splitData[1];
				// Das modifizierte Julianische Datum ausgeben
				// Print the modified Julian date
				}else if (splitData[0] == "MJD"){
					document.getElementById("MJD").value = splitData[1];
				// Die Rückrechnung von Datum und Uhrzeit aus dem MJD
				// The recalculation of date and time from the MJD
				}else if (splitData[0] == "MJDDate"){
					document.getElementById("DateMJD").value = splitData[1];
				// Das Julianische Datum des UTC, also der Berechnungszeit am Ort
				// The Julian date of the UTC, i.e. the calculation time at the location
				}else if (splitData[0] == "JDUTC"){
					document.getElementById("LTJD").value = splitData[1];
				// Das zurückgerechnete Julianische Datum des UTC, also der Berechnungszeit am Ort,
				// in ein formatiertes Datum
				// The recalculated Julian date of the UTC, i.e. the calculation time at the place,
				// in a formatted date
				}else if (splitData[0] == "dateJDUTC"){
					document.getElementById("JDLT").value = splitData[1];
				// Das Modifizierte Julianische Datum des UTC, also der Berechnungszeit am Ort
				// The modified Julian date of the UTC, i.e. the calculation time at the location
				}else if (splitData[0] == "MJDUTC"){
					document.getElementById("MJDUTC").value = splitData[1];
				// Das zurückgerechnete Modifizierte Julianische Datum des UTC, also der Berechnungszeit am Ort,
				// in ein formatiertes Datum
				// The modified Julian date of the UTC, i.e. the calculation time at the location,
				// in a formatted date
				}else if (splitData[0] == "dateMJDUTC"){
					document.getElementById("DATEMJD").value = splitData[1];
				// Die Verarbeitungsgeschwindigkeit der Berechnung der Werte
				// The processing speed of the calculation of the values
				}else if (splitData[0] == "Progress"){
					document.getElementById("msprogresstime").value = (Number(splitData[1]) + diffProgressTime);
					DELAY = (Number(splitData[1]) + diffProgressTime);
				// Die Zeit des Sonnenaufgangs bei automatischer Berechnung in Textfeld eintragen 
				// Enter the time of sunrise with automatic calculation in text field
				}else if (splitData[0] == "automaticSunrise"){
					document.getElementById("tsunrise").value = dectime2Time(splitData[1],"string");
				// Der Status des Sonnenaufgangs
				// Status of sunrise
				}else if (splitData[0] == "automaticStatSunrise"){
					document.getElementById("statsunrise").value = splitData[1];
				// Die Zeit des Sonnenuntergangs bei automatischer Berechnung in Textfeld eintragen 
				// Enter the time of sunset with automatic calculation in text field
				}else if (splitData[0] == "automaticSunset"){
					document.getElementById("tsunset").value = dectime2Time(splitData[1],"string");
				// Der Status des Sonnenauntergangs
				// Status of sunset
				}else if (splitData[0] == "automaticStatSunset"){
					document.getElementById("statsunset").value = splitData[1];
				// Der Dämmerungsaufgang
				// Twilight rise
				}else if (splitData[0] == "automaticTwilightSunrise"){
					document.getElementById("ttwlsunrise").value = dectime2Time(splitData[1], "string");
				// Status der Dämmerungsaufgang
				// Twilight rise status
				}else if (splitData[0] == "automaticTwilightStatSunrise"){
					document.getElementById("statttwlsunrise").value = splitData[1];
				// Der Dämmerungsuntergang
				// Twilight set
				}else if (splitData[0] == "automaticTwilightSunset"){
					document.getElementById("ttwlsunset").value = dectime2Time(splitData[1], "string");
				// Status des Dämmerungsuntergang
				// Twilight set status
				}else if (splitData[0] == "automaticTwilightStatSunset"){
					document.getElementById("statttwlsunset").value = splitData[1];
				// Der Azimuth des Sonnenaufgangs
				// The azimuth of sunrise
				}else if (splitData[0] == "automaticAZSunrise"){
					document.getElementById("azsunrise").value = splitData[1];
				// Der Status des Azimuth des Sonnenaufgangs
				// The status of azimuth of sunrise
				}else if (splitData[0] == "automaticAZStatSunrise"){
					document.getElementById("statazsunrise").value = splitData[1];
				// Der Azimuth des Sonnenuntergangs
				// The azimuth of sunset
				}else if (splitData[0] == "automaticAZSunset"){
					document.getElementById("azsunset").value = splitData[1];
				// Der Status des Azimuth des Sonnenuntergangs
				// The status of azimuth of sunset
				}else if (splitData[0] == "automaticAZStatSunset"){
					document.getElementById("statazsunset").value = splitData[1];
				// Das Julianische Datum des Sonnenaufgangs
				// Julian date of sunrise
				}else if (splitData[0] == "jdSunrise"){
					document.getElementById("jdsunrise").value = splitData[1];
				// Das Julianische Datum des Sonnenuntergangs
				// Julian date of sunset
				}else if (splitData[0] == "jdSunset"){
					document.getElementById("jdsunset").value = splitData[1];
				// Aus dem JD des höchsten Punkts am Himmel wieder ein Datum berechnen
				// Calculate a date from the JD of the highest point in the sky
				}else if (splitData[0] == "highNoonDate"){
					document.getElementById("timehighnoon").value = splitData[1];
				// Abstand Erde - Sonne in Km
				// Distance Earth – Sun in Km
				}else if (splitData[0] == "sunDiameter"){
					document.getElementById("distancesunearth").value = splitData[1];
				// Durchmesser der Sonne am Himmel Dezimal
				// Diameter of the Sun in the Sky Decimal
				}else if (splitData[0] == "sunDiameterSkyDec"){
					document.getElementById("diasundez").value = splitData[1];
				// Winkeldurchmesser der Sonne in Grad, Minute, Sekunde
				// Angular size as degree, minute and second
				}else if (splitData[0] == "sunDiameterSkyDeg"){
					document.getElementById("diasundeg").value = decDegrees2AngleOfHours(splitData [1]);
				// Der Azimuth des Sonnenhöchststand genau in dez. Grad
				// The azimuth of the sun’s elevation exactly in dec. Degree
				}else if (splitData[0] == "sunAZHigh"){
					document.getElementById("azhighsundez").value = splitData [1];
				// Sonnenhöchstand im Azimuth in Grad
				// Sun’s elevation in azimuth in degrees
				}else if (splitData[0] == "sunHighHigh"){
					document.getElementById("azhighsundeg").value = splitData [1];
				// Der Azimuth des aktuellen Sonnenstandes
				// The azimuth of the current position of the sun
				}else if (splitData[0] == "automaticAZ"){
					document.getElementById("actualazsun").value = splitData[1];
					if (splitData[1] < 0.0){
						document.getElementById("actualazsun").style.color = "red";
						document.getElementById("actualazsun").title = "Der geozentrische Azimuth des Mondes von N->W im horizontalen Koordinatensystem" + " - Mond ist unter dem Horizont!";
						document.getElementById("actualhighsun").style.color = "red";
						document.getElementById("actualhighsun").title = "Die geozentrische Höhe des Mondes über dem Horizont im horizontalen Koordinatensystem" + " - Mond ist unter dem Horizont!";
					}else{
						document.getElementById("actualazsun").style.color = "green";
						document.getElementById("actualazsun").title = "Der geozentrische Azimuth des Mondes von N->W im horizontalen Koordinatensystem" + " - Mond ist ueber dem Horizont!";
						document.getElementById("actualhighsun").style.color = "green";
						document.getElementById("actualhighsun").title = "Die geozentrische Höhe des Mondes über dem Horizont im horizontalen Koordinatensystem" + " - Mond ist ueber dem Horizont!";
					}
				// Die Höhe des aktuellen Sonnenstandes im Horizontalsystem
				// The level of the current position of the sun in the horizontal system
				}else if (splitData[0] == "automaticHigh"){
					document.getElementById("actualhighsun").value = splitData[1];
					if (splitData[1] < 0.0){
						document.getElementById("actualazsun").style.color = "red";
						document.getElementById("actualazsun").title = "Der geozentrische Azimuth des Mondes von N->W im horizontalen Koordinatensystem" + " - Mond ist unter dem Horizont!";
						document.getElementById("actualhighsun").style.color = "red";
						document.getElementById("actualhighsun").title = "Die geozentrische Höhe des Mondes über dem Horizont im horizontalen Koordinatensystem" + " - Mond ist unter dem Horizont!";
					}else{
						document.getElementById("actualazsun").style.color = "green";
						document.getElementById("actualazsun").title = "Der geozentrische Azimuth des Mondes von N->W im horizontalen Koordinatensystem" + " - Mond ist ueber dem Horizont!";
						document.getElementById("actualhighsun").style.color = "green";
						document.getElementById("actualhighsun").title = "Die geozentrische Höhe des Mondes über dem Horizont im horizontalen Koordinatensystem" + " - Mond ist ueber dem Horizont!";
					}
				// Die Rektaszension des aktuellen Sonnenstandes im Äquatorialsystem
				// The recaszension of the current position of the sun in the equatorial system
				}else if (splitData[0] == "automaticRA"){
					document.getElementById("actualrasun").value = splitData[1];
				// Die Deklination des aktuellen Sonnenstandes im Äquatorialsystem
				// The declination of the current position of the sun in the equatorial system
				}else if (splitData[0] == "automaticDEC"){
					document.getElementById("actualdecsun").value = splitData[1];
				// Den Mondaufgang im Textfeld "tmoonrise" ausgeben ...
				// Display the moonrise in the text field “tmoonrise” ...
				}else if (splitData[0] == "moonrise"){
					document.getElementById("tmoonrise").value = splitData[1];
				// Den Status des Mondaufgang im Textfeld "statmoonrise" ausgeben ...
				// Display the state of the moonrise in the text field “statmoonrise” ...
				}else if (splitData[0] == "statemoonrise"){
					document.getElementById("statmoonrise").value = splitData[1];
				// Den Azimuth des Mondaufgangs im Textfeld "moonriseaz" ausgeben ...
				// Display the azimuth of the moonrise in the text field “moonriseaz” ...
				}else if (splitData[0] == "azimuthmoonrise"){
					document.getElementById("moonriseaz").value = splitData[1];
				// Die Höhe des Mondaufgangs im Textfeld "moonriseazh" ausgeben ...
				// Display the altitude of the moonrise in the text field “moonriseazh” ...
				}else if (splitData[0] == "altitudemoonrise"){
					if ( (splitData[1] == "Immer Sichtbar") || (splitData[1] == "Nie Sichtbar") )
						document.getElementById("moonriseazh").value = splitData[1];
					else
						document.getElementById("moonriseazh").value = decDegrees2AngleOfHours(splitData[1]);
				// Den Azimuth des Monduntergangs im Textfeld "moonsetaz" ausgeben ...
				// Display the azimuth of the moonset in the text field “moonsetaz” ...
				}else if (splitData[0] == "azimuthmoonset"){
					document.getElementById("moonsetaz").value = splitData[1];
				// Die Höhe des Monduntergangs im Textfeld "moonsetazh" ausgeben ...
				// Display the altitude of the moonset in the text field “moonsetazh” ...
				}else if (splitData[0] == "altitudemoonset"){
					if ( (splitData[1] == "Immer Sichtbar") || (splitData[1] == "Nie Sichtbar") )
						document.getElementById("moonsetazh").value = splitData[1];
					else
						document.getElementById("moonsetazh").value = decDegrees2AngleOfHours(splitData[1]);
				// Den Monduntergang im Textfeld "tmoonset" ausgeben ...
				// Display the moonset in the text field “tmoonset” ...
				}else if (splitData[0] == "moonset"){
					document.getElementById("tmoonset").value = splitData[1];
				// Den Status des Monduntergang im Textfeld "tmoonset" ausgeben ...
				// Display the state of the moonset in the text field “tmoonset” ...
				}else if (splitData[0] == "statemoonset"){
					document.getElementById("statmoonset").value = splitData[1];
				// Den Status des Monduntergang im Textfeld "tmoonset" ausgeben ...
				// Display the state of the moonset in the text field “tmoonset” ...
				}else if (splitData[0] == "moonhigh"){
					document.getElementById("moonhighdate").value = splitData[1];
				// Den Azimuth des Höchststand des Mondes im Textfeld "moonhighaz" ausgeben ...
				// Display the azimuth of the the maximum of the moon in the text field "moonhighaz" ...
				}else if (splitData[0] == "moonhighaz"){
					document.getElementById("moonhighaz").value = splitData[1];
				// Den Azimuth des Höchststand des Mondes im Textfeld "moonhighaz" ausgeben ...
				// Display the azimuth of the the maximum of the moon in the text field "moonhighaz" ...
				}else if (splitData[0] == "moonhighdeg"){
					document.getElementById("moonhighdeg").value = splitData[1];
				// Die Entfernung Erde-Mond im Textfeld "distmoon" ...
				// Display the distance Earth-Moon in the text field "distmoon"  ...
				}else if (splitData[0] == "moondist"){
					document.getElementById("distmoon").value = splitData[1];
				// Durchmesser des Mondes am Himmel in Grad im Textfeld "diamoon" ausgeben ...
				// Send the Diameter of the Moon in the Sky in degrees to text field "diamoon" ...
				}else if (splitData[0] == "moondia"){
					document.getElementById("diamoon").value = splitData[1];
				// Die aktuelle Höhe des Mondes in Grad
				// The actual altitude of the Moon in degrees ...
				}else if (splitData[0] == "moonh"){
					document.getElementById("hmoon").value = splitData[1];
					if (splitData[1] < 0.0){
						objAzMoon.style.color = "red";
						objHMoon.style.color = "red";
						objAzMoon.title = "Der geozentrische Azimuth des Mondes von N->W im horizontalen Koordinatensystem" + " - Mond ist unter dem Horizont!";
						objHMoon.title = "Die geozentrische Höhe des Mondes über dem Horizont im horizontalen Koordinatensystem" + " - Mond ist unter dem Horizont!";
					}else{
						objAzMoon.style.color = "green";
						objHMoon.style.color = "green";
						objAzMoon.title = "Der geozentrische Azimuth des Mondes von N->W im horizontalen Koordinatensystem" + " - Mond ist ueber dem Horizont!";
						objHMoon.title = "Die geozentrische Höhe des Mondes über dem Horizont im horizontalen Koordinatensystem" + " - Mond ist ueber dem Horizont!";
					}
				// Der aktuelle Azimuth des Mondes in Grad
				// The actual azimuth of the Moon in degrees ...
				}else if (splitData[0] == "moonaz"){
					document.getElementById("azmoon").value = splitData[1];
				}			
				// Ermittelt die Endzeit der Verarbeitung in Millisekunden für das Julianische Datum
				// Determines the end time of processing in milliseconds for the Julian date
				stopProgressTime = Date.now();
				// Wenn die neue Verarbeitungszeit größer ist als die letzte ... 
				// If the new processing time is longer than the last ...
				if ( (Number(stopProgressTime) - Number(startProgressTime)) > diffProgressTime){
					// ... dann speichere die neue Verarbeitungszeit als die Höhere ...
					// ... then save the new processing time as the Higher ...
					diffProgressTime = Number(stopProgressTime) - Number(startProgressTime);
					// und ist die neue Verarbeitungszeit größer als die Wartezeit ...
					// and is the new processing time greater than the waiting time ...
					if ( diffProgressTime > DELAY){
						// dann passe die Wartezeit an plus eine kleine Sicherheit
						// then adjust the waiting time to plus a small security
						DELAY = DELAY + diffProgressTime + 10;
					}				
				}
				
			};// End of workerActualEndless.onmessage
		
		}// End of if (workerActualEndless)
		
	// Der Browser kennt den WebWorker nicht und gibt eine Fehlermeldung aus.
	} else {
		alert("Sorry, your browser does not support Web Workers...");
	}// End of if(typeof(Worker) !== "undefined") 
	
}// End of async function startWorkerActualEndless()



// Setzt die aktuelle Uhrzeit im Overlay für die autom. Berechnungen.
// Sets the current time in the overlay for the autom. Calculations.
function setActualDateAndTimeAutomatic(timezone){
	var h = "";
	var m = "";
	var s = "";
	var ms = "";
	// Zeitzone und DST ermitteln
	// Zuerst die Zeitzone aus der Select Box "Zeitzone" ermittel ...
	// First determine the time zone from the Select Box “Time Zone” ...
	var selectedItemTimezone = objTimezone.options[objTimezone.selectedIndex];
	var timezone = Number(selectedItemTimezone.value);
	// ... und negieren, da damit durch Addition direkt aus Zeitzone und DST 
	// die UT berechnet werden kann ...
	// ... and negate, because by adding directly from time zone and DST 
	// the UT can be calculated ...
	timezone *=  -1;
	// ... dann die Sommer/Winterzeit aus der Select Box "DST" ermittel. Dort ist der Wert für
	// Sommerzeit = 2 und Winterzeit = 1 ...
	// ... then determine the summer/winter time from the Select Box “DST.” There is the value for
	// Summertime = 2 and Wintertime = 1 ...
	var selectedItemDST = objDST.options[objDST.selectedIndex];
	var dst= Number(selectedItemDST.value);
	// ... darum muß der Wert 1 abgezogen werden, damit man direkt den Stundenwert
	// für UT berechnen kann ...
	// ... therefore the value 1 has to be subtracted, so that you can directly calculate the hourly value
	// can calculate for UT ...
	dst -= 1;
	// ... dann noch den Wert negieren um damit nach Ost und West durch Addition 
	// richtig rechnen zu können ...
	// ... then negate the value in order to east and west by addition 
	// to be able to calculate correctly ...
	dst *= -1;
	// ... und dann den Zeitzonenwert als Zeitzone + DST zu erhalten ...
	// ... and then get the time zone value as time zone + DST ...
	TIMEZONE = timezone + dst;
	// Datumspicker mit aktuellem Datum versehen.
	// Date picker with the current date.
	da = new Date();													// Aktuelles Datum holen - Get current date
	objCalcActualDateAutomatic.valueAsDate = da;	// und dem Datumspicker zuweisen - and assign to the date picker
	// Stunde und Minute mit "0" auffüllen und Time Picker
	// Fill the hour and minute with “0” and Time Picker
	// initialize with this.
	// damit initialisieren.
	if ((h = da.getHours()) < 10)
		h = LPad(h, 2, "0");
	if ((m = da.getMinutes()) < 10)
		m = LPad(m, 2, "0");
	objCalcActualTimeAutomatic.value = h + ":" + m;
	// Sekunden mit "0" auffüllen und Sekunden Picker
	// damit initialisieren.
	// Fill seconds with “0” and seconds picker
	// initialize with this.
	s = da.getSeconds();
	objCalcActualSecondAutomatic.value = s;
	// Millisekunden und Millisekunden Picker
	// damit initialisieren.
	// Millisecond and Millisecond Picker
	// initialize with this.
	ms = da.getMilliseconds();
	objCalcActualMSecondAutomatic.value = ms;
	// Startet den Backgroundworker für das Datum des Overlays....
	// Starts the backgroundworker for the date of the overlay....
	if (!wAutomaticTime) startWorker();

}// End of setActualDateAndTimeAutomatic()



// Eventhandler des Input Elements für die Geschwindigkeit = Delay der Berechnungen.
// Wird ausgelöst bei Änderung des Wertes im Eingabefeld.
// Event handler of the input element for the speed = delay of the calculations.
// Is triggered when the value in the input field is changed.
objVelosity.addEventListener ("input",  function (e) {
	// Der Wert der Geschwindigkeit wird dann im Broadcast Kanal gesendet.
	// Im Worker wird der Wert dann empfangen und die Rechengeschwindigkeit
	// neu eingestellt.
	// The value of the speed is then transmitted in the broadcast channel.
	// In the worker the value is then received and the computation speed
	// reset.
	channel.postMessage("velosity=" + e.target.value);
	
});// End of objVelosity.addEventListener ()



// Erstellt den neuen Worker "worker-automatictime.js" für das Overlay.
// Creates the new worker “worker-automatictime.js” for the overlay
function startWorker(){					
	// Worker erstellen, wenn der Datentyp "Worker" im Browser vorhanden ist.
	// Create workers if the “Worker” data type is present in the browser.
	if(typeof(Worker) !== "undefined") {
		// .. und der Worker noch nicht erstellt wurde ...
		// .. and the worker has not yet been created...		
		if(typeof(wAutomaticTime)=="undefined") {			
			// Neues WebWorker Objekt generiert aus der JavaScript Datei.
			// Achtung: Bei lokalen Dateien muss der Browser mit dem
			// Kommandline Parameter: "allow-file-access-from-files" gestartet
			// werden. Andernfalls unter einem Webserver starten.
			//
			// New WebWorker object generated from the JavaScript file.
			// Attention: In case of local files, the browser must use the
			// Commandline parameter: “allow-file-access-from-files” started
			//. Otherwise start under a web server.
			wAutomaticTime = new Worker("../../Bibliotheken/Sonne-Mond/worker-automatictime.js" );					
		}
		// Event Queue über die alle Daten vom WebWorker "worker-automatictime.js" eintreffen.
		// Event queue where all data from the WebWorker “worker-automatictime.js” arrive.
		wAutomaticTime.onmessage = function (event) {
			// Im Array splitData findet man zwei Werte als Key=Value.
			// Sie sind durch "=" getrennt.
			// In the splitData array you find two values as Key=Value.
			// They are separated by “=.”
			splitData = event.data.split("=");
			// Hier, nach dem Key, die einzelnen Ergebnisse den Ausgabebereichen
			// zuweisen.
			// Here, after the key, the individual results of the output areas
			// assign.
			// Das Datum wird vom Worker "worker-automatictime.js" als Datumsobjekt
			// geschickt, ist aber keins ...
			if (splitData[0] == "date"){
				// ... und darum muss es erst in ein echtes Datums Objekt gewandelt werden ...
				// ... and therefore it has to be converted into a real date object ...
				var d = new Date(splitData[1]);
				// ... und wird dann dem Datumspicker zugewiesen ...
				// ... and is then assigned to the date picker ...
				document.getElementById("dateAutomatic").valueAsDate=d;
			// ... der Zeit Picker Stunde und Minute ...
			// ... the numbers Text field hour and minute ...
			}else if (splitData[0] == "StundeMinute"){
				document.getElementById("timeAutomatic").value=splitData[1];
			// Das Zahlen Textfeld Sekunde ...
			// ... the numbers Text field second ...
			}else if (splitData[0] == "Second"){
				document.getElementById("secondAutomatic").value=splitData[1];
			// ... das Zahlen Textfeld Millisekunde ...
			// ... the numbers Text field Millisecond ...
			}else if (splitData[0] == "MSecond"){
				document.getElementById("msecondAutomatic").value=splitData[1];
			}
		};
	// Der Browser kennt den WebWorker nicht und gibt eine Fehlermeldung aus.
	// The browser does not know the WebWorker and displays an error message.
	} else {
			document.getElementById("resultError").innerHTML="Sorry, your browser does not support Web Workers...";
	}
	
}// End of startWorker()



// Der Eventhandler empfängt die Messages vom Worker oder
// einem anderen Teil der Webpage, wie Tab's oder Popups.
// Man kann von allem Empfangen die denselben Kanal benutzen.
//
channel.onmessage = function (e){
	// Im Array splitData findet man zwei Werte als Key=Value.
	// Sie sind durch "=" getrennt.
	// In the splitData array you find two values as Key=Value.
	// They are separated by “=.”
	splitData = e.data.split("=");
	// Hier, nach dem Key, die einzelnen Ergebnisse den Ausgabebereichen
	// zuweisen.
	// Das Datum wird vom Worker "worker-automatictime.js" als Datumsobjekt
	// geschickt, ist aber keins ...
	// Here, after the key, the individual results of the output areas
	// assign.
	// The date is used by the worker “worker-automatictime.js” as a date object
	// sent, but is not ...
	if (splitData[0] == "delay" || splitData[0] == "velosity"){
		// Die vom Worker gemeldete aktuelle Delay im Overlay eintragen.
		// Enter the current delay reported by the worker in the overlay.
		document.getElementsByClassName("returnedvelosity")[0].value = splitData[1];
	}

}// End of channel.onmessage



// Message Queue der Bradcast Channels "comExtern". Hierüber bekommt man zum Beispiel
// mit, wenn das Hauptprogramm "Zeitberechnung.html" geschlossen wird und dann mit das
// Datenausgabefenster auch geschlossen werden.
//
// Message Queue of the Bradcast channels “comExtern.” This gives you, for example,
// with when the main program “Time Calculation.html” is closed and then with the
// Data output window can also be closed.
channelExtern.onmessage = function (e){
		// Im Array splitData findet man zwei Werte als Key=Value.
		// Sie sind durch "=" getrennt.
		// In the splitData array you find two values as Key=Value.
		// They are separated by “=”
		splitData = e.data.split("=");
		// Das Daten Ausgabefenster soll geschlossen werden ...
		// The data output window should be closed ...
		if (splitData[0] == "Cancel"){
				// ... Datenausgabefenster schliessen, wenn "Cancel" kommt.
				// ... Close data output window when “Cancel” comes.
				popup.close();
		}
		
}// End of channelExtern.onmessage



// Beendet den Worker für die Berechnungen "Ab gewähltem Datum" endlos und die Threads.
// Endlessly terminates the worker for the calculations “From selected date” and the threads.
function stopWorkerChoiceDateEndless()
{
	// Worker beenden - Stop the worker
	if (workerChoiceEndless){
		workerChoiceEndless.terminate();
		workerChoiceEndless = undefined;
	}

}// End of stopWorkerChoiceDateEndless()



// Beendet den Worker für die Berechnungen vom "Aktuellen Datum" endlos und die Threads.
// Endlessly terminates the worker for the “Current Date” calculations and threads.
function stopWorkerActualDateEndless()
{
	// Worker beenden - Stop the worker
	if (workerActualEndless){
		workerActualEndless.terminate();
		workerActualEndless = undefined;
	}

}// End of stopWorkerActualDateEndless()



// Beendet den Worker für das Automatische Overlay und die Threads.
// Quits the worker for the Automatic Overlay and the threads.
function stopWorker()
{
	// Worker beenden - Stop the worker
	if (wAutomaticTime){
		wAutomaticTime.terminate();
		wAutomaticTime = undefined;
	}

}// End of stopWorker()