/**
 * Methode ermittelt die Groesse der Seite und gibt diese in einem Array [width,height] zurueck
 *
 * @return array
 */
jQuery.getPageSize = function(){
	var de = document.documentElement;
	var w = window.innerWidth || self.innerWidth || (de&&de.clientWidth) || document.body.clientWidth;
	var h = window.innerHeight || self.innerHeight || (de&&de.clientHeight) || document.body.clientHeight;
	arrayPageSize = [w,h];
	return arrayPageSize;
}

/**
* Methode überschriebt die Standardalertbox des Browsers und ruft
* die jQuery-setErrorMessage-Methode auf. Zusätzlich kann festgelegt werden,
* ob die Ausgabe lediglich in der Konsole des Browsers ausgegeben werden soll (wenn verfügbar).
* 
* @see setErrorMessage
* @param string	message			Nachricht, die in der Alertbox ausgegeben werden soll
* @param bool 	onlyConsole 	Wenn True, erfolgt die Ausgabe nur in der Konsole des Browsers (wenn verfügbar)
* @return void
*/
window.alert = function(message, onlyConsole)
{
	jQuery.setErrorMessage(message, onlyConsole);
}

/**
* Methode gibt Ausgabe in der Konsole des Browsers aus (wenn verfügbar).
* 
* @see setErrorMessage
* @param string	message			Nachricht, die in der Konsole ausgegeben werden soll
* @return void
*/
window.debug = function(message)
{
	jQuery.setErrorMessage(message, true);
}

/**
* Methode gibt eine Nachricht in einer Infobox aus
* 
* @param string	message			Nachricht, die in der Infobox ausgegeben werden soll
* @see setInfoMessage
* @return void
*/
window.info = function(message)
{
	jQuery.setInfoMessage(message);
}

/**
* Methode gibt eine Nachricht in einer Alertbox aus
* 
* @param string	msgTxt			Nachricht, die in der Alertbox ausgegeben werden soll
* @param bool 	onlyConsole 	Wenn True, erfolgt die Ausgabe nur in der Konsole des Browsers (wenn verfügbar)
* @return void
*/
jQuery.setErrorMessage = function(msgTxt, onlyConsole)
{
	$('#ajaxLoader, #page_last_message, #page_last_error').hide();
	$('#page_last_error div.containerText').html( " " );
	if(typeof(window.console) == "object") {
		console.debug(msgTxt);
	}
	if( onlyConsole == true && typeof(onlyConsole) != "undefined" ){
		return;
	}
	var arrayPageSize = jQuery.getPageSize();
	var size = [500, 200];
	var position = [(arrayPageSize[1]-size[1])/2, (arrayPageSize[0]-size[0])/2];
	$('#page_last_error div.containerText').html( jQuery.nl2br(jQuery.trim(msgTxt)) );
	$('#page_last_error').css({
		'width' : size[0] + 'px',
		'top' : position[0] + 'px',
		'height' : size[1] + 'px',
		'left' : position[1] + 'px',
		'opacity' : 0.95
	}).fadeIn("slow").click(function () { $(this).fadeOut("fast"); });
}

/**
 * Methode gibt eine Nachricht in einer Infobox aus
 *
 * @param string	msgTxt			Nachricht, die in der Infobox ausgegeben werden soll
 * @return void
 */
jQuery.setInfoMessage = function(msgTxt)
{
    var setInfoMessagefadeOutTimer = null;
	$('#ajaxLoader, #page_last_message, #page_last_error').hide();
	$('#page_last_message div.containerText').html( " " );
	var arrayPageSize = jQuery.getPageSize();
	var size = [500, 200];
	var position = [(arrayPageSize[1]-size[1])/2, (arrayPageSize[0]-size[0])/2];
	$('#page_last_message div.containerText').html( jQuery.nl2br(jQuery.trim(msgTxt)) );
	$('#page_last_message').css({
		'width' : size[0] + 'px',
		'top' : position[0] + 'px',
		'height' : size[1] + 'px',
		'left' : position[1] + 'px',
		'opacity' : 0.95
	}).fadeIn("slow", function(){
 		if (setInfoMessagefadeOutTimer) clearTimeout(setInfoMessagefadeOutTimer);
 		setInfoMessagefadeOutTimer = setTimeout( function(){
 			$('#page_last_message').fadeOut("slow");
 		}, 2000 );
 	}).click(function () { $(this).fadeOut("fast"); });
}

