// configuration
// constants
var RESPONSE_STATE_OK = 'OK';
var RESPONSE_STATE_EXCEPTION = 'EXCEPTION';
var STATE_SESSION_TIMEOUT = "SESSION_TIMEOUT";

// how many error messages should be displayed
// if more errors occur, those will be shown in a tooltip
// set to -1 for infinite error messages
var ERROR_MSG_MAX_DISPLAY = 1;

// div style class that should be added to the labels of fields that have errros
var ERROR_CLASS = "error";

//Name der einzelnen Error-Container
var errorElement = '#error_message';
var layerErrorElement = '#layerErrorMsg'; 

//#############################################################################
//############################     public       ###############################
//############################    Methoden      ###############################
//#############################################################################
function doAjaxCallOnButtonClick(event, myCallback) {
	var formId = getFormIdFromEvent(event);
	var remoteFunction = getButtonNameFromEvent(event);
	sendFormAsynch(formId, remoteFunction, myCallback);
	
}

function getFormIdFromEvent(event) {
	return event.target.form.id;
}

function getButtonNameFromEvent(event) {
	return event.target.name;	
}



function submitFormByButtonId(formName, submitButtonName) {
  var actionProperty = $j('#' + submitButtonName).attr("name"); 
  _submitForm(formName, actionProperty);
} 

function submitForm(formName, actionProperty) {
	_submitForm(formName, actionProperty);
} 

/**
 * Loescht alte Meldungen und entfernt bei allen Labels die errorClass
 */
function clearOldMessages() {
	_clearOldMessages(errorElement);
	_clearErrorLabels(errorElement);
}

/**
 * Loescht alte Meldungen im Layer und entfernt bei allen Labels die errorClass
 */
function clearOldLayerMessages() {
  _clearOldMessages(layerErrorElement);
  _clearErrorLabels(layerErrorElement);
}

/**
 * Behandlung bzw. Darstellung von Fehlern in Layern.
 */  
function handleLayerMessages(formValidationResult) {
  _onMessages(formValidationResult, layerErrorElement);
}
 
/**
 * Behandlung bzw. Darstellung von Fehlern auf "normalen" Seiten.
 */  
function handleMessages(formValidationResult) {
  _onMessages(formValidationResult, errorElement);
}

/**
 * Asynchrones Abschicken eines Formulars
 */
function sendFormAsynch(formId, remoteFunction, mycallback, errorCallback) {
	_sendFormAsynch(formId, remoteFunction, mycallback, errorCallback, false, null);
}

/**
 * Asynchrones Abschicken eines Formulars im Layer
 */
function sendLayerFormAsynch(formId, remoteFunction, mycallback, errorCallback) {
	_sendFormAsynch(formId, remoteFunction, mycallback, errorCallback, true, null);
}

//#############################################################################
//############################     private      ###############################
//############################    Methoden      ###############################
//#############################################################################

function _submitForm(formName, actionProperty) {
	  $j('#' + formName).append('<input id="' + formName + actionProperty + '" type="submit" name="' + actionProperty + '" style="display:none" />');
	  $j('#' + formName + actionProperty).click();
} 

/**
 * Entfernt an dem uebergebenen Elelement den Text.
 */
function _clearOldMessages(targetElement) {
  $j(targetElement).html('');
}

/**
 * Entfernt an alles Labels die sytle-Class "error".
 */
function _clearErrorLabels(errorDiv) {
  var labels = $j("label[class='"+ERROR_CLASS+"']");
  for (var i = 0; i < labels.length; i++) {
    var id = $j(labels[i]).attr("id");
    $j('#'+id).removeClass(ERROR_CLASS);
    $j('#'+id).removeAttr("title");
    $j('#'+id).tooltip();
  }
  $j(errorDiv).removeAttr("title");
  $j(errorDiv).tooltip();
}

/** 
 * Allgemeine Schnittstelle fuer die Behandung von Meldungen.
 * erroDiv ist der Bereich, in dem die Meldungen dargestellt werden sollen.
 */ 
function _onMessages(formValidationResult, errorDiv, isLayer) {
	// handle errors
	if ( formValidationResult.state == RESPONSE_STATE_EXCEPTION ) {
//    if(isLayer) {
//      layer.close();
//      layer.create(formValidationResult.errorLinkLayer, 500, 350, 'error');
//    } else {
		window.location = formValidationResult.errorLink;
//    }
	} else if (formValidationResult.errors.length > 0) {
		_displayMessages(formValidationResult, errorDiv);
		_markErrorFields(formValidationResult);
		try {
			reloadCaptcha(); // from bkbo.js
		} catch ( Exception ) {}

	} else if (formValidationResult.messages.length > 0) {
		_displayMessages(formValidationResult, errorDiv);
		_markErrorFields(formValidationResult);
  }
}

/**
 * Erzeugung / Darstellung des Bereichs mit allen Fehlermeldungen
 * 
 * Wenn nur eine Fehlermeldung enthalten ist wird diese direkt im "errorDiv" angezeigt.
 * Bei mehreren Fehlermeldungen wird die generelle Fehlermeldung angezeigt. Die Detail-Meldungen 
 * werden zudem als Tooltip an das errorDiv gehaengt
 */
