/* Copyright it-motive AG, Duisburg */

// Javascript für AJAXApplications
//
// CallAJAXapplicationGET und CallAJAXapplicationPOST zum Aufruf der Applikation via Javascript
//
// ACHTUNG: alle anderen Funktionen hier werden automatisch aufegrufen!

var AJAXapplicationLocks     = new Object();
var AJAXapplicationPrefixes  = new Object();
var AJAXapplicationCallQueue = new Array();

// CallAJAXapplicationGET()		führt einen AJAX Request aus
// 		Parameter:
// 		- applicationID: 		ID der AJAX Application
// 		- applicationURL:   	URL der AJAX Application
// 		- returnHandler:   		Return-Handler
// 		- errorHandler:   		Error-Handler (optional)
// 		- waitAnchor:   		DOM-Element, an das das Warteelement positioniert werden soll (optional)
// 		- prefix: 				String zur Identifikation der DOM-Elemente für Warte-Element und Applikation (optional, Default ist "AJAXapplication_")
// 		- queueIfLocked: 		Soll der Aufruf in Warteschlange gepackt werden, wenn schon einer läuft - true or false (default)
//
function CallAJAXapplicationGET(applicationID, applicationURL, returnHandler, errorHandler, waitAnchor, prefix, queueIfLocked)
{
	_CallAJAXapplication(applicationID, applicationURL, null, returnHandler, errorHandler, waitAnchor, prefix, queueIfLocked);
}
// CallAJAXapplicationPOST()	führt einen AJAX Request mit Formularparametern aus
// 		Parameter:
// 		- applicationID: 		ID der AJAX Application
// 		- applicationURL:   	URL der AJAX Application
// 		- applicationFORM:   	FORM-Parameter der AJAX Application
// 		- returnHandler:   		Return-Handler
// 		- errorHandler:   		Error-Handler (optional)
// 		- waitAnchor:   		DOM-Element, an das das Warteelement positioniert werden soll (optional)
// 		- prefix: 				String zur Identifikation der DOM-Elemente für Warte-Element und Applikation (optional, Default ist "AJAXapplication_")
// 		- queueIfLocked: 		Soll der Aufruf in Warteschlange gepackt werden, wenn schon einer läuft - true or false (default)
//
function CallAJAXapplicationPOST(applicationID, applicationURL, applicationFORM, returnHandler, errorHandler, waitAnchor, prefix, queueIfLocked)
{
	_CallAJAXapplication(applicationID, applicationURL, applicationFORM, returnHandler, errorHandler, waitAnchor, prefix, queueIfLocked);
}
// The real call (internal method)
function _CallAJAXapplication(applicationID, applicationURL, applicationFORM, returnHandler, errorHandler, waitAnchor, prefix, queueIfLocked)
{
	// Nix tun, solange die AJAX Application blockiert ist
	if(!IsAJAXApplicationLocked(applicationID))
	{
		// Lock anfordern (darin auch Prefix festlegen)
		LockAJAXApplication(applicationID, waitAnchor, prefix);

		// Handler und ID für Return aufbewahren
		var handlerArgs = new Object();
		handlerArgs["applicationID"] = applicationID;
		handlerArgs["returnHandler"] = returnHandler;
		handlerArgs["errorHandler"]	 = errorHandler;

		// Der Request selbst - der Return geht automatisch immer an ReturnFromAJAXApplication() und wird von dort aus weitergeleitet an die Handler der AJAX Application
		if(applicationFORM != null)
		{
			if(!AJAXformRequestXML(applicationURL, applicationFORM, ReturnFromAJAXApplication, handlerArgs))
			{
				// Im Fehlerfall entweder ErrorHandler der AJAX Application oder Standardausgabe id und url über alert
				HandleReturnExceptionInAJAXApplication(handlerArgs, "Call Error", applicationURL, applicationFORM)

				// Lock aufheben
				UnlockAJAXApplication(applicationID);
			}
		}
		else
		{
			if(!AJAXrequestXML(applicationURL, ReturnFromAJAXApplication, handlerArgs))
			{
				// Im Fehlerfall entweder ErrorHandler der AJAX Application oder Standardausgabe id und url über alert
				HandleReturnExceptionInAJAXApplication(handlerArgs, "Call Error", applicationURL)

				// Lock aufheben
				UnlockAJAXApplication(applicationID);
			}
		}
	}
	else if(queueIfLocked)
	{
		AJAXapplicationCallQueue.push(new QueuedAJAXApplicationCall(applicationID, applicationURL, applicationFORM, returnHandler, errorHandler, waitAnchor, prefix, queueIfLocked));
	}
}