/**
* Methode erstellt ein Dialogfeld zur Bestätigung von Löschvorgängen
* 
* @param string titleCaption 	Ueberschrift für Dialogbox
* @param string titleOk 		Titel für den OK-Button
* @param string titleCancel 	Titel für den Abbrechen-Button
* @param string okAction 		Url oder funktion, die nach dem Klick auf 'ok' aufgerufen werden soll
* @param string boxContent 		Anzuzeigender Inhalt in der Dialogbox (optinal)
* @param string objExpr 		Selector für die Dialogbox (optinal)
* @return void
*/
jQuery.openDialogDelete = function (titleCaption, titleOk, titleCancel, okAction, boxContent, objExpr)
{
	if( !okAction )
	{
		return false;
	}
	var objExpr = ( !objExpr ? 'div#deleteDialogBox' : objExpr );
	var buttonObj = new Object();
	if( typeof(okAction) != 'function' )
	{
		buttonObj[titleOk] = function() { location.href = okAction; };
	}
	else
	{
		buttonObj[titleOk] = okAction;
	}
	buttonObj[titleCancel] = function() { $(this).dialog('close'); };
	if( boxContent != '' )
	{
		$(objExpr).text( boxContent );
	}
	$(objExpr).dialog({
		bgiframe: true,
		autoOpen: true,
		resizable: false,
		draggable: false,
		title: ( !titleCaption ? 'Delete Element' : titleCaption ),
		height: 100,
		width: 400,
		modal: true,
		overlay: {
			backgroundColor: '#000',
			opacity: 0.5
		},
		buttons: buttonObj
	}).dialog('open');
}

