String.prototype.unfilterJSON = function (filter) { return this.replace(filter || /^\/\*-secure-([\s\S]*)\*\/\s*$/, '$1'); };

String.prototype.blank = function(){ return (/^\s*$/).test(this); };

String.prototype.isJson = function () {
	var str = this;
	if (str.blank()) { return false; }
	str = this.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, '');
	return (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(str);
};

String.prototype.evalJSON = function (sanitize) {
	var json = this.unfilterJSON();
	try {
		if (!sanitize || json.isJSON()) { return eval('(' + json + ')'); }
	} catch (e) { }
	throw new SyntaxError('Badly formed JSON string: ' + this);
};

function Mapping (el,data) {
	
	this.element = el;
	this.mapVars = {};
	this.map = null;
	
	if (data && typeof(data[el.id]) != 'undefined') {
		try {
			this.mapData = data[el.id].evalJSON();
		} catch (er) {
			this.mapData = false;
		}
	} else {
		this.mapData = false;
	}
	
	this.resetLocations = function(locations) {
		this.mapData.locations = locations;
		this.map.clearOverlays();
		if (this.mapData.pin) {	this.addPin(this.mapData.pin, '/images/map_pin.png', null);	}
		this.setMap();
	};
	
	this.geocode = function (address) {
		var mapping = this;
		if (!this.mapData.geoCoder) {
			this.mapData.geoCoder = new google.maps.ClientGeocoder();
		}
		this.mapData.geoCoder.getLatLng(address, function (latLng) {
			if (latLng) {
				mapping.map.setCenter(latLng, 17, G_HYBRID_MAP);
				mapping.draggablePin();
			}
		});
	};
	
	this.locationFromBrowser = function() {
		if (navigator.geolocation && navigator.geolocation.getCurrentPosition) {
			navigator.geolocation.getCurrentPosition(function (position) {
				this.addPin(new GLatLng(position.coords.latitude, position.coords.longitude), "Your Current Location", null);
				this.map.setCenter(new GLatLng(position.coords.latitude, position.coords.longitude), 14);
			});
		}
	}
	
	this.draggablePin = function () {
		this.map.clearOverlays();
		var latLong = this.map.getCenter();
		var searchLoc = new google.maps.Marker(latLong, {
			icon: new google.maps.Icon(this.mapVars.baseIcon, '/images/map_pin.png'),
			title: 'draggable',
			draggable: true
		});
		this.map.addOverlay(searchLoc);	
		google.maps.Event.addListener(searchLoc, "dragend", function (latLong) { console.log((Math.round(latLong.lat()*1000000)/1000000) + ", " + (Math.round(latLong.lng()*1000000)/1000000)); });	
	};
	
	this.setMap = function() {
		if (!this.map)
		{ 
			this.prepareMap();
		}
		for (var i in this.mapData.locations) {
			var l = this.mapData.locations[i],
				sum = 0,
				title = l.name;
				results = false;
			if (l.results && l.results.length > 0) {
				results = $('<ul/>').addClass('gmapWindowResults');
				jQuery.each(l.results, function(){
					sum += parseInt(this.rating, 10);
					var link = $('<a/>').html(this.name + ' (' + this.rating + '%)').attr('onclick', 'iWGC.highlightSearchResult(\'' + this.type + '\', ' + this.id + '); return false;').attr('href', '#');
					results.append($('<li/>').append(link));
				});
				sum /= l.results.length;
				sum = isNaN(sum) ? "--" : Math.round(sum);
				title += ' (' + sum + '%)';
			} else if (l.score) {
				sum = l.score;
			} else {
				sum = false;
			}
			var infoWindow = $('<div/>');
			infoWindow.append($('<div/>').addClass('gmapWindowTitle').html(title));
			if (results){
				infoWindow.append(results);
			}
			infoWindow.append($('<div/>').addClass('gmapWindowDescription').html(l.address));
			var pin = this.addPin(l, this.iconName(sum, l.type), infoWindow);
			l.mapPin = pin;
		}
		
		$('.search-result').each(function () {
			$(this).find('.locations li').each(function () {
				var id = $(this).attr('title');
				var locLink = $('<a/>').attr('href', '#').html($(this).html());
				locLink.bind('click', function () { $('#mainMap').data('map').showPinInfo(id); });
				$(this).empty().append(locLink);
			});
		});
		
		if (!this.mapVars.bound.isEmpty()) {
			var zoom = this.map.getBoundsZoomLevel(this.mapVars.bound);
			zoom = zoom > 12 ? 12 : zoom;
			this.map.setCenter(this.mapVars.bound.getCenter(), zoom);
		}
		
	};
	
	this.prepareMap = function () {
		$(this.element).css({ display: 'block' });
		this.map = new google.maps.Map2(this.element);
		this.map.setCenter(new GLatLng(55, -5), 4);
		this.mapVars.mapUI = this.map.getDefaultUI();
		this.mapVars.mapUI.controls.scalecontrol = false;
		this.mapVars.mapUI.controls.maptypecontrol = false;
		this.mapVars.mapUI.controls.menumaptypecontrol = true;
		this.map.setUI(this.mapVars.mapUI);
		this.mapVars.size = this.map.getSize();
		this.mapVars.bound = new google.maps.LatLngBounds();
		this.mapVars.baseIcon = new google.maps.Icon();
		this.mapVars.baseIcon.iconAnchor = new google.maps.Point(11, 37);
		this.mapVars.baseIcon.infoWindowAnchor = new google.maps.Point(17, 2);
		this.mapVars.baseIcon.iconSize = new google.maps.Size(22, 37);
		this.mapVars.baseIcon.shadow = '/images/pin_shadow.png';
		this.mapVars.baseIcon.shadowSize = new google.maps.Size(42,37);
		if (this.mapData.pin) {	this.mapData.pinMarker = this.addPin(this.mapData.pin, '/images/map_pin.png', null);	}
		$(window).bind('unload', function () { google.maps.Unload(); });
	};
	
	this.addPin = function (location, icon, popup) {
		if (location.latitude && location.longitude) {
			var latLong = new google.maps.LatLng(location.latitude, location.longitude);
			var title = location.name;
			if (this.mapData.pinMarker) {
				title += " (" + this.calcDistance(latLong, this.mapData.pinMarker) + "miles)";
			} 
			var searchLoc = new google.maps.Marker(latLong, {
				icon: new google.maps.Icon(this.mapVars.baseIcon, icon),
				title: title
			});
			
			this.mapVars.bound.extend(latLong);
			this.map.addOverlay(searchLoc);
			if (popup) {
				searchLoc.bindInfoWindowHtml(popup.html(), { maxWidth: this.mapVars.size.width - 40 });
			}
			return searchLoc;
		} else {
			return null;
		}
	};
	
	this.iconName = function (score, type) {
		type = type.toLowerCase();
		if (score === false) { return '/images/pin_' + type + '_na.png'; }
		else if (score >= 67) { return '/images/pin_' + type + '_high.png'; }
		else if (score >= 33) { return '/images/pin_' + type + '_mid.png'; }
		else if (score >= 0 ) { return '/images/pin_' + type + '_low.png'; }
		else { return '/images/pin_' + type + '_none.png'; }
	};
	
	this.showPinInfo = function (id) {
		var pin = this.mapData.locations[id].mapPin;
		this.map.setCenter(pin.getLatLng(), 14);
	};
	
	this.calcDistance = function(latLng, refPin) {
		if (refPin) {
			return Math.round(latLng.distanceFrom(refPin.getLatLng()) / 1609.344 * 100) / 100;
		} else {
			return false;
		}
	};
}

