var FormValidator = function(){
	
	var tests = new Array();
	var errors = new Array();
	var valAlerts = new Array();
	
	this.validated = true;
	
	this.register = function(formID){
		
		$('#'+formID).submit(function(){
			
			var errors = new Array();
			
			$('#'+formID+' :input').each(function(k,v){
				
				
				var className = explode(' ',$(v).attr('class'));
				
				if(className == null || className == undefined){
					return true;
				}
				
				$.each(className,function(kk,vv){
					
					if(testExists(vv)){
						
						if(!executeCallback(vv,$(v).val(),$(v))){
							
							var erroItem = new Array();
							erroItem['elemento'] = $(v);
							erroItem['elemento_id'] = $(v).attr('id');
							erroItem['message'] = getErrorMessage(vv);
							erroItem['testName'] = vv;
							formSubmit.validator.addError(erroItem);
						}
						else
						{
							if(formSubmit.validator.hasAlert($(v).attr('id'))){								
								var alert = formSubmit.validator.getAlert($(v).attr('id'));
								$(alert).hide('fast');
								formSubmit.validator.cleanAlert($(v).attr('id'));
							}
						}
					}
				});
				
			});

			if(formSubmit.validator.getErrors().length === 0){
				
				formSubmit.validator.validated = true;
				
				
			}
			else
			{
				$.each(formSubmit.validator.getErrors(),function(k,v){
					
					var Options = getOptions(v['testName']);
										
					if(Options != null && Options.alert){
						alert(v['message']);
						formSubmit.validator.validated = false;
					}
					else
					{
						if(!formSubmit.validator.hasAlert(v['elemento_id'])){
							formSubmit.validator.addAlert(v['elemento'],v['message']);
							formSubmit.validator.validated = false;
						}
					}
					
					
				});
			}
				
			

			formSubmit.validator.cleanErrors();
			
		});
		
	}
	
	var getOptions = function(testName){
		var options = null;
		$.each(tests,function(k,v){
			if(v['name'] == testName){
				options = v['options'];
			}
		});
		return options;
	}
	
	this.cleanErrors = function(){
		errors = new Array();
		 
	}
	
	this.getErrors = function(){
		
		return errors;
	}
	
	this.addError = function(item){
		
		errors[errors.length] = item;
		
	}
	
	var getErrorMessage = function(testName){
		
		var errorMessage = null;
		$.each(tests,function(k,v){
			if(v['name'] == testName){
				errorMessage = v['message'];
			}
		});
		return errorMessage;
		
	}
	
	var executeCallback = function(testName,value,elm){
		var callBackResult = null;
		$.each(tests,function(k,v){
			if(v['name'] == testName){
				var callBack = v['callback_test'];
				callBackResult = callBack(value,elm);
			}
		});
		return callBackResult;
	}
	
	this.getValid = function(testName,value,elm){
		
		return executeCallback(testName,value,elm);
		
	}
	
	var testExists = function(testName){
		var no_erro = false;
		$.each(tests,function(k,v){
			if(v['name'] == testName){
				no_erro = true;
			}
		});
		return no_erro;
	}
	
	this.validate = function(){
		
	}
	
	this.addTest = function(name,message,callback_test,options){
		var testItem = new Array();
		
		testItem['name'] = name;
		testItem['message'] = message;
		testItem['callback_test'] = callback_test;
		testItem['options'] = options;
		
		tests[tests.length] = testItem;
	}
	
	this.hasAlert = function(elm_id){
		
		var has = false;
		$.each(valAlerts,function(k,v){
			
			if(typeof v == 'undefined'){
				return true;
			}
			
			if(v.id == 'validate-'+elm_id){
				has = true;
			}
		});
		return has;
	}
	
	this.cleanAlert = function(elm_id){
		var has = false;
		$.each(valAlerts,function(k,v){
			
			if(typeof v == 'undefined'){
				return true;
			}
			
			if(v.id == 'validate-'+elm_id){
				has = k;
			}
		});
		valAlerts[has] = undefined;
	}
	
	this.getAlert = function(elm_id){
		
		var alert = null;
		$.each(valAlerts,function(k,v){
			
			if(typeof v == 'undefined'){
				return true;
			}
			
			if(v.id == 'validate-'+elm_id){
				alert = v;
			}
		});
		return alert;
	}
	
	this.addAlert = function(elm,msg){
		
		var alert_element = document.createElement('div');
		alert_element.innerHTML = msg;
		alert_element.className = 'validate-error';
		alert_element.style.display = 'none';
		alert_element.id = 'validate-'+elm.attr('id');
		elm.after(alert_element);
		$(alert_element).show('fast');
		
		valAlerts[valAlerts.length] = alert_element;
		
	}
	
}