/**
* Methode erweitert die jQuery um SOAP-Request via Ajax und versendet die Formulardaten
* 
* @param string url 		Url, zu der die SOAP-Verbindung aufgenommen werden soll
* @param string action 		aufzurufende Aktion beim Server
* @param string primary 	Optional, 1.Parameter eine ID oder null
* @param string callback	Optional, JS-Funktionsname der funktion die die Antowrt verarbeiten soll
* @param string afterCallBack	Optional, JS-Funktionsname der eigens definierten callback funktion
* @return object
*/
jQuery.fn.sendFormBySoap = function(url,action,primary,callback,afterCallBack)
{
	return this.each(function(){
		if( $(this).is("form") )
		{
			try {
				var soapBody = new SOAPObject(action);
				soapBody.appendChild( new SOAPObject("primary") ).val( ( primary ? primary : '' ) );
				var post = soapBody.appendChild( new SOAPObject("post") );
				jQuery.appendObjectStructure( post, jQuery.translateFormFieldsToObject( $(this) ) );
				var soapRequest = new SOAPRequest(action, soapBody);
				soapRequest.addNamespace('xsi', 'http://www.w3.org/2001/XMLSchema-instance');
				soapRequest.addNamespace('xsd', 'http://www.w3.org/2001/XMLSchema');
				SOAPClient.Proxy = url;
				var formObj = $(this);
				if( !callback )
				{
					callback = function( respObj ) {
						var faultCode = $(SOAPClient.ResponseXML).find('faultcode:first').text();
						if( faultCode )
						{
							alert( $(SOAPClient.ResponseXML).find('faultstring:first').text() );
							return true;
						}
						var returnForward = $(SOAPClient.ResponseXML).find('return > item > key:contains("returnForward"):first').next().text();
						var returnCode = $(SOAPClient.ResponseXML).find('return > item > key:contains("returnCode"):first').next().text().toLowerCase();
						var returnString = $(SOAPClient.ResponseXML).find('return > item > key:contains("returnString"):first').next().text();
						var returnArray = $(SOAPClient.ResponseXML).find('return > item > key:contains("returnArray"):first').next().children();
                        var returnHtml = $(SOAPClient.ResponseXML).find('return > item > key:contains("returnHtml"):first').next().html();
                        if( jQuery.isFunction(afterCallBack) )
                        {
                            afterCallBack( formObj, SOAPClient );
                        }
						if( returnForward != '' )
						{
							location.href = returnForward;
							return true;
						}
						jQuery.each(returnArray, function(index, val) {
							var formFieldName = $(this).find("key:first").text();
							var formFieldValue = $(this).find("value:first").text();
							jQuery.each(formObj.find('*[name='+formFieldName+']'), function(elementIndex, elementVal) {
								if( $(this).is(':hidden') || $(this).is(':text') )
								{
									$(this).val( formFieldValue );
									return true;
								}
								if( $(this).is('textarea') )
								{
									$(this).val( formFieldValue );
									$(this).text( formFieldValue );
									return true;
								}
								if( $(this).is('select') )
								{
									$(this).find('option').removeAttr( 'selected' );
									$(this).find('option[value="'+formFieldValue+'"]').attr('selected','selected');
									return true;
								}
								if( $(this).is(':checkbox') || $(this).is(':radio') )
								{
									$(this).attr('checkbox','checkbox');
									return true;
								}
							});
						});
						if( returnCode == 'true' || returnCode == 'ok' )
						{
							info( returnString );
							return true;
						}
						if( returnString )
						{
							alert( returnString );
							return false;
						}
						debug( "Undefined Error by SOAP-Request. \n" +
								"url: " + url + "\n" +
								"action: " + action + "\n" +
								"primary: " + primary + "\n" +
								"callback: " + callback + "\n" +
								"SOAPClient.Response: \n "+ SOAPClient.ResponseText );
						return false;
					};
				}
				SOAPClient.SendRequest(soapRequest, callback);
			} catch(e){
				debug( "Exception: Undefined SoapError!" + "\n" +
						"url: " + url + "\n" +
						"action: " + action + "\n" +
						"primary: " + primary + "\n" +
						"callback: " + callback + "\n"
						);
				alert( 'Exception: Undefined SoapError!' );
				return false;
			}
		}
	});
}