var iWGC = {
	
	overlayDocument: function (content, options) {
		
		$('.ui-widget-overlay, .ui-widget-shadow, .ui-widget').remove();
		var body = $('body'), offsetTop = 0, offsetLeft = 0, offsetBottom = 0, offsetRight = 0, shadow = null;
		
		if (options.modal || options.shadow) {
			var overlay = $('<div/>').css({ width: $(document).width(), height: $(document).height(), zIndex: 1001 });
			body.append(overlay);
			if (options.modal) {
				overlay.addClass('ui-widget-overlay');
			}
			if (options.shadow) {
				shadow = $('<div/>').addClass('ui-widget-shadow').css({ position: 'absolute', display: 'none', zIndex: 1002 });
				overlay.append(shadow);
				offsetTop -= parseInt(shadow.css('margin-top'), 10);
				offsetLeft -= parseInt(shadow.css('margin-left'), 10); 
				offsetBottom += parseInt(shadow.css('padding-bottom'), 10) + parseInt(shadow.css('padding-top'), 10) + parseInt(shadow.css('margin-top'), 10);
				offsetRight += parseInt(shadow.css('padding-right'), 10) + parseInt(shadow.css('padding-left'), 10) + parseInt(shadow.css('margin-left'), 10); 
			}
		}	
		
		var width = options.width || 400,
			hPos = options.hpos == 'top'   || options.hpos == 'bottom' ? options.hpos : 'middle',
			vPos = options.vpos == 'right' || options.vpos == 'left'   ? options.vpos : 'center',
			pTop = $(document).scrollTop(), pLeft = $(document).scrollLeft(),
			overlayDoc = $('<div/>').addClass('ui-widget ui-widget-content ui-corner-all').attr('id', 'overlayDiv').html(content);
			
		overlayDoc.css({ position: 'absolute', display: 'none', zIndex: 1003, width: width + "px", height: 'auto' });
		body.append(overlayDoc);
		switch (hPos) {
			case 'top' :
				pTop += 0 + offsetTop;
				break;
			case 'bottom' :
				pTop += $(window).height() - overlayDoc.outerHeight() - offsetBottom;
				break;
			default: 
			case 'middle' :
				pTop += ($(window).height() - overlayDoc.outerHeight()) / 2;
		}
		switch (vPos) {
			case 'left' :
				pLeft += 0 + offsetLeft;
				break;
			case 'right' :
				pLeft += $(window).width() - overlayDoc.outerWidth() - offsetRight;
				break;
			default:
			case 'center' :
				pLeft += ($(window).width() - overlayDoc.outerWidth()) / 2;
		}
		overlayDoc.find('form').ajaxForm();
		overlayDoc.find('a.toButton').linkToButton();
		overlayDoc.css({ top: pTop + "px", left: pLeft + "px"}).fadeIn('normal');
		if (shadow) { shadow.css({ top: pTop + "px", left: pLeft + "px", width: overlayDoc.outerWidth() + "px", height: overlayDoc.outerHeight() + "px" }).css({display: 'block'}); }
	},

	loadSearchBox: function (url) {
		$('#searchBox').elementLoadingToggle();
		var url_parts = url.split("/");
		window.location.hash = "#/" + url_parts[url_parts.length - 2] + "/" + url_parts[url_parts.length - 1];  

		$.ajax({
			url: url,
			type: 'get',
			error: function (req, status, error) {
				$('#searchBox').elementLoadingToggle();
				alert("Cannot load search form");
			},
			success: function (response, status) {
				$('#searchBox').elementLoadingToggle();
				$('#searchBoxContainer').html(response);
				$('#searchForm').setupSearchBox();
			}
		});
	},
	
	hideSearchBox: function() {
		$('#searchBox').hide('blind', 'normal', function () { 
			$('#searchBoxContainer').remove();
			$('#searchBoxHide').remove();
			$('#searchBoxShow').css({ display: 'block' });
			$('#searchBox').addClass('hidden');
			$('#searchBox').show('blind', {}, 'normal');
		});
	},
	
	showSearchBox: function(url) {
		$('#searchBoxShow').append('<img src="/images/ajax-loader-4.gif" border="0"/>');
		$.ajax({
			url: url,
			type: 'get',
			error: function (req, status ,error) {
				alert("Cannot load search form");
			},
			success: function (response, status) {
				$('#searchBox').hide('blind', 'normal', function () { 
					$('#searchBoxShow img').remove();
					if ($('#searchBoxContainer').length === 0) { $('#searchBox').append($('<div/>').attr('id', 'searchBoxContainer')); }
					$('#searchBoxContainer').html(response);
					$('#searchForm').setupSearchBox();
					$('#searchBoxShow').css({ display: 'none' });
					var hideDiv =  $('<div/>').attr('id', 'searchBoxHide').append($('<a href="#" />').html('Hide').bind('click', function() { iWGC.hideSearchBox(); return false; }));
					$('#searchBox').removeClass('hidden').append(hideDiv).show('blind', {}, 'normal');
				});
			}
		});
	},

	disableForm: function (form, text) {
		text = text || "Saving...";
		form = $(form);
		form.attr("disabled", "disabled");
		form.find(':input:enabled').attr("disabled", "disabled").data('re-enable', true);
		form.find('.ui-slider').slider('disable');
		form.find(':submit').each(function () {
			$(this).css({ width: $(this).outerWidth() + 'px' });
			$(this).data('defaultText', this.value);
			this.value = text;
		});
	},
	
	enableForm: function (form) {
		form = $(form);
		form.removeAttr("disabled");
		form.find(':input').each(function() {
			if ($(this).data('re-enable')) {
				$(this).removeAttr("disabled");
			}
		});
		form.find('.ui-slider').slider('enable');
		form.find(':submit').each(function () {
			this.value = $(this).data('defaultText');
			$(this).css({ width: 'auto' });
		});
	},
	
	showHelpAnswer: function (link) {
		if ($(link).siblings('.answer').length === 0) {
			link = $(link);
			link.after(' <img src="/images/ajax-loader-4a.gif" border="0" />');
			$.ajax({
				url: link.attr('href'),
				method: 'get',
				complete: function (req, textStatus) { link.siblings('img').remove(); },
				error: function (req, status ,error) { alert("Error, unknown question"); }, 
				success: function (response, status) {
					var answer = $('<div/>').addClass('answer').html(response).css({ display: 'none'});
					link.after(answer);
					answer.show('blind', {}, 'slow');
				}
			});
		} else {
			$(link).siblings('.answer').hide('blind', 'slow', function () { $(this).remove(); });
		}
		return false;
	},
	
	
	displayErrors: function (form, errorList, formError, dialog)	{
		form.find('.form-error, .field-error, .error-container').remove();
		form.find('.fieldWithErrors').removeClass('fieldWithErrors');
		var title = $('<' + formError.tag + '/>').addClass("form-error ui-state-error ui-corner-all").css({ display: 'none' });
		title.append($('<span/>').addClass('ui-icon ui-icon-alert')).append($('<p/>').html(formError.c));
		form[formError.pos == "append" ? "append" : "prepend"](title);
		title.fadeIn('slow');

		jQuery.each(errorList, function (id, error){
			var container, inputField;
			var fieldError = $('<' + 'div' + '/>')
			.addClass("field-error ui-state-highlight")
			.append($('<span/>')
			.addClass('ui-icon ui-icon-alert'))
			.append($('<span/>').addClass('error-message').html(error.c));
			var arrow = $("<div/>").addClass('field-error-arrow');
			for (var i = 10; i >= 1; i -= 1) {
				arrow.append($('<div/>').addClass('ui-state-highlight line' + i));
			}
			var wrappedError = $('<div/>').addClass('error-container').append(fieldError).append(arrow);
			
			if (error.container) {
				container = $(error.container);
				inputField = form.find('#' + id + " :input:visible");
			} else {
				container = form.find('#' + id + " .ui-slider").length > 0 ? form.find('#' + id + " .ui-slider").parent() : form.find('#' + id);
				inputField = container.find('fieldset').length > 0? container.find('fieldset') : container.find(':input:visible');
			}
			container.css({ position: 'relative' });
			container.append(wrappedError);
			
			var left = inputField.last().position().left + inputField.last().width() - 35,
				top = inputField.last().position().top - wrappedError.last().height() - 3,
				curParent = inputField.last().offsetParent();
			while (curParent[0] != container[0] && curParent[0].tagName != "BODY") {
				left += curParent.position().left;
				top += curParent.position().top;
				curParent = curParent.offsetParent(); 
			}
			wrappedError.css({ left: left + "px", top: top + "px"});
			inputField.addClass('fieldWithErrors');
			if (inputField.is('fieldset')){
				inputField.find(':input:visible').change(function(){ wrappedError.fadeOut().remove(); });
			} else {
				inputField.change(function(){ wrappedError.fadeOut('normal', function() { $(this).remove(); }); });
			}
			wrappedError.click(function() { wrappedError.fadeOut('normal', function() { $(this).remove(); }); });
		});
		if (dialog) {
			$('#dialog').remove();
			$('body').append($('<div/>').attr('id', 'dialog').css({ display: 'none' }).html("<h3>" + dialog.t + "</h3>" + dialog.c));
			$('#dialog').dialog({
				bgiframe: true,
				resizable: false,
				modal: true,
				width: 400,
				title: dialog.t,
				buttons: { 'Close': function() { $(this).dialog('close'); } }
			});
		}	
	},
	
	formFail: function (form, dialog) {
		form.find('.form-error, .field-error').remove();
		form.find('.fieldWithErrors').removeClass('fieldWithErrors');
		form.unbind('submit');
		form.bind('submit', function () { return false; });
		$('#dialog').remove();
		$('body').append($('<div/>').attr('id', 'dialog').css({ display: 'none' }).html("<h3>" + dialog.t + "</h3>" + dialog.c));
		$('#dialog').dialog({
			bgiframe: true,
			resizable: false,
			closeOnEscape: false, 
			modal: true,
			width: 400, 
			title: dialog.t,
			buttons: { 'Close': function() { $(this).dialog('close'); } }
		});	
		$('#dialog').bind('dialogclose', function(event, ui) { window.location.pathname = "/"; });
	},
	
	selectionDialog: function(form, title, text, options, type, destination, container) {
		$('#dialog').remove();
		var select = $('<select/>').attr('id', 'dialog_selection_input').css({ width: "95%" });
		for (var i =0; i < options.length; i += 1) {
			option = options[i];
			select.append($('<option/>').attr('value', option[0]).text(option[1]));
		}
		$('body').append($('<div/>').attr('id', 'dialog').css({ display: 'none' }).html("<h3>" + title + "</h3>" + text));
		$('#dialog').append(select.wrap($('<div/>')));
		$('#dialog').dialog({
			bgiframe: true,
			resizable: false,
			closeOnEscape: false, 
			modal: true,
			width: 400, 
			title: title,
			buttons: { 'Close': function() { $(this).dialog('close'); }, 'Select': function() { iWGC.updateFormFromSelection(select, type, destination, container); $(this).dialog('close'); } }
		});	
	},
	
	skipValidationDialog: function(form, title, text, button_list, inputs) {
		$('#dialog').remove();
		$('body').append($('<div/>').attr('id', 'dialog').css({ display: 'none' }).html("<h3>" + title + "</h3>" + text));
		var button_obj = {};
		button_obj[button_list['no']] = function() { iWGC.addBypassElements(form, inputs); $(this).dialog('close'); };
		button_obj[button_list['yes']] =  function() { $(this).dialog('close'); };
		$('#dialog').dialog({
			bgiframe: true,
			resizable: false,
			closeOnEscape: false, 
			modal: true,
			width: 400, 
			title: title,
			buttons: button_obj 
		});
	},
	
	updateFormFromSelection: function (select, type, destination, container) {
		var option = select.find('option:selected');
		for (var i=0; i < destination[0].length; i += 1) { $(destination[0][i]).val(option.val()); }
		for (var j=0; j < destination[1].length; j += 1) { 
			$(destination[1][j]).val(option.text());
			$(destination[1][j]).data('autocomplete', { id: option.val(), type: type, value: option.text() });
		}
		$(container + ' .error-container').remove();
		$(container + ' .fieldWithErrors').removeClass('fieldWithErrors');	
	},
	
	addBypassElements: function(form, inputs) {
		for (var i=0; i<inputs.length; i+=1) {
			form.append($('<input/>').attr({ 'type': 'hidden', 'id': inputs[i][0], 'name': inputs[i][1], 'value': 'false' }));
		}
		form.find('.form-error, .field-error, .error-container').remove();
		form.find('.fieldWithErrors').removeClass('fieldWithErrors');
		form.submit();
	},
	
	replaceResults: function (link, options) {
		$(options.container).elementLoadingToggle();
		$.ajax({
			url: link,
			method: 'get',
			dataType: 'json',
			complete: function (req, textStatus) { $(options.container).elementLoadingToggle(); },
			error: function (req, status ,error) { alert("Sorry we could not load the page you requested. Please try again."); }, 
			success: function (response, status) {
				var url = response.url;
				var pages = response.pagination;
				if ($('.pagination').length > 0) {
					$('.pagination').empty();
					jQuery.each(pages.pages, function () { $('.pagination').append(iWGC.paginationElement(url, this)).append(" "); });
					$('.pagination').prepend(" ").prepend(iWGC.paginationElement(url, pages.prev))
						.prepend(" ").prepend(iWGC.paginationElement(url, pages.first))
						.append(iWGC.paginationElement(url, pages.next)).append(" ")
						.append(iWGC.paginationElement(url, pages.last)).append(" ");
					$('.pagination a').ajaxPaginate({ container: options.container, replace: options.replace });
				} else {
					$(options.container).prepend('<div class="temp"/>');
				}
				$("#resultCountDiv .first").html(pages.first_record);
				$("#resultCountDiv .last").html(pages.last_record);
				var prevSibling = $(options.container + " " + options.replace + ":first").prev();
				$(options.container + " " + options.replace).remove(':not(#resultEntityNew)');
				for (var i = response.records.length -1 ; i >= 0; i -= 1) {
					prevSibling.after(response.records[i]);
				}
				$(options.container + ' div.temp').remove();
				if (response.map) {
					var map = $('#' + response.map).data('map');
					map.resetLocations(response.locations);
				}
				if (options.successFunction) {
					options.successFunction();
				}
			}
		});
	},
	
	paginationElement: function (url, data) {
		var el = $("<" + data[0] + "/>").html(data[1]);
		if (data[2]) {
			if (/^.+\?.*$/.test(url)) {
				el.attr('href', url + "&page=" + data[2]);
			} else {
				el.attr('href', url + "?page=" + data[2]);
			} 
		}
		if (data[3]) { el.addClass(data[3]); }
		return el;
	},
	
	loadGMaps: function () {
		if (typeof(google.maps) == "undefined") {
			google.load("maps", 2, { callback: iWGC.loadGMaps });
		} else {
			if (google.maps.BrowserIsCompatible()) {
				$('.toGmap').each(function(){
					map = new Mapping(this, mapDataJSON);
					map.setMap();
					$(this).data('map', map);
				});
			}
		}
	},
	
	highlightSearchResult: function(type,id) {
		window.scrollTo(0, $('#result' + type + id).offset().top - 200);
		$('#result' + type + id).effect('highlight');
	},
	
	addSwapoverElement: function(html, elSelector) {
		var afterEl = $(elSelector);
		afterEl.css({ display: 'inline' }).find(':input').removeAttr('disabled');
		var newEl = $(html);
		newEl.css({ display: 'none' }).find(':input').attr('disabled', 'disabled');
		afterEl.after(newEl);
		afterEl.find('a').bind('click', function (e) { 
			afterEl.css({ display: 'none' }).find(':input').attr('disabled', 'disabled'); 
			newEl.css({ display: 'inline' }).find(':input').removeAttr('disabled'); 
			return false; 
		});
		newEl.find('a').bind('click', function (e) { 
			newEl.css({ display: 'none' }).find(':input').attr('disabled', 'disabled'); 
			afterEl.css({ display: 'inline' }).find(':input').removeAttr('disabled'); 
			return false;
		});
		afterEl.find('input.setAutoComplete').setAutoComplete('ac_results_small');
		newEl.find('input.setAutoComplete').setAutoComplete('ac_results_small');
	},
	
	newSuggestionToggle: function(el) {
		var form = el.find('form');
		if (!el.hasClass('show')) {
			el.addClass('blueBg');
			form.css({ display: 'none' });
		}
		el.find('h2').prepend('<div class="expand">+</div>')
		.hover(
			function() { $(this).addClass('hover'); }, 
			function() { $(this).removeClass('hover'); }
		)
		.toggle(
			function() { form.show('blind', {}, 1000); el.removeClass('blueBg', 1000).find('h2 div').html("&ndash;");  },
			function() { form.hide('blind', {}, 1000); el.addClass('blueBg', 1000).find('h2 div').html("+"); }
		);		
	},
	
	liveSearchSetup: function() {
		$('#changeSearch form').submit(function (event) { 
			var request = $(event.target).attr('action') + "?" + $(event.target).serialize(); 
			iWGC.replaceResults(request, { 
				container: '#searchResults', 
				replace: '.search-result', 
				successFunction: function () { $('div.search-result a.toButton').linkToButton('ui-state-active'); } 
			});
			return false; 
		});
		$('#changeSearch select').change(function() { $('#changeSearch form').submit(); } );
	},
	
	documentReady: function(){
		if ((/^#\/home\/\w+_search$/).test(window.location.hash)) {
			iWGC.loadSearchBox(window.location.hash.substring(1));
		} else {
			$('#searchForm').setupSearchBox();
		}
		$('#searchRefine').setupSearchBox();
		
		$('.toTabs').parseToTabs();
		$('.bindPopup').addPopup();
		$('.autoShorten').autoShorten();
		$('form .radio-checkboxes').bindRadioFunction();
		$('#reviews .pagination a').ajaxPaginate({ container: '#reviews', replace: '.review' });
		$('#multiLocationsList + div img').staticMapToGMap();
		
		if ($('#new_doctor').length > 0 || $('.edit-entity').length > 0 || $('.dynamic-form').length > 0) 
		{
			$('#new_doctor input:text, .edit-entity input:text, .dynamic-form input:text').setTextSuggestion();
			$('#new_doctor input.setAutoComplete, .edit-entity input.setAutoComplete, .dynamic-form input.setAutoComplete').setAutoComplete('ac_results_small');
			/* setup autocomplete first otherwise ajax form binds first to form */
		}
		
		if ($('#searchResults').length > 0) {
			$('#searchResults .pagination a').ajaxPaginate({ container: '#searchResults', replace: '.search-result', successFunction: function () { $('div.search-result a.toButton').linkToButton('ui-state-active'); } });
			$('div.search-result a.toButton').linkToButton('ui-state-active');
			iWGC.liveSearchSetup();
			$('#searchResults #new_doctor').fadeLabels().ajaxForm(); /* revise to form.new-entity when all forms updated */
		}
		
		if ($('.toGmap').length > 0) { iWGC.loadGMaps(); }
		
		if ($('#rarForm').length > 0) {
			$('#rarForm div.rating').addSliders();
			$('#rarForm input:text, #rarForm textarea').setTextSuggestion();
			$('#rarForm textarea').resizableTextarea();
			$('#rarForm').ajaxForm();
		}
		
		if ($('#newSuggestion').length > 0) {
			$('#newSuggestion textarea').setTextSuggestion();
			iWGC.newSuggestionToggle($('#newSuggestion'));
		}
	}
};

jQuery.fn.setupSearchBox = function() {
	return this.each(function() {
		var form = $(this);
		form.find('input.setAutoComplete').setAutoComplete();
		form.find('input:text').setTextSuggestion();
		$('#searchSelector a').each(function() { $(this).bind('click', function() { iWGC.loadSearchBox($(this).attr('href')); return false; }); });
	});
};

jQuery.fn.bindRadioFunction = function() {
	return this.each(function () {
		var container = $(this);
		container.find(':checkbox').bind('click', function() {
			if ($(this).attr('checked') == true) {
				container.find(':checked').not("#" + $(this).attr('id')).each(function() {
					$(this).removeAttr('checked'); 
				});
			}
		});
	});
};

jQuery.fn.setTextSuggestion = function() {
	return this.each(function() {
		if (typeof(defaultText) != 'undefined' && defaultText[this.id] && ($(this).val() == "" || $(this).val() == defaultText[this.id])) {
			$(this).val(defaultText[this.id]);
			var input = $(this);
			input.data('defaultText', input.val());
			input.addClass('defaultText');
			input.bind('focus', function(e){
				if (this.value == input.data('defaultText')) {
					$(this).val('').removeClass('defaultText');
				}
			});
			input.bind('blur', function(e){
				if (this.value == '') {
					$(this).addClass('defaultText').val($(this).data('defaultText'));
				}
			});
			var form = input.parents('form:first');
			if (!form.data('clearSuggestionBound')) {
				form.data('clearSuggestionBound', true);
				form.unbind('submit.clearSuggestion').bind('submit.clearSuggestion', function(){
					$(this).find('input:text, textarea').clearSuggestion();
				});
			}
			if (input.hasClass('setAutoComplete') || input.hasClass('isAutoCompleted')) {
				if (typeof(linkedInput) != 'undefined' && linkedInput[input.attr('id')] && typeof(linkedInput[input.attr('id')]) == "object") {
					for (var dest in linkedInput[input.attr('id')])	{
						$('#' + linkedInput[input.attr('id')][dest]).val("");
					}
				}
			}
		}
	});
};

jQuery.fn.clearSuggestion = function () {
	return this.each(function() {
		if (typeof(defaultText) != 'undefined' && defaultText[this.id] && $(this).val() == defaultText[this.id]) {
			$(this).val("");
		}
	});
};

jQuery.fn.resetSuggestion = function() {
	return this.each(function() {
		if (typeof(defaultText) != 'undefined' && defaultText[this.id] && $(this).val() == "") {
			$(this).val(defaultText[this.id]);
		}
	});
};

jQuery.fn.parseToTabs = function() {
	return this.each(function() {
		var parent = $(this);
		$('h3', this).each(function (i) {
			var curId = parent.attr('id') + '_tab_' + i;
			$(this).html('<a href="#'+ curId + '">' + $(this).html() + '</a>');
		});
		$('div.content', this).removeClass('content');
		parent.accordion({ header: 'h3', autoHeight: false });
		parent.removeClass('toTabs');
	});
};

jQuery.fn.elementLoadingToggle = function(text) {
	text = text || "Loading";
	return this.each(function() {
		var el = $(this);
		if (el.find('.loading').length > 0) {
			el.find('.loading, .loading-overlay').fadeOut("normal", function () { $(this).remove(); } ); 
		} else {
			if (el.css('position') == 'static') { el.css('position', 'relative'); }
			var overlay = $('<div/>').addClass('loading-overlay').css({ display: 'none', height: el.innerHeight() + 'px', width: el.innerWidth() + 'px' });
			var loading = $('<div/>').addClass('loading').css({ display: 'none' }).html(text);
			el.append(overlay).append(loading);
			if (jQuery.support.opacity) {
				overlay.fadeIn("normal");
			} else {
				overlay.css({ opacity: 0, display: '' }).bgIframe();
				overlay.fadeTo("normal", 0.40);
			}
			loading.css({top: Math.round((el.outerHeight() - loading.outerHeight()) / 2) + "px", left: Math.round((el.outerWidth() - loading.outerWidth()) / 2) + "px"}).fadeIn("normal");
		}
	});
};

jQuery.fn.addSliders = function() {
	return this.each(function() {
		var infoDiv = $(this).find('.rating-info');
		var minText = infoDiv.find('span.min-text').addClass('description').remove();
		var maxText = infoDiv.find('span.max-text').addClass('description').remove();
		infoDiv.css({ 'float': 'none' }).find('div').remove();
		$(this).find('.rating-input').removeClass('rating-input').addClass('value').wrap($('<div/>').addClass('rating-input'));
		var input = $(this).find('input').addClass('slider').val("--").bind('blur', function() {
			var value = parseInt($(this).val(), 10);
			var slider = $(this).parent().parent().find('div.ui-slider');
			if (value && value >= slider.slider('option', 'min') && value <= slider.slider('option', 'max')) {
				slider.slider('value', $(this).val());	
			} else {
				$(this).val(slider.slider('value'));
			}
		});
		$(this).find('div.rating-input').prepend($('<div/>').slider({ value: 50, range: 'min', animate: true, slide: function(e,ui) { input.val(ui.value); } }));
		$(this).find('div.ui-slider').before(minText).after(maxText);
	});
};

jQuery.fn.linkToButton = function(defaultClass) {
	defaultClass = defaultClass || 'ui-state-default';
	return this.each(function () {
		if (this.tagName == "A") {
			var buttonName = $(this).attr('title') || $(this).text(),
				method = $(this).hasClass('post') ? 'POST' : 'GET',
				link = $(this).attr('href'),
				button = $('<button type="button"></button>')
			.addClass(defaultClass + ' ui-corner-all fromLink')
			.text(buttonName)
			.hover(function() { $(this).addClass('ui-state-hover'); $(this).removeClass(defaultClass); }, function() { $(this).removeClass('ui-state-hover'); $(this).addClass(defaultClass); })
			.focus(function() {	$(this).addClass('ui-state-focus');	$(this).removeClass(defaultClass);})
			.blur(function() { $(this).removeClass('ui-state-focus'); $(this).addClass(defaultClass); });
			$(this).replaceWith(button);
			if (method == "POST") {
				button.after($('<form/>').css({ display: 'none' }).attr({ 'method': method, action: link }));
				button.click(function() {
					$(this).next().submit();
				});
			} else {
				button.click(function() { 
					if (jQuery.support.hrefNormalized) { window.location.href = window.location.protocol + "//" + window.location.host + link; }
					else { window.location.href = link;	}
				});
			}
		}
	});
};

jQuery.fn.autoShorten = function() {
	return this.each(function(){
		if ($(this).text().length > 100) {
			var words = $(this).text().substring(0,100).split(" ");
			var shortText = words.slice(0, words.length - 1).join(" ") + "...";
			$(this).data('replacementText', $(this).text())
			.text(shortText)
			.css({ cursor: 'pointer' })
			.hover(function() { $(this).css({ textDecoration: 'underline' }); }, function() { $(this).css({ textDecoration: 'none' }); })
			.click(function() { var tempText = $(this).text(); $(this).text($(this).data('replacementText')); $(this).data('replacementText', tempText); });
		}
	});
};

jQuery.fn.addPopup = function() {
	return this.each(function () {
		if (this.tagName == "A") {
			$(this).bind('click', function () {
				$('#dialog').remove();
				$('body').append($('<div/>').attr('id', 'dialog').css({ display: 'none' }).html('<div style="text-align: center"><img src="/images/ajax-loader-3.gif" border="0" style="padding-top: 20px" /></div>'));
				$('#dialog').dialog({
					bgiframe: true,
					resizable: false, 
					title: 'Loading ...',
					buttons: { 'Close': function() { $(this).dialog('close'); } }
				});
				$.ajax({ 
					url: this.href,
					type: 'get',
					dataType: 'json',
					error: function (req, status, error) {
						$('#dialog').html("Sorry, we can't load the page you requested. Please close this popup and try again.");
					},
					success: function(response, status) {
						var dialog = $('#dialog');
						dialog.dialog('option', 'title', response.title).html(response.content);
						if (response.width) {
							dialog.dialog('option', 'width', response.width);
							dialog.dialog('option', 'position', 'center');
						}
						var popupForm = dialog.find('form')[0];
						if (popupForm) {
							var buttons = dialog.dialog('option', 'buttons');
							$(popupForm).find(':submit').each( function() {
								buttons[$(this).val()] = function() { $(popupForm).submit(); };
								$(this).remove();
								dialog.dialog('option', 'buttons', buttons);
							});
							$(popupForm).ajaxDialog();
						}
					}
					
				});
				return false;
			});
		}
	});
};

jQuery.fn.ajaxDialog = function () {
	return this.each(function () {
		if (this.tagName == "FORM") {
			$(this).bind('submit', function () {
				var form = $(this);
				if (form.attr('disabled') != "disabled") {
					form.attr("disabled", "disabled");
					form.parent().elementLoadingToggle('Saving');
					$.ajax({
						url: this.action,
						type: this.method,
						dataType: 'json',
						data: $(this).serialize(),
						error: function (req, status, error) {
							alert("Sorry, we can't load the page you requested. Please try again.");
							form.removeAttr("disabled");
							form.parent().elementLoadingToggle();
						},
						success: function (response, status) {
							form.removeAttr("disabled");
							form.parent().elementLoadingToggle();
							var dialog = $('#dialog');
							dialog.html(response.content);
							var buttons = {};
							jQuery.each(dialog.dialog('option', 'buttons'), function (k, v) { 
								if (k == "Close") { buttons[k] = v; } 
							});
							var popupForm = dialog.find('form')[0];
							if (popupForm) {
								$(popupForm).find(':submit').each( function() {
									buttons[$(this).val()] = function() { $(popupForm).submit(); };
									$(this).remove();
								});
								$(popupForm).ajaxDialog();
							}
							dialog.dialog('option', 'buttons', buttons);
						}
					});
				}
				return false;
			});
		}
	});
};

jQuery.fn.ajaxForm = function () {
	return this.each(function () {
		if (this.tagName == "FORM") {
			$(this).bind('submit', function () {
				var form = $(this);
				if (form.attr('disabled') != "disabled") {
					var postData = $(this).serialize();
					iWGC.disableForm(form);
					$.ajax({
						url: this.action,
						type: this.method,
						dataType: 'json',
						data: postData,
						complete: function (req, status) { 
							iWGC.enableForm(form);
							form.find('input:text, textarea').resetSuggestion(); 
						}, 
						error: function (req, status, error) {
							alert("Sorry, we can't find the page you requested. Please try again.");
						},
						success: function (response, status) {
							if (response.status && response.status == "OK")	{
								iWGC.overlayDocument(response.content, { modal : true, shadow: true, width: response.width });
							} else if (response.status && response.status == "REDIRECT") {
								$(form).parent().elementLoadingToggle();
								window.location.pathname = response.location;
							} else if (response.status && response.status == "STOP") {
								iWGC.formFail(form, response.dialog);
							} else if (response.status && response.status == "SELECT") {
								iWGC.selectionDialog(form, response.title, response.text, response.options, response.type, response.destination, response.container);
							} else if (response.status && response.status == "SKIP_VALIDATION") {
								iWGC.skipValidationDialog(form, response.title, response.text, response.buttons, response.inputs);
							} else if (response.status && response.status == "ERROR") {
								iWGC.displayErrors(form, response.errors, response.formError, response.dialog);
								/* if the form is within a #customOverlay then check for a shadow and resize it */
								if (form.parents('#overlayDiv').length > 0) {
									var overlayDoc = form.parents('#overlayDiv');
									$('.ui-widget-shadow').css({ width: overlayDoc.outerWidth() + "px", height: overlayDoc.outerHeight() + "px" });
								}
							}
						}
					});
				}
				return false;
			});
		}
	});
			
};

jQuery.fn.ajaxPaginate = function(options) {
	return this.each(function () {
		if (this.tagName == "A") {
			$(this).bind('click', function(){
				iWGC.replaceResults($(this).attr('href'), options);
				return false;
			});
		}
	});
};

jQuery.fn.staticMapToGMap = function () {
	return this.each(function () {
		var image = $(this);
		image.replaceWith($('<div/>').css({ width: image.width() + "px", height: image.height() + "px" }).addClass('toGmap').attr('id', 'locationGMap'));
	});
};

jQuery.fn.resizableTextarea = function() {
	return this.each(function () {
		var height = $(this).height();
		$(this).resizable({ handles: 's', minHeight: height });
	});
};

jQuery.fn.setAutoComplete = function(acClass) {
	acClass = acClass || "ac_results";
	return this.each(function () {
		$(this).autocomplete(url[this.id], { 
			dataType: 'json', 
			parse: function (data) {
				var parsed = [];
				for (var i = 0; i < data.length; i += 1) {
					var row = data[i];
					parsed[parsed.length] = { data: row, value: row[1], result: row[1] };
				}
				return parsed; 
			},
			formatItem: function(row) { 
				var text = row[2] ? row[1] + " (" + row[2] + ")" : row[1];
				if (row[3] == "doctor_location") {
					return "<span class=\"alternate\">" + text + "</span>";
				} else {
					return text;
				}
			},
			resultsClass: acClass,
			formatMatch: function(row) { return row[1]; },
			matchContains: true,
			minChars: 3,
			scrollHeight: 280
		}).result(function(e, data, value) {
			if ($(this).data('autocomplete')) {
				$("#" + $(this).attr('id') + "_" + $(this).data('autocomplete').type + "_id").val("");
			}
			$("#" + $(this).attr('id') + "_" + data[3] + "_id").val(data[0]);
			$(this).data('autocomplete', { id: data[0], value: data[1], type: data[3] });
		});
		if (typeof(extraParams) !== "undefined" && typeof(extraParams[this.id]) !== "undefined")
		{
			var id = this.id;
			var params = {};
			params[$(extraParams[this.id]).attr('name')] = function () { return $(extraParams[id]).val(); }; 
			$(this).setOptions({ extraParams: params });
			$(extraParams[this.id]).bind('change', function (){ $('#' + id).flushCache(); });
		}
		
		$(this).removeClass('setAutoComplete');
		$(this).addClass('isAutoCompleted');
		var form = $(this).parents('form:first');
		if (!form.data('autocompleteCheckBound')) {
			form.data('autocompleteCheckBound', true);
			form.unbind('submit.autocompleteCheck').bind('submit.autocompleteCheck', function(){
				$(this).find('input.isAutoCompleted').checkAutoComplete();
			});
		}
	});
};

jQuery.fn.checkAutoComplete = function() {
	return this.each(function() {
		var input = $(this);
		if (input.data('autocomplete')) {
			var data = input.data('autocomplete');
			if (input.val() != data.value) {
				$("#" + input.attr('id') + "_" + data.type + "_id").val("");
			}
		}
	});
};

jQuery.fn.fadeLabels = function() {
	return this.each(function() {
		var form = $(this);
		$(form).find(':input').each(function() {
			var label = form.find("label[for='" + $(this).attr('id') + "']");
			if (label.length > 0) {
				label.css({ opacity: 0, filter: 'Alpha(Opacity=0)' });
				$(this).focusin(function() { label.animate({opacity: 1, filter: 'Alpha(Opacity=100)' }); })
				.focusout(function() { label.animate({ opacity: 0, filter: 'Alpha(Opacity=0)' }); });
			}
		});
	});
};

$(document).ready(function() { iWGC.documentReady(); });