// ReturnFromAJAXApplication()	führt den AJAX Return aus - wird automatisch aufgerufen!
// 		Parameter:
// 		- httpRequest: 		ID der AJAX Application
// 		- handlerArgs:   	Struktur mit den Elementen "applicationID" und "returnHandler"
//
function ReturnFromAJAXApplication(httpRequest, handlerArgs)
{
	if(httpRequest.readyState == 4)
	{
		if(handlerArgs && handlerArgs["applicationID"])
		{
			// Standardverhalten bei Status 200 = "OK"
			if(httpRequest.status == 200)
			{
				// Error Handling in der AJAX Application
				var appElement = document.getElementById(AJAXapplicationPrefixes[handlerArgs["applicationID"]]+handlerArgs["applicationID"]+"_div");
				if(appElement)
				{
					var oldErrorElements = appElement.getElementsByTagName("AJAXapplicationError");
					var newErrorElements = httpRequest.responseXML.getElementsByTagName("AJAXapplicationError");

					// Alte Fehlermeldungen wegwerfen
					if(oldErrorElements && oldErrorElements.length > 0)
					{
						for(var i=0; i<oldErrorElements.length; i++) oldErrorElements[i].parentNode.removeChild(oldErrorElements[i]);
					}
					// Neue Fehlermeldungen einbauen
					if(newErrorElements && newErrorElements.length > 0)
					{
						for(var i=0; i<newErrorElements.length; i++) appElement.appendChild(CloneDOMnode(newErrorElements[i], document, true));
					}
				}

				// Und nun zum ReturnHandler der AJAX Application
				try
				{
					if(handlerArgs["returnHandler"]) handlerArgs["returnHandler"](httpRequest);
				}
				catch(e)
				{
					//	Zum Debugging hilfreich, wenn der ReturnHandler fehlerhaft ist
					//	HandleReturnExceptionInAJAXApplication(handlerArgs, "Return Handler Exception", httpRequest, e);
				}
			}
			// Im Fehlerfall entweder ErrorHandler der AJAX Application oder Standardausgabe des Status über alert
			else HandleReturnExceptionInAJAXApplication(handlerArgs, "Return Error", httpRequest);

			// Lock aufheben
			UnlockAJAXApplication(handlerArgs["applicationID"]);
		}
		else alert("Fatal AJAX Application Error: no handler arguments specified");
	}
}
// HandleReturnExceptionInAJAXApplication()	führt den Exception Handler aus - wird automatisch aufgerufen!
function HandleReturnExceptionInAJAXApplication(handlerArgs, errorType, v1, v2)
{
	if(handlerArgs["errorHandler"])
	{
		try
		{
			handlerArgs["errorHandler"](handlerArgs["applicationID"], errorType, v1, v2);
		}
		catch(e)
		{
			//	Zum Debugging hilfreich, wenn der ErrorHandler fehlerhaft ist
			//	HandleReturnErrorInAJAXApplication(handlerArgs["applicationID"], errorType, v1, v2);
		}
	}
	else HandleReturnErrorInAJAXApplication(handlerArgs["applicationID"], errorType, v1, v2);
}
// HandleReturnExceptionInAJAXApplication()	führt den Error Handler aus - wird automatisch aufgerufen!
function HandleReturnErrorInAJAXApplication(applicationID, errorType, v1, v2)
{
	var responseText = "";

	if(errorType == "Call Error") responseText = "URL: "+v1+"\nFORM: "+v2;
	else		// Return Error
	{
		if(v2) 	// Return Handler Exception
		{
			responseText = "EXCEPTION: ";
			for(var i in v2) responseText = responseText + "\n" + i + ": " + v2[i];
		}

		//	Nachfolgende Zeile kann zum Debugging hilfreich sein, wenn ein "internal Server Error" gemeldet wird und keine Mail ankommt
		//	if(v1.responseText) responseText =  "RETURN-XML: " + v1.responseText.replace(/^\s+|\s+$/g, '').replace(/\s+\s+/g, '') + "\n" + responseText;
		responseText = "AJAX Return Status: "+v1.status+" \""+v1.statusText+"\"\n"+responseText;
	}
	// Am Ende: Fehlerausgabe per alert()
	alert("AJAX Application \""+errorType+"\" for id: "+applicationID+"\n"+responseText);
}