/**
* Methode hängt an das übergebene Eltern-SOAPObject das übergebene Element.
* Die Methode entscheidet anhand des Types des übergebenen Elementes,
* wie es dieses verarbeiten muss.
* Die Methode ruft sich selbst rekursiv auf.
* 
* @param object parentObj 	das Eltern-SOAPObject
* @param object childObj 	das einzuhängende Element.
* @return void
*/
jQuery.appendObjectStructure = function ( parentObj, childObj )
{
	if( parentObj.typeOf != "SOAPObject" )
	{
		return '';
	}
	switch( typeof(childObj) )
    {
	    case "string":
	    	// parentObj.val( childObj.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;") );
	    	// parentObj.val( childObj );
	        parentObj.val( '<![CDATA[' + childObj.toString() + ']]>' );
	    break;
	    case "number":
	    case "boolean":
	        parentObj.val( childObj.toString() );
		break;
	    case "object":
			for(var p in childObj)
			{
				var type = p;
	            if(!isNaN(p)) // linear array
	            {
	                (/function\s+(\w*)\s*\(/ig).exec(p.constructor.toString());
	                type = RegExp.$1;
	                switch(type)
	                {
	                    case "":
	                        type = typeof(childObj);
	                    case "String":
	                        type = "string"; break;
	                    case "Number":
	                        type = "int"; break;
	                    case "Boolean":
	                        type = "bool"; break;
	                    case "Date":
	                        type = "DateTime"; break;
	                }
	            }
	            if( childObj[p].constructor.toString().indexOf("function Array()") > -1)
	            {
	            	for(var p2 in childObj[p])
	            	{
	            		var nextDepth = parentObj.appendChild( new SOAPObject(type) );
	            		jQuery.appendObjectStructure( nextDepth, childObj[p][p2] );
	            	}
	            }
	            else
	            {
		            var nextDepth = parentObj.appendChild( new SOAPObject(type) );
		            jQuery.appendObjectStructure( nextDepth, childObj[p] );
	            }
			}
		break;
    }
}

/**
* Wandelt alle Formularfelder aus einem Formobjekt in ein Objekt um und gibt dieses zurueck
* 
* @param object objRef 	Formularobjekt
*/
jQuery.translateFormFieldsToObject = function ( objRef )
{
	var structure = {};
	var lastObj = lastIndexObj = null;
	var lastIndex = 0;
	jQuery.each($(objRef).find(":input"), function(index, val) {
		if( ($(this).attr('type') == 'radio' || $(this).attr('type') == 'checkbox') && ! $(this).attr('checked'))
		{
			// nicht gesetzte Checkboxen und Radiobuttons ignorieren
			return;
		}
		if( $(this).is('select') && $(this).find('option').length == 0 )
		{
			// Leere Auswahllisten ignorieren
			return;
		}
		if( $(this).is('select') && $(this).attr('multiple') && $(this).find('option:selected').length == 0 )
		{
			// Leere Mehrfachauswahllisten ignorieren
			return;
		}
		var inputName = $(this).attr('name').split('[');
		if(inputName.length == 1)
		{
			structure[inputName.shift()] = $(this).val();
		}
		else
		{
			for(var i=0; i < inputName.length; i++)
			{
				var keyName = inputName[i].replace(']','');
				if(i==0)
				{
					if (typeof structure[keyName] != "object")
					{
						var nextLevelKeyForCheck = inputName[(i+1)].replace(']','');
						if( !(nextLevelKeyForCheck != '' && isNaN(nextLevelKeyForCheck)) ) {
							structure[keyName] = [];
						} else {
							structure[keyName] = {};
						}
					}
					lastObj = structure[keyName];
				}
				else if( inputName[i].indexOf(']') == 0 ) // autocounter
				{
					lastObj.push( $(this).val() );
				}
				else if((i+1) == inputName.length) // letztes Element
				{
					lastObj[keyName] = $(this).val();
				}
				else // Neue Tiefe in der Struktur erzeugen
				{
					if (typeof lastObj[keyName] != "object")
					{
						if( inputName[(i+1)].indexOf(']') == 0 ) {
							lastIndex = 0;
							lastObj[keyName] = [];
						} else {
							lastObj[keyName] = {};
						}
					}
					lastObj = lastObj[keyName];
				}
			}
		}
    });
    return structure;
}

/**
* Hilfsmethode für die print_r Funktion.
* 
* @param integer laenge 	Zeichenlänge
*/
jQuery.print_r_padding = function (laenge)
{
	result = '';
	for (i = 0; i < laenge; i++)
	{
		result = result + '___';
	}
	return result;
}

/**
 * Methode gibt Informationen zu einem Array oder Objekt in menschenlesbarer Form zurück.
 * 
* @param array 		arrElement 	Das auszugebende Array oder Objekt 
* @param integer 	ebene		Ebene, die ausgegeben werden soll
* @param integer 	maxDepth	Maximale Anzahl der Ebenentiefe, die durchlaufen werden soll, wenn nichts gesetzt oder -1, dann gibt es keine Beschraenkung
 */
jQuery.print_r = function(arrElement, ebene, maxDepth)
{
	var result = ''; 
	if( !ebene || isNaN(ebene) )
	{
		var ebene = 0;
	}
	else
	{
		var ebene = parseInt(ebene);
	}
	if( !maxDepth || isNaN(maxDepth) )
	{
		var maxDepth = -1;
	}
	else
	{
		var maxDepth = parseInt(maxDepth);
	}
	if( ebene > maxDepth && maxDepth != -1 )
	{
		return result;
	} 
	for (var wert in arrElement)
	{
		if (typeof arrElement[wert] == "object") 
		{
			result = result + ' ' + jQuery.print_r_padding(ebene) + wert + "\n" + jQuery.print_r(arrElement[wert], ebene + 1, maxDepth);
		}
		else
		{
			result = result + ' ' + jQuery.print_r_padding(ebene) + wert + ' = ' + arrElement[wert] + "\n";
		}
	}
	return result;
}


/**
* Methode gibt den string  mit einem vor allen Neue-Zeile-Zeichen eingefügten '<br />' oder '<br>' zurück.
*     example 1: nl2br('One\nTwo\nThree');
*     returns 1: 'One<br />\nTwo<br />\nThree'
*     example 2: nl2br("\nOne\nTwo\n\nThree\n", false);
*     returns 2: '<br>\nOne<br>\nTwo<br>\n<br>\nThree<br>\n'
*     example 3: nl2br("\nOne\nTwo\n\nThree\n", true);
*     returns 3: '<br />\nOne<br />\nTwo<br />\n<br />\nThree<br />\n'
* 
* @param string str 		Die Eingabezeichenkette. 
* @param bool is_xhtml 		Bestimmt, ob XHTML-kompatible Zeilenumbrüche verwendet werden sollen oder nicht (Standardwert ist TRUE). 
* @return string 			Gibt die veränderte Zeichenkette zurück. 
*/
jQuery.nl2br = function(str, is_xhtml)
{
    breakTag = '<br />';
    if (typeof is_xhtml != 'undefined' && !is_xhtml) {
        breakTag = '<br>';
    }
    return (str + '').replace(/([^>]?)\n/g, '$1'+ breakTag +'\n');
}

jQuery.fn.extend({
  scrollTo : function(speed, easing) {
    return this.each(function() {
      var targetOffset = $(this).offset().top;
      $('html,body').animate({scrollTop: targetOffset}, speed, easing);
    });
  }
});

/**
* Wandelt alle Formularfelder aus einem Formobjekt in ein Objekt um und gibt dieses zurueck
*
* @param object objRef 	Formularobjekt
*/
function getSaveFormFieldsToObject( objRef )
{
    var structure = {};
    var lastObj = lastIndexObj = null;
    var lastIndex = 0;
    jQuery.each($(objRef).find(":input"), function(index, val) {
        if( ($(this).attr('type') == 'radio' || $(this).attr('type') == 'checkbox') && ! $(this).attr('checked'))
        {
            // nicht gesetzte Checkboxen und Radiobuttons ignorieren
            return;
        }
        if( $(this).is('select') && $(this).find('option').length == 0 )
        {
            // Leere Auswahllisten ignorieren
            return;
        }
        if( $(this).is('select') && $(this).attr('multiple') && $(this).find('option:selected').length == 0 )
        {
            // Leere Mehrfachauswahllisten ignorieren
            return;
        }
        var inputName = $(this).attr('name').split('[');
        if(inputName.length == 1)
        {
            structure[inputName.shift()] = $(this).val();
        }
        else
        {
            for(var i=0; i < inputName.length; i++)
            {
                var keyName = inputName[i].replace(']','');
                if(i==0)
                {
                    if (typeof structure[keyName] != "object")
                    {
                        var nextLevelKeyForCheck = inputName[(i+1)].replace(']','');
                        if( !(nextLevelKeyForCheck != '' && isNaN(nextLevelKeyForCheck)) ) {
                            structure[keyName] = [];
                        } else {
                            structure[keyName] = {};
                        }
                    }
                    lastObj = structure[keyName];
                }
                else if( inputName[i].indexOf(']') == 0 ) // autocounter
                {
                    lastObj.push( $(this).val() );
                }
                else if((i+1) == inputName.length) // letztes Element
                {
                    lastObj[keyName] = $(this).val();
                }
                else // Neue Tiefe in der Struktur erzeugen
                {
                    if (typeof lastObj[keyName] != "object")
                    {
                        if( inputName[(i+1)].indexOf(']') == 0 ) {
                            lastIndex = 0;
                            lastObj[keyName] = [];
                        } else {
                            lastObj[keyName] = {};
                        }
                    }
                    lastObj = lastObj[keyName];
                }
            }
        }
    });
    return structure;
}

/**
* Wandelt alle Formularfelder aus einem Formobjekt in ein Objekt um und gibt dieses zurueck
*
* @param object objRef 	Formularobjekt
*/
function getDeleteCheckboxFieldsToObject( objRef )
{
    var structure = {};
    var lastObj = lastIndexObj = null;
    var lastIndex = 0;
    jQuery.each($(objRef).find(":checkbox"), function(index, val) {
        if( $(this).attr('checked') )
        {
            // alle aktiven Checkboxen ignorieren
            return;
        }
        var inputName = $(this).attr('name').split('[');
        if(inputName.length == 1)
        {
            structure[inputName.shift()] = $(this).val();
        }
        else
        {
            for(var i=0; i < inputName.length; i++)
            {
                var keyName = inputName[i].replace(']','');
                if(i==0)
                {
                    if (typeof structure[keyName] != "object")
                    {
                        var nextLevelKeyForCheck = inputName[(i+1)].replace(']','');
                        if( !(nextLevelKeyForCheck != '' && isNaN(nextLevelKeyForCheck)) ) {
                            structure[keyName] = [];
                        } else {
                            structure[keyName] = {};
                        }
                    }
                    lastObj = structure[keyName];
                }
                else if( inputName[i].indexOf(']') == 0 ) // autocounter
                {
                    lastObj.push( $(this).val() );
                }
                else if((i+1) == inputName.length) // letztes Element
                {
                    lastObj[keyName] = $(this).val();
                }
                else // Neue Tiefe in der Struktur erzeugen
                {
                    if (typeof lastObj[keyName] != "object")
                    {
                        if( inputName[(i+1)].indexOf(']') == 0 ) {
                            lastIndex = 0;
                            lastObj[keyName] = [];
                        } else {
                            lastObj[keyName] = {};
                        }
                    }
                    lastObj = lastObj[keyName];
                }
            }
        }
    });
    return structure;
}


 /**
  * Methode bindet die globalen Ajax-Handler fuer den visuellen Loader
  * @return void
  */
 function initAjaxLoader(){
     $("#ajaxLoader").ajaxSend(function(event, request, settings){
 		showLoader($("#ajaxLoader"));
     });
     $("#ajaxLoader").ajaxSuccess(function(evt, request, settings){
     	$(this).fadeOut("slow");
     });
     $("#ajaxLoader").ajaxStop(function(){
     	$(this).fadeOut("slow");
     });
     $("#ajaxLoader").ajaxError(function(event, request, settings){
     	$(this).fadeOut("slow");
     	alert("Ajax Error: " + settings.url);
     });
 }

function showLoader(loader) {
	if(typeof(loader) == "undefined") {
		loader = $("#ajaxLoader");
	}
	var arrayPageSize = jQuery.getPageSize();
	var size = [500, 80];
	var position = [(arrayPageSize[1]-size[1])/2, (arrayPageSize[0]-size[0])/2];
	$(loader).css({
		'text-align' : 'center',
		'padding' : '20px',
		'width' : size[0] + 'px',
		'top' : position[0] + 'px',
		'height' : size[1] + 'px',
		'left' : position[1] + 'px',
		'opacity' : 0.95
	}).fadeIn("slow");
 }

 function hideLoader() {
	 $("#ajaxLoader").fadeOut("slow");
 }