function app(){
	this.prefix ="zC";
	this.debug = false;
	this.lockScreenDelay = null;
	var busy = false;
	var queue = [];

	this.onDomReady = function(){
		this.displayLogin(false);
		var passwordHint = $('lbPasswordHint');
		if(passwordHint){
			passwordHint.setStyle('display','none');
		}
		var passwordBox = $('loginPassword');
		if(passwordBox){
			passwordBox.addEvent('keypress',function(ev){
			  	// A-Z + !shift = CAPS or a-z  +shift = CAPS
			 	if (((ev.code >= 65 && ev.code <= 90) && !ev.shift) || ((ev.code >= 97 && ev.code <= 122) && ev.shift)){
			 		passwordHint.setStyle('display','block');
			 	}else{
			 		passwordHint.setStyle('display','none');
			 	}
			});
		}
		//if registration => instanciate formvaldator..
		if($('registrationForm')){
			new FormCheck('registrationForm');
		}
		if($('micrositeForm')){
			new FormCheck('micrositeForm');
		}
		if($('upgradeForm')){
			new FormCheck('upgradeForm');
		}
		if($('accountingchangeForm')){
			new FormCheck('accountingchangeForm');
		}
		if($('passwordchangeForm')){
			new FormCheck('passwordchangeForm');
		}
		if($('recommandForm')){
			new FormCheck('recommandForm');
		}
		if($('accountingForm')){
			new FormCheck('accountingForm');
		}
		if($('feedbackForm')){
			new FormCheck('feedbackForm');
		}
		//helpfunction init..
		this.initHelpFunction();
		//map init..
		if($('initialMaplong') && $('initialMaplat')){
			var long = $('initialMaplong').firstChild.data;
			var lat = $('initialMaplat').firstChild.data;
			this.registerGoogleMaps(long,lat);
		}

	}.bind(this);

	this.displayLogin = function(flag){
		var loginBox = $('loginBoxTop');
		if(loginBox){
			if(flag){
				loginBox.setStyle('display','block');
				$('loginLink').setStyle('display','none');
			}else{
				$('loginLink').setStyle('display','block');
				loginBox.setStyle('display','none');
			}
		}
	}

	this.registerGoogleMaps=function(long,lat){
			if(document.getElementById("mapGoogle")){
			   if (GBrowserIsCompatible()) {
					map = new GMap2(document.getElementById("mapGoogle"));
					map.addControl(new GSmallMapControl());
 					map.addControl(new GMapTypeControl());
					var point = new GLatLng(long,lat);
					map.setCenter(point, 13);

					var baseIcon = new GIcon(G_DEFAULT_ICON);
					baseIcon.shadow = "http://www.google.com/mapfiles/shadow50.png";
					baseIcon.iconSize = new GSize(20, 34);
					baseIcon.shadowSize = new GSize(37, 34);
					baseIcon.iconAnchor = new GPoint(9, 34);
					baseIcon.infoWindowAnchor = new GPoint(9, 2);

					var letter = String.fromCharCode("X".charCodeAt(0));
					var letteredIcon = new GIcon(baseIcon);
					letteredIcon.image = "http://www.google.com/mapfiles/marker" + letter + ".png";
					// Set up our GMarkerOptions object
					markerOptions = { icon:letteredIcon };
					var marker = new GMarker(point, markerOptions);

					/*GEvent.addListener(marker, "click", function() {
					   marker.openInfoWindowHtml(content);
					});*/
					map.addOverlay(marker);
				}
			}
	}.bind(this);

	 this.registerAutoSuggest = function(obj,params){
         obj = $(obj);
         var dim = obj.getCoordinates();
         obj.onfocus = null; // clear registration handler
  		 var prevValue = obj.value;
         var timer;
         var lastNotFoundPrefix = null;

         if(!drop) var drop = new Element("div",{"styles":{"display":"none","position":"absolute"},"class":"suggestDropDown"}).injectInside($(document.body));
         drop.setStyles({"left":dim.left,"top":dim.top+dim.height});

         obj.addEvents({
                        "focus": function(ev) { drop.empty().setStyle('width',obj.getCoordinates().width); },
                        "blur": function(ev) { drop.setStyle('display','none'); }, // hide
                        "keyup": function(ev) {
                                ev = new Event(ev);
                                if(ev.key == 'up' || ev.key == 'down') { // navigate through dropdown list
                                 	    var cur = drop.getChildren(".autoSuggested").removeClass("autoSuggested")[0];
                                        var next;
                                        if(cur){
                                                next = ev.key == 'up' ? cur.getPrevious() : cur.getNext();
                                        }else{
                                                next = ev.key == 'up' ? drop.getLast() : drop.getFirst();
										}

                                        if(next) {      // highlight new element and fetch suggested text
                                                next.addClass("autoSuggested");
                                                // get highlighted-text and append rest(if there is one..)
                                          		if($chk(next.lastChild.data)){
                                          			obj.value = next.getChildren(".highlight")[0].firstChild.data+next.lastChild.data;
                                          		}else{
                                          			obj.value = next.getChildren(".highlight")[0].firstChild.data;
                                          		}
                                        }
                                        ev.stop();
                                } else if(ev.key == "enter") {
                                        obj.blur();
                                        return false;
                                } else {
                                	 // check if content changed, refresh dropdown list
                                     if(obj.value == prevValue) return true;
                                     // content has changed...
                                     prevValue = obj.value;
                                     if(obj.value.length > 0 && (!lastNotFoundPrefix || obj.value.indexOf(lastNotFoundPrefix) != 0)){
                                     	$extend(params,{xValue:obj.value});
                                     	this.xGetAutoSuggest(params,
                                                         function(result){
                                                                 if(!result.payload){
                                                                         lastNotFoundPrefix = obj.value;
                                                                         drop.empty().setStyle("display","none");
                                                                 }else{
                                                                         drop.empty().set('html',result.payload).setStyle("display","block").getChildren().addEvents({
                                                                         "mouseenter":function(){
	                                                                                 drop.getChildren().removeClass("autoSuggested");
	                                                                                 $(this).addClass("autoSuggested");
                                                                         			},
                                                                         "mousedown" : function(){
                                                                         		// get highlighted-text and append rest(if there is one..)
                                                                         		if($chk(this.lastChild.data)){
                                                                         			obj.value = this.getChildren(".highlight")[0].firstChild.data+this.lastChild.data;
                                                                         		}else{
                                                                         			obj.value = this.getChildren(".highlight")[0].firstChild.data;
                                                                         		}
                                                                         }
                                                                         });
                                                                 }
                                                         }
                                                 );
                                     }else{
                                      // emtpy string ..clear and hide dropDown
                                       drop.empty();
                                       drop.setStyle("display","none");
                                     }
                                }
                        }.bind(this)
                }).fireEvent("focus",null);
	}

   	this.xGetAutoSuggest = function(params,callback){
   		$extend(params,{xType:'xGetAutoSuggest'});
		queue.push([params,callback]);
		xDispatch();
   	}

    this.xCall = function(params,callback){
			var loc = document.location;
			loc = loc.protocol+"//"+loc.host+"/";

			/*this.ajaxInProgress(true);*/
			this.lockScreen(true);

			var arguments = {
						url: loc,
                        onFailure : function() {
                                /*do nothing*/
                        }.bind(this),
                        onComplete : function(result) {
                        		this.lockScreen(false);
                        		var special = false;
                        		if(params.aType == 4) special='inject';
                        		if(params.zType =='banner' || params.zType =='logo' || params.zType =='file' || params.zType=='product_image') special=params.zType;
                                /*this.ajaxInProgress(false);*/

                                xHandleResult(result,callback,special);
                        }.bind(this)
                };

            $extend(params,{xCall:1});
            var jsonRequest = new Request.JSON(arguments).post(params);
    }

    var xHandleResult = function(result,callback,special){
    	// delete previous erros...
    	this.xCleanupErrors();
    	if(special){
    		callback(result,special);
    	}else{
    		callback(result);
    		if($('contactForm')){
      			new FormCheck('contactForm');
    		}
    	}

    	$$('.RTEviewShort').each(function(element){
    		var parent = element.parentNode;
    		parent = $(parent);
    		var buttons = parent.getChildren('button');
    		if(buttons.length == 2){
    			element.setStyles({
					height:"50px"
				});
    		}else{
    			element.setStyles({
    				height:"100%"
    			});
    		}
    	});

    	$$('.RTEviewLarge').each(function(element){
    		var parent = element.parentNode;
    		parent = $(parent);
    		var buttons = parent.getChildren('button');
    		if(buttons.length == 2){
    			element.setStyles({
					height:"450px"
				});
    		}else{
    			element.setStyles({
    				height:"100%"
    			});
    		}
    	});



    		//lw_dm - lw_mp workaround for reinitialisation of more than one tiny...
    		var tmpContent = result.payload;
    		var tmpContainer = new Element('div');
    		tmpContainer.set('html',tmpContent);
    		//var tmpContent = tmpContainer.getChildren();
    		var textarea = $(tmpContainer).getElement('textarea[class^=RTE]');
    		// if error remove control to reinitialize the tinymce afterwards

    		//alert(textarea);
    		if($defined(textarea)){
    			var resultId = textarea.getProperty('id');
    			tinyMCE.init({
    				//mode : "specific_textareas",
        			mode : "none",
        			theme : "advanced",
    				//editor_selector: "RTEview",
    				//editor_selector: /(RTEview|RTEviewLarge|RTEviewShort)/,
    				plugins : "inlinepopups",
    				language : "de",
    				theme_advanced_toolbar_location : "top",
    				theme_advanced_toolbar_align : "left",
    				theme_advanced_buttons1 : "formatselect,|,bold,italic,|,numlist,bullist,|,undo,redo",
    				theme_advanced_buttons2 : "",
    				theme_advanced_buttons3 : "",
    				theme_advanced_blockformats : "p,h2,h3",
    				valid_elements : "p,h2,h3,b,strong,i,ul,ol,li,br" // please also take care of formvalidator filter $allowedTags in CoreFormValidator.inc.php line 235
    			});
	    		//lw_pk übrigens ein leerstring reicht
	    		//alert('resultid='+resultId);
	    		tinyMCE.execCommand('mceAddControl',false,""+resultId);
    		}


		this.initHelpFunction();
    }.bind(this);

	this.initHelpFunction =function(){
		$$('.helpContent').each(function(element){
					element.setStyles({
						display:'none'
					});
		});

		$$('.helpText').addEvents({
		    'mouseenter': function(event){
		        var parent = $(this.parentNode);

				var helpcontent = parent.getChildren('.helpContent')[0];
				var helptext = parent.getChildren('.helpText')[0];
		        $(helpcontent).setStyles({
						display:'block',
						position:'absolute',
						top:$(helptext).getCoordinates().top+20,
						left:$(helptext).getCoordinates().left
					});
		    },
		    'mouseleave': function(){
		    	var parent = this.parentNode;
				var child = parent.getChildren('.helpContent')[0];
		        child.setStyles({
						display:'none'
				});
		    }
		});
	}

	this.lockScreen = function(state){
		if(state){
			var size = window.getSize();
			var x = size.x;
			var y = size.y;

			$('ajaxInProgressBackground').setStyles({
				display:'block',
				'background-Color':'white',
				opacity: 0.1,
				position:'absolute',
				top:0,
				left:0,
				width:x,
				height:y,
				'z-index':3
			});
			 // lock screen and after 700 ms blending effekt...
			 $clear(this.lockScreenDelay);
             this.lockScreenDelay = function() {
            		this.ajaxInProgress(true);
             }.bind(this).delay(700);
		}else{
			if(this.lockScreenDelay){
				//clear function call
				$clear(this.lockScreenDelay);
			}
			this.ajaxInProgress(false);
		}
	}.bind(this);

	this.ajaxInProgress=function(state){
		if(state){
			var size = window.getSize();
			var x = size.x;
			var y = size.y

			$('ajaxInProgressBackground').setStyles({
				display:'block',
				'background-Color':'black',
				opacity: 0.4,
				position:'absolute',
				top:0,
				left:0,
				width:x,
				height:y,
				'z-index':3
			});

			$('ajaxInProgress').setStyles({
				display:'block',
				position:'absolute',
				top:(y/2)-100,
				left:(x/2)-33,
				'z-index':4
			});
		}else{
			$('ajaxInProgress').setStyle('display','none');
			$('ajaxInProgressBackground').setStyle('display','none');
		}
	}

	this.xCheckAddress = function(params,domObj){

		var callback = function(result){
			var child =domObj.getChildren('.adressCheck')[0];
			if(result.error){
				child.set('html',result.error);
			}else{
				child.set('html',result.payload);
			}
		}.bind(this);

		$extend(params,{xType:'xCheckAddress'});
		queue.push([params,callback]);
		xDispatch();
	}

	this.xEditInPlace = function(params,domObj){

		domObj = $(domObj);

		// check if editable object is an textarea (RTE special case)
		var textareaId = this.getTinyMCETextarea(domObj,'child');
		if($defined(textareaId)){
			/*
			 * 	close editor ..save/cancel => must remove instance form global object
			 *  to be able to reinitialize the new instance of tinymce in callback function
			*/
			tinyMCE.execCommand('mceRemoveControl',false,''+textareaId);
		}
		// end special case

		var callback = function(result,special){
			if(result.error){
				// another special case for tinymce see also handleresult...
				var textareaId = this.getTinyMCETextarea(domObj,'child');
				if($defined(textareaId)){
					tinyMCE.execCommand('mceAddControl',false,''+textareaId);
				}
				this.xCleanupErrors();
				var errorDiv = new Element('div', {
	   				'class': 'zCError',
	   				'html': result.error
				});
				// domObj.grab(errorDiv);
				if (domObj.getChildren("span")[1])
					errorDiv.injectAfter(domObj.getChildren("span")[1]);
				else
					domObj.grab(errorDiv);
			}else{
				switch (special) {
				    case "inject":
				    	var resultLi = new Element('li',{
						'html':result.payload
						});
				    	if(domObj.getChildren("ul").length == 0){
				    		//check if there is an ul. if not add a new one
				    		var resultUl = new Element('ul');
				    		resultLi.inject(resultUl);
				    		domObj.grab(resultUl);
				    	} else {
				    		domObj.getChildren("ul")[0].grab(resultLi,'top');
						}
				    break;
				    case "product_image":
				    case "file":
				    case "banner":
				    case "logo":
				    	domObj.set('html',result.payload);
						var frame = $('FileUpload');
						frame.src = "/";
						frame.removeEvents("load");
						frame.addEvent("load",function() {
						this.lockScreen(false);
						var frameContent = frame.contentWindow;
							//look if iframe is not emtpy
							if($defined(frameContent.document.body.firstChild)){
								//got result ? handle it
								var result = window.frames['FileUpload'].document.getElementById('result'+params.zType+params.zObjectId);
								var error = window.frames['FileUpload'].document.getElementById('error');
	                     		if(result){
	                     			result = result.innerHTML;
									domObj.set('html',result);
								}
								if(error){
									var errorText = error.firstChild.data;
									this.xCleanupErrors();
									var errorDiv = new Element('div', {
	   									'class': 'zCError',
	   									'html': errorText
									});
									domObj.grab(errorDiv);
								}
	                     	}
	                     }.bind(this));
					break;
				    default:
				     	// the normal wy to replace the domobject by payload
				     	//alert(result.payload);
						domObj.set('html',result.payload);
						//domObj.innerHTML = result.payload;
				  }
			}
		}.bind(this);

		$extend(params,{xType:'xEditInPlace'});
		queue.push([params,callback]);
		xDispatch();
	}

	this.xEditProfile = function(params,domObj){
			if(!(domObj instanceof Array) && ((domObj !== null) && (typeof(domObj) == 'object'))){
					var domObject = domObj;
			}else{
					var domObject = $(domObj);
			}
			domObj = $(domObj);

			if(params.zType == "tag"){
				var callback = function(result){
						if(result.error){
							this.xCleanupErrors();
							this.xCleanupInfos();
							var errorDiv = new Element('div', {
		   						'class': 'zCError',
		   						'html': result.error
								});
							if (params.aType == 2) {
								domObject.grab(errorDiv);
							}else{
								errorDiv.injectAfter(domObject.getChildren("div")[0]);
							}
						}else{
							this.xCleanupErrors();

							if (params.aType != 2) {
								$("NewTag"+params.zSubType).value ="";
							}
							if (params.aType == 2) {
								/*
								var resultDiv = new Element('div');
								resultDiv.set('html',result.payload);
								resultDiv.set('class','saveInfo');
								resultDiv.inject(domObject);
								*/
								//redirect to new tag_id details
								window.location.href = result.redirect;
							}
							if(params.aType == 3){
								domObject.dispose();
							}
							if(params.aType == 4){
								if (result.redirect) {
									window.location.href = result.redirect;
								}else{
									var resultDiv = new Element('div');
									resultDiv.set('html',result.payload);
									//resultDiv.inject(domObject);
									resultDiv.inject(domObject.getChildren("div")[0],'after');
								}
							}
						}
				}.bind(this);
			}

			$extend(params,{xType:'xEditProfile'});
			queue.push([params,callback]);
			xDispatch();
	}.bind(this);

	this.xDeleteItem = function(params,domObj,confirmation){
		if(confirmation !== null) {
			if (!confirm(confirmation))
				return false;
		}
		if(!(domObj instanceof Array) && ((domObj !== null) && (typeof(domObj) == 'object'))){
				var domObject = domObj;
		}else{
				var domObject = $(domObj);
		}
		var callback = function(result){
			if(result.error){
				this.xCleanupErrors();
				var errorDiv = new Element('div', {
   				'class': 'zCError',
   				'html': result.error
				});
				$(domObj).grab(errorDiv);
			}else{
				if(domObj.parentNode.getChildren("li").length == 1){
					$(domObject.parentNode).dispose();
				} else {
					$(domObject).dispose();
				}
			}
		}.bind(this);

		$extend(params,{xType:'xDeleteItem'});
		queue.push([params,callback]);
		xDispatch();
	}.bind(this);

	this.xUpdateContainer = function(params,domObj) {
	    var callback = function(result){
			if(!(domObj instanceof Array) && ((domObj !== null) && (typeof(domObj) == 'object'))){
					var domObject = domObj;
			}else{
					var domObject = $(domObj);
			}

			if(result.error){
				this.xCleanupErrors();
				var errorDiv = new Element('div', {
   				'class': 'zCError',
   				'html': result.error
				});
				domObject.grab(errorDiv);
			}else{
				domObject.set('html',result.payload);
				//domObject.innerHTML = result.payload;
			}
		}.bind(this);

		$extend(params,{xType:'xUpdateContainer'});
		queue.push([params,callback]);
		xDispatch();
	}.bind(this);

	this.xCleanupErrors = function(){
			$$('.zCError').each(function(el){
					el.destroy();
			});
	}.bind(this);

	this.xCleanupInfos = function(){
			$$('.saveInfo').each(function(el){
					el.destroy();
			});
	}.bind(this);

	var xDispatch = function(){
		if(busy || queue.length == 0)
			return;
		busy = true;
		var currentRequest = queue.pop();
		this.xCall(currentRequest[0],currentRequest[1]);
		busy = false;
		xDispatch();
	}.bind(this);


	this.xMicroforms=function(params,domObj){
		 var callback = function(result){
			if(!(domObj instanceof Array) && ((domObj !== null) && (typeof(domObj) == 'object'))){
					var domObject = domObj;
			}else{
					var domObject = $(domObj);
			}
			if(result.error){
				this.xCleanupErrors();
				var errorDiv = new Element('div', {
   				'class': 'zCError',
   				'html': result.error
				});
				domObject.grab(errorDiv);
			}else{
				domObject.set('html',result.payload);
				//domObject.innerHTML = result.payload;
			}
		}.bind(this);

		$extend(params,{zType:'xMicroforms'});
		queue.push([params,callback]);
		xDispatch();
	}.bind(this);

	this.checkUsername = function(params,obj){
		var callback = function(result){
			if(result.payload){
				var errorDiv = new Element('div', {
   				'class': 'zCError',
   				'html': result.payload
				});
				errorDiv.injectAfter(obj);
			}
		}.bind(this);

		$extend(params,{xType:'xCheckUser'});
		queue.push([params,callback]);
		xDispatch();
	}.bind(this);

	this.checkProfile = function(params,obj){
		var callback = function(result){
			if(result.payload){
				var errorDiv = new Element('span', {
   				'class': 'zCError',
   				'html': result.payload
				});
				errorDiv.injectAfter(obj);
			}
		}.bind(this);

		$extend(params,{xType:'xCheckProfile'});
		queue.push([params,callback]);
		xDispatch();
	}.bind(this);

	this.setFormular = function(params,domObj){
		domObj = $(domObj);
		var callback = function(result){
			if(result.error){
				var errorDiv = new Element('div', {
   				'class': 'zCError',
   				'html': result.error
				});
				errorDiv.injectAfter(domObj);
			}else{
				var test  = new Element ('div',{
					'html' : result.payload
				});
				domObj.empty();
				domObj.grab(test);
			}
		}.bind(this);
		$extend(params,{xType:'xSetFormular'});
		queue.push([params,callback]);
		xDispatch();
	}.bind(this);

	window.addEvent('domready', function() {
                this.onDomReady();
	}.bind(this));

	this.xEditConfig = function(field, section, key, value){
		// sets a config parameter per AJAX
		// form = $(form);
		var params = {};
		$extend(params,{xType:'xEditConfig'});
		$extend(params,{section:section});
		$extend(params,{key:key});
		$extend(params,{value:value});

		var callback = function(result){
			//alert(result.payload);
			//field.value = result.payload;
		}

		queue.push([params,callback]);
		xDispatch();
	}

	this.getTinyMCETextarea = function(domObj,mode) {

		domObj = $(domObj);

		var textarea = null;
		var textareaId = null;
		switch(mode){
			case "sibling":
				textarea = domObj.getPrevious('textarea');
			break;
			case "child":
				textarea = domObj.getElement('textarea');
			break;
			default:
				return false;
		}
		if($defined(textarea)) textareaId = textarea.getProperty('id');
		if(!$defined(textareaId))return false;
		//returns the id of the previous textarea
		//needed for product page as we have 2 tinymces and TinyMCE.getCurrent... can maybe use the wrong one
		return textareaId;
	}

	this.getSelectedRadioValue = function(domObj,mode,special) {
		domObj = $(domObj);
		var radio = null;
		switch(mode) {
			case "sibling":
				radio = domObj.getPrevious('input[checked]');
			break;
			case "childbefore":
				tmpObj = null;
				if(special == '') return false;
				tmpObj = domObj.getPrevious('*[class='+special+']');
				if($defined(tmpObj)) radio = tmpObj.getElement('input[checked]');
			break;
			case "child":
				radio = domObj.getElement('input[checked]');
			break;
			default:
				return false;
		}

		if($defined(radio)) {
			var radioValue = null;
			radioValue = radio.getProperty('value');
			if($defined(radioValue)) return radioValue;
		}
		return false;
	}
}
var zombig = new app();