var FormUpload = function(formSubmit){

	var uploadDivs = new Array();
	var uploadAdded = new Array();
	var uploadForm = new Array();
	var upConfig = new Array();
	var numberUps = 0;
	var actualDiv = null;
	
	this.remove = function(idImage,divId){
		$.getJSON('ajax/upload.php','remove='+idImage,function(response){
			
			$.each(uploadAdded[divId],function(k,v){
				if(typeof v =='undefined'){
					return true;
				}
				
				if(v['tempFileName'] == idImage){
					$(v['object']).fadeOut('slow');
					uploadAdded[divId][k] = undefined
				}
			});
			
		});
	}
	this.add = function(divId,formId,config){
		
		var configItem = new Array();
		configItem['div'] = divId;
		configItem['maxlength'] = config;
		
		upConfig[upConfig.length] = configItem;
		
		var uploadFormItem =new Array();
		uploadFormItem['div'] = divId;
		uploadFormItem['form'] = formId
		uploadForm[uploadForm.length] = uploadFormItem;
		
		
		var divObj = new Array();
		divObj['id'] = divId;
		
		
		var upButton = document.createElement('input');
		upButton.type = 'button';
		upButton.name = divId+'_upload_button';
		upButton.value = 'Buscar...';
		upButton.id = divId+'_upload_button';
		upButton.className = 'upload_upload_button';

		var upResult = document.createElement('div');
		upResult.id=divId+'_upload_result';
		upResult.className = 'upload_upload_result';
		
		var upError = document.createElement('div');
		upError.id=divId+'_upload_error';
		upError.className = 'upload_upload_error';
				
		divObj['upButton'] = upButton;
		divObj['upResult'] = upResult;
		divObj['upError'] = upError;
		uploadDivs[divId] = divObj;
		
		uploadAdded[divId] = new Array();
		
		$('#'+divId).append(upError);
		$('#'+divId).append(upResult);
		$('#'+divId).append(upButton);
		
		
		addListener(divId);
		
				
	}
	
	this.getForm = function(formId){
		
		
		var formDivs = new Array();
		
		$.each(uploadForm,function(k,v){
			
			if(v['form'] == formId){
				$.each(uploadAdded[v['div']],function(kk,vv){
					
					
					if(typeof vv == 'undefined'){
						return true;
					}
					
					var divQuery = new Array();
					divQuery['tempFilename'] = vv['tempFileName'];
					divQuery['filename'] = vv['realFileName'];
					divQuery['divname'] = v['div'];
					
					formDivs[formDivs.length] = divQuery;					
				});
			}
		});
		
		var qry = '';
		var j = 0;
		$.each(formDivs,function(k,v){
			
			qry += v['divname'] + '['+j+'][tempFilename]=' +  v['tempFilename'] + "&";
			qry += v['divname'] + '['+j+'][filename]=' +  v['filename'] + "&";
			j++;
			
		});
		return qry;
		
		
	}

	var addListener = function(divId){

		
		new AjaxUpload(divId+'_upload_button', {
		  action: 'ajax/upload.php',
		  responseType: 'json',
		  onSubmit: function(file, ext) {
				if(!checkNumbers(divId)){
					alert('Você colocou mais imagens que o possivel!');
					return false;
				}
				if(!checkImages(ext)){
					alert('O arquivo '+file+' não é uma imagem!');
					return false;
				}
			  
		 },
		  onComplete: function(file, response) {
			
			if(!response.status){
				alert(response.error);
				return false;
			}
			  var holeObj = document.createElement('div');
			  holeObj.id = response.tempFileName;
			  holeObj.className = 'upload_item_result';
			  holeObj.style.display = 'none';
			  
			  holeObj.innerHTML = '<a href="javascript:void(0);" onClick="formSubmit.upload.remove(\''+response.tempFileName+'\',\''+divId+'\')" class="upload_item_remove"></a> <span class="upload_item_title">'+response.realFileName+'</span>';
			  $(uploadDivs[divId]['upResult']).append(holeObj);

			  var addedUp = new Array();
			  addedUp['tempFileName'] = response.tempFileName;
			  addedUp['realFileName'] = response.realFileName;
			  addedUp['object'] = holeObj;
			  
			  uploadAdded[divId][uploadAdded[divId].length] = addedUp;
			  $(holeObj).fadeIn('fast');

		  }
		});
	}
	
	var checkNumbers = function(divId){
		var noerror = true;
		$.each(upConfig,function(k,v){
			
			if(v['div'] == divId){
				
				var totalUps = 0;
				$.each(uploadAdded[divId],function(k,v){
					if(typeof v == 'undefined'){
						return true;
					}
					totalUps++;
				});
				
				if(totalUps >= v['maxlength']){
					noerror = false;
				}
			}
		});
		return noerror;
	}
	
	var checkImages = function(ext){
		if (! (ext && /^(jpg|png|jpeg|gif)$/.test(ext))){
			return false;
		}
		else{
			return true;
		}
	}
	
};



