$(
  function() {
    var Search = new function() {
	  // private scope
	  var settings = {
		url: $('#logo').attr('href'),
	    selectors: { 
		  browse : {
			$form: $('#choose-region'),
			$regions: $('#search_browse div.country-region'),
			cbs: []
		  },
		  citySearch: {
			$wrap: $('#advert_search_wrap'),
			$search: $('#advert_search_string'),
			message: 'Your search for: &quot;{search}&quot; found <b>{count}</b> results.'
		  },
		  userSearch: {
			$wrap: $('#user_search_wrap'),
			$search: $('#user_search_string'),
			message: 'Your search for: &quot;{search}&quot; found <b>{count}</b> results.'
		  },		  
		  locations: {
			$form: $('#choose-location'),
			$btns: $('#choose-location input[@type=submit]'),
			$action: $('#action_url')
		  }
		}
	  };
	  var util = {
		replaceRegion: function(s, n, r) {
		  return s.replace(new RegExp('\{' + n + '\}', 'gim'), r);
		}
	  };
	  
	  var initBrowse = function(o) {
		o.$regions.each(
		  function(i) {
			var $name = $('h2', this).wrap('<a href="javascript:;" class="control"></a>').append('<img src="' + settings.url + 'public/images/xp_plus.gif" />').prepend('<input type="checkbox" id="search_check_all_' + i + '" />');
			var $states = $('div.state-region', this).hide();
			var $img = $('a.control img', this);
			var $checkAll = $('#search_check_all_' + i).bind(
			  'click',
			  function(e) {
				e.stopPropagation();
				this.checked ? $checkboxes.attr('checked', 'checked') : $checkboxes.attr('checked', '');
			  }
			);			
			var $checkboxes = $('input[@type=checkbox]', $states);
			$checkboxes.bind(
			  'click',
			  function(e) {
				var j = 0;
				var cbs = $checkboxes.get();
				for (; j < cbs.length; j++) {
				  if (!cbs[j].checked) {
				    break;
				  }
				}
				$checkAll.attr('checked', (j < cbs.length ? '' : 'checked'));
			  }
			);
			var $a = $('a.control', this).bind(
			  'click',
			  function(e) {
				if ($states.css('display') == 'none') {
				  $states.show('fast');
				  $img.attr('src', settings.url + 'public/images/xp_minus.gif');				  
				} else {
				  $states.hide('fast');
				  $img.attr('src', settings.url + 'public/images/xp_plus.gif');				  
				}
			  }
			);
		    $.merge(o.cbs, $checkboxes.get());
		  }
		);
		
		$message = $('span.s-e-m', $('input[@type=submit]', o.$form).after('<span class="s-e-m"></span>').end()).hide();
		
		o.$form.bind(
		  'submit',
		  function(e) {
			var i = 0, e = true;
			for (; i < o.cbs.length; i++) {
			  if (o.cbs[i].checked) {
			    e = false; 
				break;
			  }
			}
			e ? $message.html('Please select at least one state or country').fadeIn('fast') : $message.fadeOut('fast');
			return !e;  
		  }
		);		
	  };
	  var initSearch = function(o, t) {
		var $working = null;
		var $result = null;
		var $wraper = null;
		var $again = null;
		var $btn = $('input[@type=submit]', o.$wrap);
		var handler = '';

		if (!o.$wrap.length) {
		  return;
		}
		
		switch (t) {
		  case 'city': {
			handler = 'extensions/com/adverts/AdvertAjaxGateway.cfc';  
			break;  
		  }
		  case 'contact': {
			handler = 'extensions/com/contacts/ContactAjaxGateway.cfc';  
			break;  
		  }		  
		}
		
		o.$search.after('<img src="' + settings.url + 'public/images/working.gif" class="working" />');
		o.$wrap.append('<div class="wrapper"><input type="submit" value="Display Results" class="btn indent" /> <input type="submit" value="Search Again" id="search_again" class="btn" /></div>');				
		$btn.after('<span class="results"></span>');

		$working = $('img', o.$wrap).hide();
		$result = $('span', o.$wrap);
		$wrapper = $('div.wrapper', o.$wrap).hide();
		$again = $('#search_again').bind(
		  'click',
		  function(e) {
			$wrapper.fadeOut(
			  'fast',
			  function() {
				$result.html('');
				o.$search.val('').get(0).focus();  
			  }
			);
			
			return false;  
		  }
		);
		
		$btn.bind(
		  'click',
		  function(e) {
			var searchString = o.$search.val();  
			  
			$working.show();

			$.getJSON(
			  settings.url + handler,
			  'method=init&methodname=search&returntype=json&search=' + searchString,
			  function(JSON) {
				$result.html(util.replaceRegion(util.replaceRegion(o.message, 'count', JSON), 'search', searchString));
				$wrapper.fadeIn(
				  'fast', 
				  function() {
					$working.hide();							 
				  }
				);
			  }
			);
			return false;  
		  }
		);
	  };
	  var initLocations = function(o) {
		var $message = null;
		var method = 'method=init&methodname=get&returntype=json';
		var fields = {};
		var selects = [ 
		  { 
			id: 'country_id',
			label: 'Country:',
			url: settings.url + 'extensions/com/states/StateAjaxGateway.cfc?' + method
		  },
		  {
			id: 'state_id',		
			label: 'State:',	
			url: settings.url + 'extensions/com/counties/CountyAjaxGateway.cfc?' + method
		  },
		  {
			id: 'county_id',		
			label: 'County:',	
			url: settings.url + 'extensions/com/cities/CityAjaxGateway.cfc?' + method
		  },
		  {
			id: 'city_id',		
			label: 'City:'
		  }
		];
		
		o.$btns.hide();
		o.$form.ChainedSelects({ 
		  display: 'show',
		  defaultOptionValue: -1,
		  defaultLoadingText: '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;',
		  resetSelect: false,
		  selects: selects
		}).attr('action', o.$action.val());	 
		
		$.each(
		  selects,
		  function(i, n) {
			fields[this.label.replace(/:/, '')] = $('#' + this.id);
		  }
		);			
		
		$message = $('span.h-e-m', o.$form.append('<input type="submit" value="Display Results" class="indent btn" style="width:100px;" /><span class="h-e-m"></span>')).hide();
		
		o.$form.bind(
		  'submit',
		  function(e) {
			var e = [];
			$.each(
			  fields,
			  function(i, n) {
				this.val() == -1 ? e.push(i) : null;
			  }
			);			

			e.length ? $message.html('Please select values for: ' + e.join(', ')).fadeIn('fast') : $message.fadeOut('fast');
			return e.length ? false : true;  
		  }
		);
	  };
	
	  // public scope
	  this.init = function() {
		initBrowse(settings.selectors.browse);
		initSearch(settings.selectors.citySearch, 'city');
		initSearch(settings.selectors.userSearch, 'contact');		
		initLocations(settings.selectors.locations);
	  };
	};
	Search.init();
  }
);