
function var_dump(element, limit, depth)
{
   depth =   depth?depth:0;
   limit = limit?limit:1;

   returnString = '<ol>';

   for(property in element)
   {
      //Property domConfig isn't accessable
      if (property != 'domConfig')
      {
         returnString += '<li><strong>'+ property + '</strong> <small>(' + (typeof element[property]) +')</small>';

         if (typeof element[property] == 'number' || typeof element[property] == 'boolean')
            returnString += ' : <em>' + element[property] + '</em>';
         if (typeof element[property] == 'string' && element[property])
            returnString += ': <div style="background:#C9C9C9;border:1px solid black; overflow:auto;"><code>' +
                           element[property].replace(/</g, '&amp;lt;').replace(/>/g, '&amp;gt;') + '</code></div>';

         if ((typeof element[property] == 'object') && (depth < limit))
            returnString += var_dump(element[property], limit, (depth + 1));

         returnString += '</li>';
      }
   }
   returnString += '</ol>';

   if(depth == 0)
   {
      winpop = window.open("", "","width=800,height=600,scrollbars,resizable");
      winpop.document.write('<pre>'+returnString+ '</pre>');
      winpop.document.close();
   }   

   return returnString;
}


var FormCheck = new Class({
	
	Implements: [Options, Events],
        
        options : {
		
		tipsClass: 'fc-tbx',				//tips error class
		errorClass: 'fc-error',				//div error class
		fieldErrorClass: 'fc-field-error',	//error class for elements
		
		trimValue : false,					//trim (remove whitespaces before and after) the value
		validateDisabled : false,			//skip validation on disabled input if set to false.
		
		submitByAjax : true,				//false : standard submit way, true : submit by ajax
		ajaxResponseDiv : false,			//element to inject ajax response into (can also use onAjaxSuccess) [cronix] 
		ajaxEvalScripts : false,			//use evalScripts in the Request response [cronix] 
		onAjaxRequest : $empty,				//Function to fire when the Request event starts 
		onAjaxSuccess : $empty,				//Function to fire when the Request receives .  Args: response [the request response] - see Mootools docs for Request.onSuccess 
		onAjaxFailure : $empty,				//Function to fire if the Request fails 

		display : {
			showErrors : 0,
			titlesInsteadNames : 0,
			//errorsLocation : 1,
			indicateErrors : 2,
			indicateErrorsInit : 0,
			keepFocusOnError : 0,
			checkValueIfEmpty : 1,
			addClassErrorToField : 0,
			fixPngForIe : 1,
			replaceTipsEffect : 1,
			flashTips : true,
			closeTipsButton : 1,
			tipsPosition : "right",
			tipsOffsetX : -45,
			tipsOffsetY : 0,
			//listErrorsAtTop : false,
			scrollToFirst : true,
			fadeDuration : 1
		}
	},
        
        initialize : function(form, options) {
                
                if (this.form = $(form)) {
                                //this.setOptions(options);
                                this.alreadyIndicated = false;
                                
                                //internalization
                                
                               /* this.form.addEvents({
                                        "keydown": this.onKeyDown.bind(this)
                                });*/
                                
                                                       
                                
                                this.form.addEvents({
                                        "submit": this.onSubmit.bind(this)
                                });
                                
                                //this.form.addEvents({
                                //	"keydown": this.onKeyDown.bind(this)
                                //});
                                }
                
                var url = this.form.getProperty('action')+"?_action=get_required";

                new Request.JSON({
			url: url,
			//evalScripts: this.options.ajaxEvalScripts,
			onFailure: function(instance){
				//this.fireEvent('ajaxFailure', instance);
			},
			onSuccess: function(obj){
                              
                              //alert(obj.nachname.type);
                              
                                  for (var i in obj[0])   
                                  {
                                    if(document.getElementsByName(i)[0]){
                                        var el = new Element(document.getElementsByName(i)[0]);
                                       
                                        el.addClass("required"); 
                                        if(obj[1].form_check_events==1){
                                                if(obj[0][i].type == "text" || obj[0][i].type == "captcha"){
                                                        el.addEvents({
                                                        "keydown": this.onKeyDown.bind(this),
                                                        "keyup" : this.onKeyDown.bind(this),
                                                        "click": this.onKeyDown.bind(this)
                                                        });    
                                                } else if(obj[0][i].type == "select"){ 
                                                        el.addEvents({
                                                        "change": this.onKeyDown.bind(this),
                                                        "click": this.onKeyDown.bind(this)
                                                        });    
                                                } else {
                                                        el.addEvents({
                                                        "keydown": this.onKeyDown.bind(this),
                                                        "keyup" : this.onKeyDown.bind(this),
                                                        "click": this.onKeyDown.bind(this)
                                                        });    
                                                }
                                        
                                        }
                                    }
                                       // alert(i);
                                }
                              
                            
                              
                              
                        }.bind(this)
		}).send();
                
                        
		
	},
        
        manageError : function(el, method) {

		if(this.options.display.errorsLocation == 4 && method == 'submit'){
                    this.listErrorsAtTop(el, method);
		}
                if ((this.options.display.indicateErrors == 2 ||this.alreadyIndicated == false || el.name == this.alreadyIndicated.name) && this.options.display.errorsLocation)
		{
			
		    if(!this.firstError) this.firstError = el;
				
		    this.alreadyIndicated = el;
				
		    if (this.options.display.keepFocusOnError && el.name == this.firstError.name) (function(){el.focus()}).delay(20);
		    this.addError(el);
		    return false;
		}
		return true;
	},
	
	/*
	Function: addError
		Private method
		
		Add error message
	*/
	addError : function(obj) {
		if(!obj.element && this.options.display.indicateErrors != 0) {
			if (this.options.display.errorsLocation == 1) {
				var pos = (this.options.display.tipsPosition == 'left') ? obj.getCoordinates().left : obj.getCoordinates().right;
				var options = {
					'opacity' : 0,
					'position' : 'absolute',
					'float' : 'left',
					'left' : pos + this.options.display.tipsOffsetX
				}
				obj.element = new Element('div', {'class' : this.options.tipsClass, 'styles' : options}).injectInside(document.body);
				this.addPositionEvent(obj);
			} else if (this.options.display.errorsLocation == 2){
				obj.element = new Element('div', {'class' : this.options.errorClass, 'styles' : {'opacity' : 0}}).injectBefore(obj);
			} else if (this.options.display.errorsLocation == 3){
				obj.element = new Element('div', {'class' : this.options.errorClass, 'styles' : {'opacity' : 0}});
				if ($type(obj.group) == 'object' || $type(obj.group) == 'collection')
					obj.element.injectAfter(obj.group[obj.group.length-1]);
				else
					obj.element.injectAfter(obj);
			}
		}					
		if (obj.element && obj.element != true) {
			obj.element.empty();
			if (this.options.display.errorsLocation == 1) {
				var errors = [];
				//obj.errors.each(function(error) {
					errors.push(new Element('p').set('html', obj.error));
				//});
				//var tips = this.makeTips(errors).injectInside(obj.element);
				var tips = this.makeTips(errors).injectInside(obj.element);
                                
				if(this.options.display.closeTipsButton) {
					tips.getElements('a.close').addEvent('mouseup', function(){
						this.removeError(obj);
					}.bind(this));
				}
				obj.element.setStyle('top', obj.getCoordinates().top - tips.getCoordinates().height + this.options.display.tipsOffsetY);
			} else {
				//obj.errors.each(function(error) {
					//new Element('p').set('html',error).injectInside(obj.element);
							    
					new Element('p').set('html',obj.error).injectInside(obj.element);
				//});
			}
			
			if (!this.options.display.fadeDuration || Browser.Engine.trident && Browser.Engine.version == 5 && this.options.display.errorsLocation < 2) {
				obj.element.setStyle('opacity', 1);
			} else {
				obj.fx = new Fx.Tween(obj.element, {
					'duration' : this.options.display.fadeDuration,
					'ignore' : true,
					'onStart' : function(){
						this.fxRunning = true;
					}.bind(this),
					'onComplete' : function() {
						this.fxRunning = false;
						if (obj.element && obj.element.getStyle('opacity').toInt() == 0) {
							obj.element.destroy();
							obj.element = false;
						}
					}.bind(this)
				})
				if(obj.element.getStyle('opacity').toInt() != 1) obj.fx.start('opacity', 1);
			}
		}
		if (this.options.display.addClassErrorToField && this.isChildType(obj) == false){
			obj.addClass(this.options.fieldErrorClass);
			obj.element = obj.element || true;
		}

                obj.removeClass("correct");
                obj.removeClass("required");
                obj.addClass("incorrect");
			
	},
	
	fixIeStuffs : function () {
		if (Browser.Engine.trident4) {
			//We fix png stuffs
			var rpng = new RegExp('url\\(([\.a-zA-Z0-9_/:-]+\.png)\\)');
			var search = new RegExp('(.+)formcheck\.css');
			for (var i = 0; i < document.styleSheets.length; i++){
				if (document.styleSheets[i].href.match(/formcheck\.css$/)) {
					var root = document.styleSheets[i].href.replace(search, '$1');
					var count = document.styleSheets[i].rules.length;
					for (var j = 0; j < count; j++){
						var cssstyle = document.styleSheets[i].rules[j].style;
						var bgimage = root + cssstyle.backgroundImage.replace(rpng, '$1');
						if (bgimage && bgimage.match(/\.png/i)){
							var scale = (cssstyle.backgroundRepeat == 'no-repeat') ? 'crop' : 'scale';
							cssstyle.filter =  'progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, src=\'' + bgimage + '\', sizingMethod=\''+ scale +'\')';
							cssstyle.backgroundImage = "none";
						}
					}
				}
			}
		}
	},
	
	addPositionEvent : function(obj) {
		if(this.options.display.replaceTipsEffect) {
			obj.event = function(){
				new Fx.Morph(obj.element, {
					'duration' : this.options.display.fadeDuration
				}).start({ 
					'left':[obj.element.getStyle('left'), obj.getCoordinates().right + this.options.display.tipsOffsetX],
					'top':[obj.element.getStyle('top'), obj.getCoordinates().top - obj.element.getCoordinates().height + this.options.display.tipsOffsetY]
				});
			}.bind(this);
			
		} else {
			obj.event = function(){
				obj.element.setStyles({ 
					'left':obj.getCoordinates().right + this.options.display.tipsOffsetX,
					'top':obj.getCoordinates().top - obj.element.getCoordinates().height + this.options.display.tipsOffsetY
				});
			}.bind(this)
		}
		window.addEvent('resize', obj.event);
	},
	
	/*
	Function: focusOnError
		Private method
		
		Create set the focus to the first field with an error if needed
	*/
	focusOnError : function (obj) {
		if (this.options.display.scrollToFirst && !this.alreadyFocused && !this.isScrolling) {
			if (!this.options.display.indicateErrors || !this.options.display.errorsLocation) {
				var dest = obj.getCoordinates().top-30;
			} else if (this.alreadyIndicated.element) {
				switch (this.options.display.errorsLocation){
					case 1 : 
						var dest = obj.element.getCoordinates().top;
						break;
					case 2 :
						var dest = obj.element.getCoordinates().top-30;
						break;
					case 3 :
						var dest = obj.getCoordinates().top-30;
						break;
				}
				this.isScrolling = true;
			}
			if (window.getScroll.y != dest) {
				new Fx.Scroll(window, {
					onComplete : function() {
						this.isScrolling = false;
						obj.focus();
					}.bind(this)
				}).start(0,dest);
			} else {
				this.isScrolling = false;
				obj.focus();
			}
			this.alreadyFocused = true;
		}
	},
        
        listErrorsAtTop : function(obj) {
                
		if(!this.form.element) {
			 this.form.element = new Element('div', {'id' : 'errorlist', 'class' : this.options.errorClass}).injectTop(this.form);
		}
                //new Element('p').set('html',"<span>test: </span> Fehler").injectInside(this.form.element);
		if ($type(obj) == 'collection') {
			new Element('p').set('html',"<span>" + obj[0].name + " : </span>" + obj[0].errors[0]).injectInside(this.form.element);
		} else {
      
			//if ((obj.validation.contains('required') && obj.errors.length > 0) || (obj.errors.length > 0 && obj.value && obj.validation.contains('required') == false)) {

					new Element('p').set('html',obj.error).injectInside(this.form.element);

			//}
		}
	},
        
        removeError : function(obj) {
		this.alreadyIndicated = false;
		obj.errors = [];
		obj.isOK = true;
		window.removeEvent('resize', obj.event);
		if (this.options.display.errorsLocation >= 2 && obj.element) {
			new Fx.Tween(obj.element, {
				'duration': this.options.display.fadeDuration
			}).start('height', 0);
                        
		}
		if (!this.options.display.fadeDuration || Browser.Engine.trident && Browser.Engine.version == 5 && this.options.display.errorsLocation == 1 && obj.element) {
			this.fxRunning = true;
                        
			obj.element.destroy();
			obj.element = false;
                        
                        
                        
			(function(){this.fxRunning = false}.bind(this)).delay(100);
		} else if (obj.element && obj.element != true) {
			obj.fx.start('opacity', 0);
                        obj.removeClass("incorrect");
                       
                        //if(obj.className.indexOf("incorrect")!=-1){
                               obj.addClass("required"); 
                        //}
                        
                        //obj.addClass("correct");
		}
		
		if (this.options.display.addClassErrorToField && !this.isChildType(obj))
			obj.removeClass(this.options.fieldErrorClass);
      
                 if(this.currentElement && this.fields.indexOf(this.currentElement+",")==-1) {
                                 var cur_el = new Element(document.getElementsByName(this.currentElement)[0]);
                                 cur_el.removeClass("incorrect");
                                 cur_el.removeClass("required");
                                 cur_el.addClass("correct");
                                 
                        } else if(this.event == "submit" && this.fields.indexOf(obj.name+",")==-1){
                                obj.removeClass("incorrect");
                                obj.removeClass("required");
                                //obj.addClass("correct");
                        } else{
                                //obj.removeClass("incorrect");
                                //obj.removeClass("correct");
                                //obj.addClass("required");
                        }

	},
	
	/*
	Function: makeTips
		Private method
		
		Create tips boxes
	*/
	makeTips : function(txt) {
		var table = new Element('table');
			table.cellPadding ='0';
			table.cellSpacing ='0';
			table.border ='0';
			
			var tbody = new Element('tbody').injectInside(table);
				var tr1 = new Element('tr').injectInside(tbody);
					new Element('td', {'class' : 'tl'}).injectInside(tr1);
					new Element('td', {'class' : 't'}).injectInside(tr1);
					new Element('td', {'class' : 'tr'}).injectInside(tr1);
				var tr2 = new Element('tr').injectInside(tbody);
					new Element('td', {'class' : 'l'}).injectInside(tr2);
					var cont = new Element('td', {'class' : 'c'}).injectInside(tr2);
						var errors = new Element('div', {'class' : 'err'}).injectInside(cont);
						txt.each(function(error) {
							error.injectInside(errors);
						});
						if (this.options.display.closeTipsButton) new Element('a',{'class' : 'close'}).injectInside(cont);
					new Element('td', {'class' : 'r'}).injectInside(tr2);
				var tr3 = new Element('tr').injectInside(tbody);
					new Element('td', {'class' : 'bl'}).injectInside(tr3);
					new Element('td', {'class' : 'b'}).injectInside(tr3);
					new Element('td', {'class' : 'br'}).injectInside(tr3);			
		return table;
	},
        
        	/*
	Function: isChildType
		Private method
		
		Determine if the field is a group of radio or not.
	*/
	isChildType: function(el) {
		return ($defined(el.type) && el.type == 'radio') ? true : false;
	},
	
	reinitialize: function(obj) {
		
		/*$$('.fc-error').each(function(el) {
				
				  el.destroy();
				},this);*/
		
		for (var i in obj[1])   //obj[1] ... fields
                {
                  if(document.getElementsByName(i)[0]){
			var el = document.getElementsByName(i)[0];
			
			if(el.element){
				
				if(el.isValid){
					
				} else {
                                   //el.removeClass("incorrect");    
                                   //el.addClass("required");    
                                }
				
				//el.element = false;
				
				
			}
                        //el.addClass("required");
			el.isValid = true;
                  }	
		}
		if (this.form.element) this.form.element.destroy();
		this.form.element = false;
		this.alreadyFocused = false;
		this.firstError = false;
		this.elementToRemove = this.alreadyIndicated;
		this.alreadyIndicated = false;
		this.form.isValid = true;
	},
        
         	/*
	Function: getOptions
		Private method
		
		Reads Options
	*/
	getOptions: function(options) {
                //alert(options.errorsLocation);
		switch (options.errorsLocation) {
                        case "tooltip":
                        this.options.display.errorsLocation = 1;
                        break;
                        case "beforeinput":
                        this.options.display.errorsLocation = 2;
                        break;
                        case "afterinput":
                        this.options.display.errorsLocation = 3;
                        break;
                        case "beforeform":
                        this.options.display.errorsLocation = 4;
                        break;
                        default:
                        this.options.display.errorsLocation = 4;
                        break;
                }
                
                if(options.onlyOneError==1){
                     this.options.display.onlyOneError = options.onlyOneError;   
                } else{
                     this.options.display.onlyOneError = 0;
                }
                
                
	},
        
        removeAll: function(obj){
                for (var i in obj)   //obj[1] ... fields
		{
                  if(document.getElementsByName(i)[0]){
			var el = document.getElementsByName(i)[0];
                        var my_el = new Element(el);
			if(my_el.isValid){
                                this.removeError(my_el);	
                        }
                  }
		}
        },
        
               



        
        createError: function(obj){
                for (var i in obj)	//obj[0] ... errors
                {
                  if(document.getElementsByName(i)[0]){
                        //alert(this.fields.indexOf(this.currentElement));
                        //if(this.fields.indexOf(this.currentElement)==-1){
                        //   alert("yeah");     
                        //}
                        //alert(this.options.display.onlyOneError);
                         var el = document.getElementsByName(i)[0];
                                    var my_el = new Element(el);
                       
                        //alert(this.fields);test@asd.at
                        //alert("createError");
                        //alert(this.fields+":"+this.currentElement);
                       
                        if(this.currentElement == i || this.event == "submit" || (this.fields.indexOf(this.currentElement+",")==-1 && this.currentElement != i ) || this.options.display.onlyOneError==0){
                             
                                my_el.error = obj[i];
                       
                                my_el.isValid = false;
    
                                this.manageError(my_el,'submit');
                                if(this.options.display.onlyOneError == 1){
                                        break;    
                                }  
                        } 
                  }         
                }      
        },
        
        onKeyDown: function(event) {
                this.currentElement = event.target.name;
                var actionRegExp = /\_action=([A-Za-z0-9_]*)/;
                actionRegExp.exec(this.form.toQueryString());
                var save_action = RegExp.$1;
                
                var query = this.form.toQueryString();
                query = query.replace(save_action,"checkform_ajax");
            
                var url = this.form.getProperty('action')+"?"+query;

                new Request.JSON({
			url: url,
			onFailure: function(instance){
			}.bind(this),
			onSuccess: function(obj){
                                
                                var fields = "";
				for (var i in obj[0])	//obj[0] ... errors
                                {
                                        //fields.push(i);
                                        
                                        
                                        fields = fields + i + ",";
                                }
                                //fields.join(',');
                                this.fields = fields;
                                this.getOptions( obj[2] );
                                //alert(old_action);
				//this.form._action.value = old_action; //alte action muss jedes mal wieder zurück geschrieben werden!
				if(obj[0] == null || this.options.display.errorsLocation == 0){
                                        /*var el = new Element(document.getElementsByName("senden")[0]);
                                        el.error = "Absenden";
                                        el.isValid = false;
                                        this.manageError(el,"submit");*/
                                }
                                
                                this.reinitialize(obj);   
                                
                                
                                this.createError(obj[0]);
                                this.removeAll(obj[1]);
                                //this.removeAll(obj[1]);
				/*for (var i in obj[0])	//obj[0] ... errors
                                {
				    
                                    var el = document.getElementsByName(i)[0];
                                    var my_el = new Element(el);
                                    el.error = obj[0][i];
                                    //alert(my_el.getCoordinates().left);
				    //alert(var_dump(el));
				    el.isValid = false;
				    
                                    this.manageError(el,'submit');
				    
                                    //alert(obj[i]);
                                }*/
				
				
                                
				
				
                                
			               
			}.bind(this)
		}).send();
        },
        
     
        
        
        onSubmit: function(event) {

                this.event = event.type;
                //var old_action = this.form._action.value;
                var actionRegExp = /\_action=([A-Za-z0-9_]*)/;
                actionRegExp.exec(this.form.toQueryString());
                var save_action = RegExp.$1;
                
                var query = this.form.toQueryString();
                query = query.replace(save_action,"checkform_ajax");
                //alert(query);
                //this.form._action.value = "checkform_ajax";
                new Event(event).stop();
            
                var url = this.form.getProperty('action')+"?"+query;
		//this.fireEvent('ajaxRequest');
		//new Request.JSON({
                new Request.JSON({
			url: url,
			//data : query,
			//evalScripts: this.options.ajaxEvalScripts,
			onFailure: function(instance){
				//this.fireEvent('ajaxFailure', instance);
			}.bind(this),
			onSuccess: function(obj){
                                
				var fields = "";
				for (var i in obj[0])	//obj[0] ... errors
                                {
                                       if(document.getElementsByName(i)[0]){
                                            fields = fields + i + ",";
                                       } else{
                                             delete obj[0][i];
                                       }
                                        //fields.push(i);
                                        
                                }
                                //fields.join(',');
                                this.fields = fields;
                                if(obj[0] != null){
                                        this.getOptions( obj[2] );     
                                }
                                
                                //alert(old_action);
				//this.form._action.value = old_action; //alte action muss jedes mal wieder zurück geschrieben werden!
				if(obj[0] == null || this.options.display.errorsLocation == 0||this.fields==""){
                                    this.form.submit();
                                    return;
                                }
				 //alert(obj[2].errorLocation)
                                
				
				
				this.reinitialize(obj);
		
                             
                                
                                this.createError(obj[0]);
                                
                                this.removeAll(obj[1]);

                               
                                
				/*for (var i in obj[0])	//obj[0] ... errors
                                {
				    
                                    var el = document.getElementsByName(i)[0];
                                    var my_el = new Element(el);
                                    el.error = obj[0][i];
                                    //alert(my_el.getCoordinates().left);
				    //alert(var_dump(el));
				    el.isValid = false;
				    
                                    this.manageError(el,'submit');
				    
                                    //alert(obj[i]);
                                }
				
				for (var i in obj[1])   //obj[1] ... fields
				{
					var el = document.getElementsByName(i)[0];
			
	
					//alert(i+":"+el.isValid);
					if(el.isValid){
						this.removeError(el);	
					}			
				}*/
                                
                                
			               
                               

				
				
				
                                /*if(document.getElementById("errorlist")){ //Damit das Div gelöscht wird
                                    document.getElementById("errorlist").destroy();
                                    this.form.element = false;
                                }*/

                                

                                //this.focusOnError(this.firstError);
                               

                                
                                //alert(document.getElementsByName("email")[0].getCoordinates().left );
                                
                                //alert(obj.name);
                                /*elements.each(function(el, key) {
                                    alert(key);
                                }, this);*/

				//this.fireEvent('ajaxSuccess', result);
				//if(this.options.ajaxResponseDiv) $(this.options.ajaxResponseDiv).set('html',result);
			}.bind(this)
		}).send();
                
	}

});