/*
 * Form handlers
 *
 */
$(document).bind('ready', function(){

	$('form div.form-field')
		.live('focus', function(){
			$(this).addClass('focus');
		})
		.live('blur', function(){
			$(this).removeClass('focus');
		});

	var form_list = [];
	$('form.form-builder').each(function(){
		form_list.push(new Form(this));
	});
	
});

var Form = function(form_container){

	var _this = this;

	var form_container = $(form_container);
	var submit_main = $('.submit-main', form_container);
	var field_list = [];
	var running = false;
	this.submit = _submit;
	this.is_completed = _is_completed;
	this.check_status = _check_status;

	form_container.find('div.form-field').each(function(){
		field_list.push(new Field(this));
	});

	form_container.bind('submit', _submit);

	function _submit(){
		if(!running){
			submit_main.attr('disabled', 'disabled');
			var status = _this.is_completed();
			if(status == 'pending'){
				setTimeout(_this.submit, 500);
			}else{
				running = true;
				$.each(field_list, function(key, field){
					field.validate();
				});
				setTimeout(_this.check_status, 500);
			}
		}

		return false;
	}

	function _is_completed(){
		var status = 'valid';
		$.each(field_list, function(index, field){
			if(field.is_completed()){
				if(!field.is_valid()){
					status = 'error';
				}
			}else{
				status = 'pending';	
			}
		});
		return status;
	}

	function _check_status(){
		var status = _this.is_completed();
		if(status == 'pending'){
			setTimeout(_this.check_status, 500);
		}else if(status == 'valid'){
			form_container
				.unbind('submit')
				.trigger('submit');
		}else{
			submit_main.removeAttr('disabled');
			running = false;
		}
	}

}

var Field = function(field_container){

	var _this = this;

	var field_container = $(field_container);
	var field_element = field_container.find('.data');
	var validation_rules = field_container.find('[name^=validation]');
	var validation_rules_total = 0;
	var validation_rules_completed = 0;
	var data;
	var validation_status = true;

	this.validate = _validate;
	this.is_completed = _is_completed;
	this.is_valid = _is_valid;

	field_element.bind('blur', function(){
		_this.validate();
	});

	function _validate(){
		validation_rules_total = validation_rules.length;
		validation_rules_completed = 0;
		validation_status = true;

		data = field_element.val();
		data = data ? data : '';

		validation_rules.each(function(){
			var target = $(this);
			var validation_json = eval('('+target.val()+')');
			var url = '/api/?method=validation.checkRule&rule='+validation_json.rule+'&value='+data;
	
			$.each(validation_json.args, function(index, arg){
				url+='&args['+index+']='+arg;
			});

			$.getJSON(url, function(data){
				validation_rules_completed++;
				if(!data.outcome){
					validation_status = false;
					if(!field_container.find('.'+data.rule).length){
						var message = $('<p class="message error '+data.rule+'">'+data.message+'</p>');
						field_container.append(message);
					}
				}else{
					field_container.find('.'+data.rule).remove();
				}
			});
	
		});
	}

	function _is_valid (){
		return validation_status;	
	};
	
	function _is_completed(){
		if(validation_rules_completed == validation_rules_total){
			return true;
		}else{
			return false;	
		}
	};

};