// IsAJAXApplicationLocked()	check, ob eine AJAX Application gelockt ist
// 		Parameter:
// 		- applicationID: 		ID der AJAX Application
//
function IsAJAXApplicationLocked(applicationID)
{
	return(AJAXapplicationLocks[applicationID]);
}
// LockAJAXApplication()		lock einer AJAX Application
// 		Parameter:
// 		- applicationID: 		ID der AJAX Application
// 		- waitAnchor: 			DOM-Element, an das das Warteelement positioniert werden soll (optional)
// 		- prefix: 				String zur Identifikation der DOM-Elemente für Warte-Element und Applikation (optional, Default ist "AJAXapplication_")
//
function LockAJAXApplication(applicationID, waitAnchor, prefix)
{
	// Lock erstellen
	AJAXapplicationLocks[applicationID] = true;

	// Prefix festlegen (entweder über Argument oder Default)
	if(prefix) AJAXapplicationPrefixes[applicationID] = prefix;
	else       AJAXapplicationPrefixes[applicationID] = "AJAXapplication_";

	// Warte-Element anzeigen (und positionieren)
	var waitElement = document.getElementById(AJAXapplicationPrefixes[applicationID]+applicationID+"_waitAjax");
	var appElement  = document.getElementById(AJAXapplicationPrefixes[applicationID]+applicationID+"_div");

	if(waitElement)
	{
		if(waitAnchor) position = GetPosition(waitAnchor);
		else           position = GetPosition(appElement);

		waitElement.style.display         = "block";
		waitElement.style.backgroundColor = "white";
		waitElement.style.padding         = "2px";
		waitElement.style.borderWidth     = "1px";
		waitElement.style.borderStyle     = "solid";
		waitElement.style.borderColor     = "#153b62";
		waitElement.style.position        = "absolute";
		waitElement.style.left            = position.x;
		waitElement.style.top             = position.y;
	}
}
// UnlockAJAXApplication()	unlock einer AJAX Application
// 		Parameter:
// 		- applicationID: 		ID der AJAX Application
//
function UnlockAJAXApplication(applicationID)
{
	// Warte-Element unsichtbar machen
	var waitElement = document.getElementById(AJAXapplicationPrefixes[applicationID]+applicationID+"_waitAjax");
	if(waitElement) waitElement.style.display = "none";

	// Prefix leeren
	AJAXapplicationPrefixes[applicationID] = "";

	// Lock löschen
	AJAXapplicationLocks[applicationID] = false;

	// ersten aus Queue abarbeiten (jeder weitere dann jeweils im Anschluss)
	if(AJAXapplicationCallQueue.length) AJAXapplicationCallQueue.shift().resubmit();
}

// QueuedAJAXApplicationCall()	Struktur für einen Call der in Warteschlange aufbewahrt wird
// 		Parameter:
// 		- applicationID: 		ID der AJAX Application
// 		- applicationURL:   	URL der AJAX Application
// 		- applicationFORM:   	FORM-Parameter der AJAX Application
// 		- returnHandler:   		Return-Handler
// 		- errorHandler:   		Error-Handler (optional)
// 		- waitAnchor:   		DOM-Element, an das das Warteelement positioniert werden soll (optional)
// 		- prefix: 				String zur Identifikation der DOM-Elemente für Warte-Element und Applikation (optional, Default ist "AJAXapplication_")
// 		- queueIfLocked: 		Soll der Aufruf in Warteschlange gepackt werden, wenn schon einer läuft - true or false (default)
//
function QueuedAJAXApplicationCall(applicationID, applicationURL, applicationFORM, returnHandler, errorHandler, waitAnchor, prefix, queueIfLocked)
{
	this.applicationID   = applicationID;
	this.applicationURL  = applicationURL;
	this.applicationFORM = applicationFORM;
	this.returnHandler   = returnHandler;
	this.errorHandler    = errorHandler;
	this.waitAnchor      = waitAnchor;
	this.prefix          = prefix;
	this.queueIfLocked   = queueIfLocked;

	this.resubmit = ResubmitQueuedAJAXApplicationCall;
}
// Resubmit-Funktion
function ResubmitQueuedAJAXApplicationCall()
{
	if(IsAJAXApplicationLocked(this.applicationID)) AJAXapplicationCallQueue.push(this);
	else                                            _CallAJAXapplication(this.applicationID, this.applicationURL, this.applicationFORM, this.returnHandler, this.errorHandler, this.waitAnchor, this.prefix, this.queueIfLocked);
}

