(function($) {
	var settings = {
			messageSelector: "label.form_msg",
			url: "general/optionsFetch.php"
	};

	function OptionManager(element, parent) {
		this.element = element;
		
		this.getQuery = function() {
			if(parent === undefined)
				return $(element).val();
			else
				return $(element).val() + "_" + parent.getQuery();
		};
		
		var children = [];

		this.addChild = function(child) {
			children.push(child);
		};
		
		parent === undefined || parent.addChild(this);
		
		$(element).change(function() {
			for (i in children) {
				var child = children[i];
				if($(this).val() == $(this).attr('_nullval'))
					child.hide();
				else
					child.update();
			}
		});
		
		this.hide = function(callback) {
			var countdown = children.length + 1;

			var route = function() {
				countdown--;
				countdown != 0 || callback === undefined || callback();
			};
			
			$(element).fadeOut("normal",function() {
				$(this).val($(this).attr('_nullval'));
				$(this).find("[value!="+$(this).attr('_nullval')+"]").remove();
				$(this).removeClass('required');
				$(this).resetValidation();
				$(this).message().html(settings.messages.notApplicable);
				route();
			});
			
			for (i in children)
				children[i].hide(route);
		};
		
		this.update = function(callback) {
			var query = parent.getQuery();
			this.hide(function() {
				$(element).message().html(settings.messages.loading);
				$.ajax({
					data: {
						lang: settings.language,
						req: query 
					},
					error: function() {
						$(element).message().html(settings.messages.serverFailure).addClass('invalid');
						if($(parent.element).hasClass('required'))
							$(element).addClass('required');
						callback();
					},
					success: function(response) {
						if(response != "") {
							$(element).append(response);
							$(element).message().html("");
							if($(parent.element).hasClass('required'))
								$(element).addClass('required');
							$(element).fadeIn("normal",callback);
						} else {
							$(element).message().html(settings.messages.notApplicable);
							callback === undefined || callback();
						}
					},
					timeout: 30000,
					type: "post",
					url: settings.url
				});
			});
		};
	}

	$.extend({
		optionsSetup: function(options) {
			$.extend(settings,options);
		},
		optionsAssign: function(levels) {
			for(i in levels)
				$(levels[i]).each(function() {
					var parentId = $(this).attr("_parentId");
					var parent = document.getElementById(parentId);
					if(parent === null)
						parent = undefined;
					else
						parent = parent.myOptions;
					this.myOptions = new OptionManager(this,parent);
				});
		}
	});
})(jQuery);