var FormSubmit = function(){

	var formRegistered = new Array();
	
	this.get = function (obj) {
	  var getstr = "";
	  for (i=0; i<obj.getElementsByTagName("input").length; i++) {
	        if (obj.getElementsByTagName("input")[i].type == "text") {
	           getstr += obj.getElementsByTagName("input")[i].name + "=" + 
	           urlencode(obj.getElementsByTagName("input")[i].value) + "&";
	        }
	        if (obj.getElementsByTagName("input")[i].type == "hidden") {
		           getstr += obj.getElementsByTagName("input")[i].name + "=" + 
		           urlencode(obj.getElementsByTagName("input")[i].value) + "&";
		        }
	        if (obj.getElementsByTagName("input")[i].type == "password") {
	           getstr += obj.getElementsByTagName("input")[i].name + "=" + 
	           hex_md5(obj.getElementsByTagName("input")[i].value) + "&";
	        }
	        if (obj.getElementsByTagName("input")[i].type == "checkbox") {
	           if (obj.getElementsByTagName("input")[i].checked) {
	              getstr += obj.getElementsByTagName("input")[i].name + "=" + 
	              urlencode(obj.getElementsByTagName("input")[i].value) + "&";
	           } else {
	              getstr += obj.getElementsByTagName("input")[i].name + "=&";
	           }
	        }
	        if (obj.getElementsByTagName("input")[i].type == "radio") {
	           if (obj.getElementsByTagName("input")[i].checked) {
	              getstr += obj.getElementsByTagName("input")[i].name + "=" + 
	              urlencode(obj.getElementsByTagName("input")[i].value) + "&";
	           }
	     }  
	  }
	  
	  for (i=0; i<obj.getElementsByTagName("select").length; i++) {
	        
	       getstr += obj.getElementsByTagName("select")[i].name + "=" + 
	       urlencode(obj.getElementsByTagName("select")[i].value) + "&";

	  }
	  
	  for (i=0; i<obj.getElementsByTagName("textarea").length; i++) {
	        
	       getstr += obj.getElementsByTagName("textarea")[i].name + "=" + 
	               urlencode(obj.getElementsByTagName("textarea")[i].value) + "&";

	  }
	  
	  return getstr;
	}
	
	
	
	this.register = function(formID){
		
		formRegistered[formRegistered.length] = formID;
		
		 $('#'+formID+' .file_upload').each(function(i,k){
			 
			var id=$(k).attr('id');
			var config=$(k).attr('rel');
			
			formSubmit.upload.add(id,formID,config);
		 });
		
		 $('#'+formID).submit(function(){
			return false; 
		 });
		 
		 this.validator.register(formID);
		 
		$('#'+formID).submit(function(){
			
			
			if(!formSubmit.validator.validated){
				return false;
			}
			
			var url = $(this).attr('action');
			var data = formSubmit.get($(this).get(0));
		
			data += formSubmit.upload.getForm($(this).attr('id'));
			
			$.post(url,data,function(result){
				if(result.result == false){
					
					var tempErros = '';
					
					$.each(result.erros,function(m,n){
						tempErros += "\n"+n;
					});
					
					alert('Ocorreu um erro na sua solicitação!'+tempErros);
				}
				else
				{
					alert('Solicitação enviada com sucesso!');
					
					window.location=result.next;
					return false;
				}
				
			},'json');
			
			return false;
		});
		
		
	}
	
	this.upload = new FormUpload(this);
	this.validator = new FormValidator();
	this.validator.addTest('required','Este campo é obrigatório!',function(val){
		if(val==''){return false;}return true;
	});
	
	this.validator.addTest('validate-email','É necessário um email válido!',function (v) {
       
        return /^[a-z0-9,!\#\$%&'\*\+/=\?\^_`\{\|}~-]+(\.[a-z0-9,!#\$%&'\*\+/=\?\^_`\{\|}~-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*\.([a-z]{2,})/i.test(v);
    });
    
    this.validator.addTest('validate-not-negative-number', 'Por favor, entre com um numero valido!', function(v) {
        v = parseNumber(v);
        return (!isNaN(v) && v>=0);
    });
    
    this.validator.addTest('IsEmpty', '', function(v) {
        return  (v == '' || (v == null) || (v.length == 0) || /^\s+$/.test(v)); // || /^\s+$/.test(v));
    });
    
    this.validator.addTest('validate-date-au','Por favor, utilize este formato de data: dd/mm/yyyy.',function(v) {
    	
        if(formSubmit.validator.getValid('IsEmpty',v)) return true;
        var regex = /^(\d{2})\/(\d{2})\/(\d{4})$/;
        if(!regex.test(v)) return false;
        var d = new Date(v.replace(regex, '$2/$1/$3'));
        return ( parseInt(RegExp.$2, 10) == (1+d.getMonth()) ) &&
                    (parseInt(RegExp.$1, 10) == d.getDate()) &&
                    (parseInt(RegExp.$3, 10) == d.getFullYear() );
    });
	
    this.validator.addTest('validate-number', 'Por favor, coloque um número neste campo.', function(v) {
        return formSubmit.validator.getValid('IsEmpty',v) || (!isNaN(parseNumber(v)) && !/^\s+$/.test(parseNumber(v)));
    });
    
    this.validator.addTest('validate-phone', 'Por favor, utilize um telefone válido. Por exemplo 48 3333-1234.', function(v) {
        return formSubmit.validator.getValid('IsEmpty',v) || /^(\()?\d{2,3}(\))?(-|\s|\.)?\d{4}(-|\s|\.)?\d{4}$/.test(v);
    });
    
    this.validator.addTest('validate-use-terms', 'Para prosseguir você deve aceitar os termos de uso.', function(v,elm) {
        return elm.attr('checked');
    },{alert:true});
    
}

var formSubmit = new FormSubmit();