function _displayMessages(formValidationResult, errorDiv) {
    var message = formValidationResult.errorHeader;
    for (i=0;i<formValidationResult.errors.length;i++) {
      message += formValidationResult.errorPrefix + formValidationResult.errors[i] + formValidationResult.errorSuffix;
    }
    message += formValidationResult.errorFooter;

    for (i=0;i<formValidationResult.messages.length;i++) {
      message += formValidationResult.errorPrefix + formValidationResult.messages[i] + formValidationResult.errorSuffix;
    }

    var stackMessages = ERROR_MSG_MAX_DISPLAY != -1 && formValidationResult.errors.length > ERROR_MSG_MAX_DISPLAY;
    if (stackMessages) {
    	$j(errorDiv).append(formValidationResult.errorHeader + formValidationResult.errorPrefix + errorTxts.detailMessage + formValidationResult.errorSuffix + formValidationResult.errorFooter);
        $j(errorDiv).attr("title", message);
        $j(errorDiv).tooltip();
    } else {
        $j(errorDiv).append(message);      
    }
}

/**
 * Markiert alle fehlerhaften Felder
 */
function _markErrorFields(formValidationResult) {
   	for (i=0;i<formValidationResult.errorsProperties.length;i++) {
   		_markErrorField(formValidationResult.errorsProperties[i], formValidationResult.errors[i]);
	}
}

/**
 * Markiert fehlerhafte Felder und setzt den Fehlertext als Tooltip
 */
function _markErrorField(targetElement, message) {
   if(targetElement != null && targetElement.length > 0) {
	   var input = $j("input[name$='"+targetElement+"'], select[name$='"+targetElement+"']");
	   for (var i = 0; i < input.length; i++) {
	     var id = $j(input[i]).attr("id");
	     $j('#'+id+'Label').attr("class", ERROR_CLASS);
	     if(message.length > 0) {
		     $j('#'+id+'Label').attr("title", message);
		     $j('#'+id+'Label').tooltip();
	     }     
	   }
   }
}


/**
 * Sendet ein Formular asynchron an den server und wertet die antwort aus
 */
function _sendFormAsynch(formId, remoteFunction, mycallback, errorCallback, isLayer, successFunction) {
	 _myCallBack = mycallback; 	
	 _errorCallback = errorCallback;
	 _isLayer = isLayer; 	
	
	$j('#' + formId).ajaxSubmit( {
		dataType:  'json', 
		beforeSubmit: function(formData, jqForm, options) {
			formData.push({name:"ajx", value:"1"});
			formData.push({name:remoteFunction, value:"1"});
			_removeEmptyFileFromData(formData, jqForm);
			return true;
		},	
		success: successFunction ? successFunction : _defaultSuccessFunction
	});
}

/**
 * Entfernt alle Attribute vom Typ input:file aus der zu uebermittelnden Form, deren
 * Dateiname eine Laenge von 0 Zeichen hat.
 *  
 * @param formData Struts-Form
 * @param jqForm HTML-Form
 * @return Die um die input:file modifizierte Form 
 */
function _removeEmptyFileFromData(formData, jqForm) {
	var files = $j('input:file', jqForm);
	for ( var i = 0; i<files.length; i++) {
		var property = files[i].name;
		var value = files[i].value;
		if ( value.length == 0 ) {
			_removeFromData(formData, property);
		}
	}			
}

/**
 * Entfernt das Element mit dem uebergebenen Namen aus der Struts-Form
 * @param formData Struts-Form
 * @param elementName Name des zu entfernden Elements
 * @return Die um das geloeschte Element modifizierte Form
 */
function _removeFromData(formData, elementName) {
	for (var i = 0; i < formData.length; i++) {
		var name = formData[i] ['name'];
		if (name==elementName) {
			for ( var x = i; x<formData.length; x++ ) {
				formData[x] = formData[x + 1];
			}
			formData.pop();
			return;
		}
	}	
}


// LATER SRA - kann man das als parameter des callback mitgeben? 
var _myCallBack; 
var _isLayer;
var _errorCallback
/**
 * Default Implementierung fuer den Success Fall eines asynchronen form submit
 * - loescht alte Fehlermeldungen
 * - zeigt im Fehlerfall neue Fehlermeldungen an
 * - ruft den uebergebenen callback im Erfolgsfall auf 	
 */
function _defaultSuccessFunction(responseObject, statusText, mycallback) {
	if (_isLayer) {
		clearOldLayerMessages();
	} else {
		clearOldMessages();
	}
	
	if(STATE_SESSION_TIMEOUT == responseObject.formValidationResult.state) {
		window.location = responseObject.nextLink;
	} else if (RESPONSE_STATE_OK == responseObject.formValidationResult.state) {
		if(_myCallBack) {
			var theResponse = responseObject.resultObject ? responseObject.resultObject : responseObject.nextLink;  
			_myCallBack(theResponse);
		}
 	} else {
		if (_isLayer) {
			handleLayerMessages(responseObject.formValidationResult);
		} else {
			// layer.close();
			handleMessages(responseObject.formValidationResult);
		}
		if(_errorCallback) {
			_errorCallback(responseObject.resultObject, responseObject.formValidationResult);
		}
	}
}

