(function($) {
	jQuery.fn.searchFilterOptions = function() {
		// setup the basic required variables
		$('#frm_options').css('visibility', 'hidden');
		$('#prop_search_loading').css('visibility', 'visible');
		var form = $(this);
		var fields = new Array();
		$.each(form.find('select'), function(i, el) {
			fields[i] = el.id;
			$(el).change(select_change);
		});
		// Ajax URL
		var url = document.location.href.split('?')[0]
		if (url.substr(-1) == '/')
			url += 'index';
		else {
			var urlbits = url.split('/');
			var rx = new RegExp('^index(?:|\.html)$')
			if (!urlbits[urlbits.length-1].match(rx))
				url += '/index';
		}
		url += ':getDistinctIndexJson';
		// Default ajax params
		var params = {dindex: fields.join(',')};

		// reset the form
		form.find('input[type=reset]').click(function(e) {
			$('#frm_options').css('visibility', 'hidden');
			$('#prop_search_loading').css('visibility', 'visible');
			var params = {dindex: fields.join(','), refresh: Number(new Date)};
			$.each(fields, function(i, field) {
				reset_select(form.find('#'+ field));
				params[field] = 'reset';
			});
			$('.propertyitem-top, .propertyitem, .paging').remove();
			$.getJSON(url, params, function(data, status) {
				json_callback(data, status);
		    });
			
			return false;
		});

		// bound to the change event of the form's select inputs
		function select_change(event) {
			$('#frm_options').css('visibility', 'hidden');
			$('#prop_search_loading').css('visibility', 'visible');
			params['refresh'] = Number(new Date);
			$.each(fields, function(i, field) {
				params[field] = form.find('#' + field).val() || "reset";
			});
			var $this = $(this);					
			$.getJSON(url, params, function(data, status) {
				json_callback(data, status, $this, $this.val());
			});
		};
		
		// select the appropriate options based on the GET parameters
		var get = get_query_params();
		var use_get = false;
		$.each(get, function(key, value) {
			if($("select[name='" + key + "']").length) {
				var el = form.find("select[name='" + key + "']");
				if (el.length == 0 || value == "")
					return true;
				$('<option>').val(value).text(ucfirst(value)).appendTo(el);
				el.val(value).change();
				use_get = true;
			}
		});
		
		// populate the select boxes with all available options (if it's a fresh search)
		if (!use_get) {
			var params = params;
			$.each(fields, function(i, field) {
				reset_select(form.find('#'+ field));
				params[field] = 'reset';
			});
			params['refresh'] = Number(new Date);
			$.getJSON(url, params, json_callback);
		}
		
		// Internal Functions
		function json_callback(data, status, $this, val) {
			$.each(data, function(key, values) {
				if (values == null) // poor responses from server here.
					values = [];
				if (values[0] != undefined && String(values[0]).match(RegExp(/\d+\-\d+/)))
					values = values.sort(function(a, b) {
						a = Number(a.split('-')[0].replace(',', ''));
						b = Number(b.split('-')[0].replace(',', ''));
						return (a - b);
					});
				var el = form.find('#' + key)
				if (el.length == 0)
					return;
				el_val = el.val();
				reset_select(el);
				$.each(values, function(i, option) {
					option = String(option);
					if (option.indexOf('selected:') === 0)
						option = option.substr(9);
					$('<option>').val(option).text(ucfirst(option)).appendTo(el);
				});
				el.val(el_val);
			});
			
			$('#frm_options').css('visibility', 'visible');
			$('#prop_search_loading').css('visibility', 'hidden');
			
			try {
				$this.val(val);
			} catch(e) {}
		};
		
		function reset_select(el, val) {
			if (val == undefined)
				val = ''
			el.children().remove();
			$('<option>').val(val).text('All').appendTo(el);
		};
		
		function ucfirst(string) {
			// helper function to mimic python's str.title()
			if (typeof(string) != "string")
				string = new String(string);
			var strarr = string.split(/\s+/);
			$.each(strarr, function(i, w) {
				strarr[i] = w.replace(/^(.)/, function(char) { return char.toUpperCase(); });
			});
			return strarr.join(' ');
		};
		
		function get_query_params() {
			var params = {};
			if (window.location.search.length <= 1)
				return params;
			qs = window.location.search.substring(1);
			$.each(qs.split('&'), function(i, pair) {
				keyval = pair.split('=');
				params[decodeURIComponent(keyval[0])] = decodeURIComponent(keyval[1]).replace('+', ' ');
		    });
			
			$('#frm_options').css('visibility', 'visible');
			$('#prop_search_loading').css('visibility', 'hidden');
			return params;
		};
	};
})(jQuery);
