﻿/*!
* tg.mapSearch.js
* ===========================================
* Copyright (c) 2011 Bauer Consumer Media Ltd
* -------------------------------------------
*/

var mapSearch = {
	id: null,
	map: null,
	settings: null,

	cons: {
		maxResults: 75,
		maxSuggestions: 15,
		minSuggestChars: 3,
		zoomCity: 10,
		zoomCounty: 9,
		zoomCountry: 6,
		zoomCourse: 14,
		zoomLocal: 8,
		zoomPostcode: 12
	},
	markers: {
		flag: {
			image: {
				file: '/shared/images/markers/flag.{0}.{1}.png',
				point: [0, 30],
				size: [20, 30]
			},
			shadow: {
				file: '/shared/images/markers/flag.{0}.shadow.png',
				point: [0, 30],
				size: [38, 30]
			},
			shape: {
				coord: [2, 0, 18, 1, 19, 2, 19, 3, 19, 4, 19, 5, 19, 6, 19, 7, 19, 8, 19, 9, 19, 10, 19, 11, 19, 12, 19, 13, 19, 14, 18, 15, 2, 16, 2, 17, 2, 18, 2, 19, 2, 20, 2, 21, 2, 22, 2, 23, 2, 24, 2, 25, 2, 26, 2, 27, 2, 28, 2, 29, 0, 29, 0, 28, 0, 27, 0, 26, 0, 25, 0, 24, 0, 23, 0, 22, 0, 21, 0, 20, 0, 19, 0, 18, 0, 17, 0, 16, 0, 15, 0, 14, 0, 13, 0, 12, 0, 11, 0, 10, 0, 9, 0, 8, 0, 7, 0, 6, 0, 5, 0, 4, 0, 3, 0, 2, 0, 1, 0, 0, 2, 0],
				type: 'poly'
			}
		},
		pin: {
			image: {
				file: '/shared/images/markers/pin.png',
				point: [0, 30],
				size: [16, 30]
			},
			shadow: {
				file: '/shared/images/markers/pin.shadow.png',
				point: [0, 30],
				size: [34, 30]
			},
			shape: {
				coord: [5, 0, 7, 1, 8, 2, 10, 3, 12, 4, 14, 5, 15, 6, 15, 7, 15, 8, 13, 9, 12, 10, 10, 11, 8, 12, 6, 13, 4, 14, 2, 15, 2, 16, 2, 17, 2, 18, 2, 19, 2, 20, 2, 21, 2, 22, 2, 23, 2, 24, 2, 25, 2, 26, 2, 27, 2, 28, 2, 29, 0, 29, 0, 28, 0, 27, 0, 26, 0, 25, 0, 24, 0, 23, 0, 22, 0, 21, 0, 20, 0, 19, 0, 18, 0, 17, 0, 16, 0, 15, 0, 14, 0, 13, 0, 12, 0, 11, 0, 10, 0, 9, 0, 8, 0, 7, 0, 6, 0, 5, 0, 4, 0, 3, 0, 2, 0, 1, 0, 0, 5, 0],
				type: 'poly'
			}
		}
	},
	text: {
		noInput: 'Please enter either a course name or location to search for.',
		noMatches: 'No matches found',
		noMatchingCourse: 'Sorry, we couldn\'t find a course matching your search. Please check your spelling and try again.',
		noMatchingLocation: 'Sorry, we couldn\'t find a location matching your search. Please check your spelling and try again.'
	},
	vars: {
		busy: false,
		dragged: false,
		infoOpen: [],
		infoWindows: [],
		localized: false,
		markers: [],
		resultsCallbackCount: 0,
		resultsLoaded: false,
		resultsSort: 'Passthrough',
		resultsSortChanged: false,
		state: 'ok',
		zoomed: false,
		zoomLevel: 6
	},

	init: function (settings) {
		mapSearch.id = mapSearch.id || settings.clientIds.mapCanvas;
		mapSearch.settings = mapSearch.settings || settings;
		var tb, cids = mapSearch.settings.clientIds;

		if (cids.txtCourseName && (tb = $('#' + cids.container + ' #' + cids.txtCourseName)).length > 0) {
			bui.forms.autoSuggest.load(tb, {
				highlightFirst: true,
				highlightPhrase: true,
				minChars: 1,
				noMatchText: mapSearch.text.noMatches,
				onSelect: mapSearch.courseSelect,
				onSuggest: mapSearch.courseSuggest
			});
		}
		if (cids.txtLocation && (tb = $('#' + cids.container + ' #' + cids.txtLocation)).length > 0) {
			bui.forms.autoSuggest.load(tb, {
				highlightFirst: true,
				highlightPhrase: true,
				minChars: 1,
				noMatchText: mapSearch.text.noMatches,
				onSelect: mapSearch.locationSelect,
				onSuggest: mapSearch.locationSuggest
			});
		}
		$('#' + cids.container + ' .' + cids.regionClass).attr('autocomplete', 'off');
		$('#' + cids.container + ' #' + cids.hidLatLong).attr('autocomplete', 'off');
		$('#' + cids.container + ' #' + cids.hidSearch).attr('autocomplete', 'off');
		$('#' + cids.container + ' #' + cids.hidZoom).attr('autocomplete', 'off');
		$('#' + cids.container + ' #' + cids.btnFind).click(mapSearch.findClick);

		var region = bui.query.get(mapSearch.settings.keys.region);
		if (region) {
			mapSearch.setRegion(region);
		} else {
			mapSearch.setRegion('uk');
		}

		mapSearch.map = bui.googleApi.maps.loadMap(mapSearch.id, settings.mapOptions, mapSearch.onLoad, mapSearch.onZoom, mapSearch.onDrag, mapSearch.onClick);
		if (cids.mapStreetView) {
			var msv = $('#' + cids.container + ' #' + cids.mapStreetView);
			bui.googleApi.maps.loadStreetView(msv, mapSearch.map);
		}
	},

	addCourseMarkers: function (courses) {
		mapSearch.clearMarkers(true);
		mapSearch.closeInfoWindows(true);

		if (courses && courses.GolfCourses) {
			var i;
			for (i = 0; i < courses.GolfCourses.length; i++) {
				var index = i + 1;
				var course = courses.GolfCourses[i];
				var center = mapSearch.map.getCenter();
				var latLong = bui.googleApi.maps.latLong(course.Geocode);

				var mo = {
					map: mapSearch.map,
					position: latLong,
					title: course.CourseName,
					zIndex: courses.GolfCourses.length - index
				};
				if (mapSearch.vars.localized || mapSearch.vars.zoomLevel >= mapSearch.cons.zoomLocal) {
					var color = mapSearch.getFlagColor(course.TwoForOne, course.TeeTimes);
					mo.icon = mapSearch.generateMarker(mapSearch.markers.flag.image, color, index);
					mo.shadow = mapSearch.generateMarker(mapSearch.markers.flag.shadow, color);
					mo.shape = mapSearch.markers.flag.shape;
				} else {
					mo.icon = mapSearch.generateMarker(mapSearch.markers.pin.image);
					mo.shadow = mapSearch.generateMarker(mapSearch.markers.pin.shadow);
					mo.shape = mapSearch.markers.pin.shape;
				}
				var marker = new google.maps.Marker(mo);
				google.maps.event.addListener(marker, 'click', function () {
					mapSearch.openInfoWindow(this);
				});
				mapSearch.vars.markers[course.PageId] = marker;

				var details = '<div class="mapSearchCourseInfo">';
				details += '<h6 class="title">';
				if (mapSearch.vars.localized || mapSearch.vars.zoomLevel >= mapSearch.cons.zoomLocal) {
					details += '<span class="index">' + index + '.</span> ';
				}
				details += course.CourseName + '</h6>';
				details += '<div class="address">' + course.Address + '</div>';
				details += '<div class="link"><a href="' + course.ReviewUrl + '">View full details</a></div>';
				details += '</div>';

				var infoWin = new google.maps.InfoWindow({
					content: details
				});
				google.maps.event.addListener(infoWin, 'closeclick', function () {
					mapSearch.vars.infoOpen = [];
				});
				mapSearch.vars.infoWindows[course.PageId] = infoWin;

				if (mapSearch.vars.infoOpen.length === 0 && course.Geocode === (center.lat() + ',' + center.lng())) {
					mapSearch.openInfoWindow(marker);
				}

				if (mapSearch.vars.resultsLoaded) {
					mapSearch.updateMarkers();
				}
			}
		}
	},

	clearCache: function () {
		var cids = mapSearch.settings.clientIds;
		$('#' + cids.container + ' #' + cids.hidLatLong).val('');
		$('#' + cids.container + ' #' + cids.hidSearch).val('');
		$('#' + cids.container + ' #' + cids.hidZoom).val('');
	},

	clearMarkers: function (reset) {
		var m;
		for (m in mapSearch.vars.markers) {
			mapSearch.vars.markers[m].setMap(null);
		}
		if (reset) {
			mapSearch.vars.markers = [];
		}
	},

	closeInfoWindows: function (reset) {
		var w;
		for (w in mapSearch.vars.infoWindows) {
			mapSearch.vars.infoWindows[w].close();
		}
		mapSearch.vars.infoOpen = [];
		if (reset) {
			mapSearch.vars.infoWindows = [];
		}
	},

	courseSelect: function (tb, text, value) {
		var cids = mapSearch.settings.clientIds;

		$('#' + cids.container + ' #' + cids.hidSearch).val(text);
		if (text !== '') {
			mapSearch.vars.localized = true;
			mapSearch.loadPoint(value, mapSearch.cons.zoomCourse);
		} else {
			mapSearch.setStatus(mapSearch.text.noMatchingCourse, 'error');
		}
	},

	courseSuggest: function (tb) {
		var cids = mapSearch.settings.clientIds;
		$('#' + cids.container + ' #' + cids.txtLocation).val('');

		var val = tb.val().trim();
		if (val.length >= mapSearch.cons.minSuggestChars) {
			bui.json.fetch(mapSearch.settings.urls.courseProvider, {
				maxresults: mapSearch.cons.maxSuggestions,
				method: 'all',
				phrase: val,
				region: mapSearch.getRegion()
			}, function (data) {
				if (data && data.GolfCourses) {
					var i, m = [];
					for (i = 0; i < data.GolfCourses.length; i++) {
						m.push({ text: data.GolfCourses[i].CourseName, value: data.GolfCourses[i].Geocode });
						if (m.length === mapSearch.cons.maxSuggestions) { break; }
					}
					bui.forms.autoSuggest.showMatches(tb, m);
				}
			});
		} else {
			bui.forms.autoSuggest.hideMatches(tb);
		}
	},

	enableScrollwheel: function () {
		if (!mapSearch.settings.mapOptions.scrollwheel) {
			mapSearch.map.setOptions({ scrollwheel: true });
			mapSearch.settings.mapOptions.scrollwheel = true;
		}
	},

	fetchCourses: function (params) {
		mapSearch.vars.resultsLoaded = false;
		bui.json.fetch(mapSearch.settings.urls.courseProvider, params, function (data) {
			mapSearch.addCourseMarkers(data);
		});
	},

	findClick: function (e) {
		e.preventDefault();
		var cids = mapSearch.settings.clientIds;
		var cn = $('#' + cids.container + ' #' + cids.txtCourseName);
		var loc = $('#' + cids.container + ' #' + cids.txtLocation);
		var hp = $('#' + cids.container + ' #' + cids.hidLatLong);
		var hs = $('#' + cids.container + ' #' + cids.hidSearch);
		var hz = $('#' + cids.container + ' #' + cids.hidZoom);

		if (hs.val() !== cn.val() && hs.val() !== loc.val()) {
			mapSearch.clearCache();
		}

		if (mapSearch.settings.urls.resultsTarget !== '' && hp.val() !== '') {
			var keys = mapSearch.settings.keys;
			var region = mapSearch.getRegion();

			bui.window.redirect(mapSearch.settings.urls.resultsTarget, [
				[keys.course, cn.val()],
				[keys.latLong, hp.val()],
				[keys.location, loc.val()],
				[keys.region, region],
				[keys.zoom, hz.val()]
			], [keys.course, keys.latLong, keys.location]);
		} else if (cn.val() !== '') {
			mapSearch.loadCourse(cn.val());
		} else if (loc.val() !== '') {
			mapSearch.loadLocation(loc.val());
		} else {
			mapSearch.setStatus(mapSearch.text.noInput, 'warning');
		}
	},

	generateMarker: function (spec, color, index) {
		if (color) {
			spec = bui.clone(spec);
			spec.file = bui.string.format(spec.file, color, index !== null ? bui.string.pad(index, 2) : null);
		}
		return new google.maps.MarkerImage(
			spec.file,
			new google.maps.Size(spec.size[0], spec.size[1]),
			new google.maps.Point(0, 0),
			new google.maps.Point(spec.point[0], spec.point[1])
		);
	},

	getCourses: function () {
		if (!mapSearch.vars.busy) {
			mapSearch.clearMarkers();
			mapSearch.closeInfoWindows();
			mapSearch.setStatus();

			var cids = mapSearch.settings.clientIds;
			var region = mapSearch.getRegion();
			var center = mapSearch.map.getCenter();

			if (mapSearch.vars.localized || mapSearch.vars.zoomLevel >= mapSearch.cons.zoomLocal) {
				var radius = bui.googleApi.maps.getRadius(center, mapSearch.map.getBounds()) || 1;
				mapSearch.fetchCourses({
					method: 'md',
					midpoint: center.lat() + ',' + center.lng(),
					distance: radius,
					sort: mapSearch.vars.resultsSort,
					maxcount: mapSearch.cons.maxResults
				});
				$('#' + cids.mapKey + ':hidden').slideDown('fast');
			} else {
				var data = mapSearch.getRegionData(region);
				if (data) {
					mapSearch.fetchCourses({
						method: region,
						midpoint: center.lat() + ',' + center.lng(),
						maxcount: data.maxCourses
					});
				}
				$('#' + cids.mapKey + ':visible').slideUp('fast');
			}
			mapSearch.loadSearchResults();
		}
	},

	getFlagColor: function (twoForOne, teeTimes) {
		var twoForOne = String(twoForOne).toLowerCase() === 'true';
		var teeTimes = String(teeTimes).toLowerCase() === 'true';
		var color = 'red';

		if (twoForOne && teeTimes) {
			color = 'yellow';
		} else if (twoForOne) {
			color = 'green';
		} else if (teeTimes) {
			color = 'blue';
		}

		return color;
	},

	getGeocodeRegion: function (result) {
		var i;
		for (i = 0; i < result.address_components.length; i++) {
			var ac = result.address_components[i];
			if (bui.utils.inArray(ac.types, 'country')) {
				if (ac.short_name === 'GB') {
					return 'uk';
				} else if (bui.utils.inArray(bui.googleApi.maps.countryCodes.europe, ac.short_name)) {
					return 'europe';
				} else {
					return 'rotw';
				}
			}
		}
		return 'uk';
	},

	getGeocodeZoom: function (result) {
		if (result.buiType === 'postcode') {
			return mapSearch.cons.zoomPostcode;
		} else if (result.buiType === 'city') {
			return mapSearch.cons.zoomCity;
		} else if (result.buiType === 'region') {
			return mapSearch.cons.zoomCounty;
		} else if (result.buiType === 'province') {
			return mapSearch.cons.zoomCountry;
		} else {
			return mapSearch.cons.zoomCourse;
		}
	},

	getRegion: function () {
		var cids = mapSearch.settings.clientIds;
		var rb = $('#' + cids.container + ' .' + cids.regionClass + ' input:checked');
		if (rb.length > 0) {
			rb = rb.attr('id');
			return rb.replace(cids.regionPrefix, '');
		}
	},

	getRegionData: function (region) {
		var i, data;
		for (i = 0; i < mapSearch.settings.regions.length; i++) {
			var r = mapSearch.settings.regions[i];
			if (r.name === region) {
				data = r;
				break;
			}
		}
		return data;
	},

	loadCourse: function (course) {
		bui.json.fetch(mapSearch.settings.urls.courseProvider, {
			maxresults: mapSearch.cons.maxSuggestions,
			method: 'all',
			phrase: course,
			region: mapSearch.getRegion()
		}, function (data) {
			var cids = mapSearch.settings.clientIds;

			if (data && data.GolfCourses && data.GolfCourses.length > 0) {
				var c = data.GolfCourses[0];
				$('#' + cids.container + ' #' + cids.hidSearch).val(c.CourseName);
				$('#' + cids.container + ' #' + cids.txtCourseName).val(c.CourseName);
				$('#' + cids.container + ' #' + cids.txtLocation).val('');
				mapSearch.vars.localized = true;
				mapSearch.loadPoint(c.Geocode, mapSearch.cons.zoomCourse);
			} else {
				mapSearch.setStatus(mapSearch.text.noMatchingCourse, 'error');
			}
		});
	},

	loadLocation: function (address) {
		var options = {
			bounds: mapSearch.map.getBounds(),
			region: 'uk'
		};
		bui.googleApi.maps.geocode(address, options, function (results) {
			var cids = mapSearch.settings.clientIds;

			if (results && results.length > 0) {
				var r = results[0];
				$('#' + cids.container + ' #' + cids.hidSearch).val(r.formatted_address);
				$('#' + cids.container + ' #' + cids.txtCourseName).val('');
				$('#' + cids.container + ' #' + cids.txtLocation).val(r.formatted_address);
				mapSearch.vars.localized = true;
				mapSearch.loadPoint(r.geometry.location.lat() + ',' + r.geometry.location.lng(), mapSearch.getGeocodeZoom(r));
			} else {
				mapSearch.setStatus(mapSearch.text.noMatchingLocation, 'error');
			}
		});
	},

	loadPoint: function (point, zoom, store) {
		if (point) {
			zoom = zoom || mapSearch.cons.zoomLocal;
			var cids = mapSearch.settings.clientIds;

			if (store || typeof store === 'undefined') {
				$('#' + cids.container + ' #' + cids.hidLatLong).val(point);
				$('#' + cids.container + ' #' + cids.hidZoom).val(zoom);
			}

			mapSearch.vars.busy = true;
			mapSearch.map.getStreetView().setVisible(false);
			mapSearch.map.setCenter(bui.googleApi.maps.latLong(point));
			if (zoom) {
				mapSearch.map.setZoom(parseInt(zoom, 10));
				mapSearch.vars.zoomLevel = zoom;
			}
			mapSearch.vars.busy = false;
			mapSearch.getCourses();
		}
	},

	loadRegion: function (region) {
		var cids = mapSearch.settings.clientIds;
		region = region.toLowerCase();

		$('#' + cids.container + ' #' + cids.txtCourseName).val('');
		$('#' + cids.container + ' #' + cids.txtLocation).val('');
		mapSearch.setRegion(region);

		var data = mapSearch.getRegionData(region);
		if (data) {
			mapSearch.vars.localized = false;
			mapSearch.loadPoint(data.center, data.zoom, false);
		}
	},

	loadSearchResults: function (callback) {
		var cids = mapSearch.settings.clientIds;

		if (cids.searchResultsPanel) {
			callback = callback || false;
			var results = $('#' + cids.searchResultsContainer);

			if (callback) {
				bui.data.set(results, 'buiPager', null);
				var resultCount = bui.widgets.pager.load(results, {
					className: 'searchResults',
					onSort: function () {
						if ($('#' + cids.searchResultsSorter).val() !== mapSearch.vars.resultsSort) {
							mapSearch.loadSearchResults();
							return;
						}
					}
				});

				$('#' + cids.searchResultsPromo).hide();
				$('#' + cids.searchResultsLoading).hide();

				if (resultCount > 0) {
					$('#' + cids.searchResultsNone).hide();
					results.show();
					results.find('.courseCost').buiRating({
						className: 'courseCost',
						scale: 3,
						textPrefix: 'Cost: ',
						textValues: ['-', 'Low', 'Medium', 'High']
					});
					mapSearch.updateMarkers();
					tg.googleAnalytics.init(results);

					if (mapSearch.vars.resultsCallbackCount === 0 && bui.query.get(mapSearch.settings.keys.latLong)) {
						// only scroll on first load
						bui.window.scrollTop($('#' + cids.container).offset().top, 'slow');
					}
				} else {
					results.hide();
					$('#' + cids.searchResultsNone).show();
				}

				mapSearch.vars.resultsCallbackCount++;
				mapSearch.vars.resultsLoaded = true;
			} else {
				if (mapSearch.vars.localized || mapSearch.vars.zoomLevel >= mapSearch.cons.zoomLocal) {
					mapSearch.vars.resultsSortChanged = (mapSearch.vars.resultsSort !== $('#' + cids.searchResultsSorter).val());
					mapSearch.vars.resultsSort = $('#' + cids.searchResultsSorter).val();

					var center = mapSearch.map.getCenter();
					var radius = bui.googleApi.maps.getRadius(center, mapSearch.map.getBounds()) || 1;
					var eventTarget = cids.searchResultsPanel.replace(/_/g, '$');
					var eventArgs = 'll:' + center + '|dist:' + radius + '|max:' + mapSearch.cons.maxResults + '|sort:' + mapSearch.vars.resultsSort;
					window.__doPostBack(eventTarget, eventArgs);
					$('#' + cids.searchResultsPromo).hide();
					results.hide();
					if (mapSearch.vars.resultsLoaded) {
						$('#' + cids.searchResultsLoading).css('height', results.height() > 300 ? results.height() : 300).show();
					} else {
						$('#' + cids.searchResultsLoading).show();
					}
				} else {
					results.hide();
					$('#' + cids.searchResultsLoading).hide();
					$('#' + cids.searchResultsNone).hide();
					$('#' + cids.searchResultsPromo).show();
					mapSearch.vars.resultsLoaded = true;
				}
			}
		}
	},

	locationSelect: function (tb, text, value) {
		var cids = mapSearch.settings.clientIds;

		$('#' + cids.container + ' #' + cids.hidSearch).val(text);
		if (text !== '') {
			value = value.split(',');
			var point = value[0] + ',' + value[1];
			mapSearch.setRegion(value[2]);

			if (mapSearch.settings.urls.resultsTarget === '') {
				mapSearch.vars.localized = true;
				mapSearch.loadPoint(point, value[3]);
			} else {
				$('#' + cids.container + ' #' + cids.hidLatLong).val(point);
				$('#' + cids.container + ' #' + cids.hidZoom).val(value[3]);
				$('#' + cids.container + ' #' + cids.btnFind).trigger('click');
			}
		} else {
			mapSearch.setStatus(mapSearch.text.noMatchingLocation, 'error');
		}
	},

	locationSuggest: function (tb) {
		var cids = mapSearch.settings.clientIds;
		$('#' + cids.container + ' #' + cids.txtCourseName).val('');

		var val = tb.val().trim();
		if (val.length >= mapSearch.cons.minSuggestChars) {
			var region = mapSearch.getRegion();
			if (region === 'uk') {
				val += ', uk';
			}
			var options = {
				bounds: mapSearch.map.getBounds()
			};
			bui.googleApi.maps.geocode(val, options, function (results) {
				var i, m = [];
				for (i = 0; i < results.length; i++) {
					var r = results[i];
					var reg = mapSearch.getGeocodeRegion(r);

					if (reg === region) {
						m.push({ text: r.formatted_address, value: r.geometry.location.lat() + ',' + r.geometry.location.lng() + ',' + reg + ',' + mapSearch.getGeocodeZoom(r) });
						if (m.length === mapSearch.cons.maxSuggestions) { break; }
					}
				}
				bui.forms.autoSuggest.showMatches(tb, m);
			});
		} else {
			bui.forms.autoSuggest.hideMatches(tb);
		}
	},

	onClick: function () {
		mapSearch.enableScrollwheel();
	},

	onDrag: function () {
		if (mapSearch.vars.busy) { return; }
		mapSearch.enableScrollwheel();
		if (mapSearch.vars.localized || mapSearch.vars.zoomLevel >= mapSearch.cons.zoomLocal || mapSearch.vars.state !== 'ok') {
			mapSearch.getCourses();
		}
	},

	onLoad: function () {
		var cids = mapSearch.settings.clientIds;
		var keys = mapSearch.settings.keys;
		var course = bui.query.get(keys.course);
		var latLong = bui.query.get(keys.latLong);
		var location = bui.query.get(keys.location);
		var region = bui.query.get(keys.region);
		var zoom = bui.query.get(keys.zoom);

		if (latLong) {
			mapSearch.vars.localized = true;
			mapSearch.loadPoint(latLong, zoom || mapSearch.cons.zoomLocal);
		} else if (course) {
			mapSearch.loadCourse(course);
		} else if (location) {
			mapSearch.loadLocation(location);
		} else if (region) {
			mapSearch.loadRegion(region);
		} else {
			mapSearch.loadRegion('uk');
		}

		$('#' + cids.container + ' #' + cids.txtCourseName).val(course);
		$('#' + cids.container + ' #' + cids.txtLocation).val(location);
	},

	onZoom: function () {
		if (mapSearch.vars.busy) { return; }
		mapSearch.enableScrollwheel();
		var pzl = mapSearch.vars.zoomLevel;
		mapSearch.vars.zoomLevel = mapSearch.map.getZoom();
		if (mapSearch.vars.localized || mapSearch.vars.zoomLevel >= mapSearch.cons.zoomLocal || pzl >= mapSearch.cons.zoomLocal || mapSearch.vars.state !== 'ok') {
			if (pzl >= mapSearch.cons.zoomLocal && mapSearch.vars.zoomLevel < mapSearch.cons.zoomLocal) {
				mapSearch.vars.localized = false;
			}
			window.setTimeout(mapSearch.getCourses, 10); //delay to allow bounds to change
		}
	},

	openInfoWindow: function (marker, scrollIntoView) {
		var cids = mapSearch.settings.clientIds;
		mapSearch.enableScrollwheel();
		mapSearch.closeInfoWindows();

		var id = -1;
		if (bui.test.isType(marker, 'object')) {
			id = $.inArray(marker, mapSearch.vars.markers);
		} else {
			id = marker;
			marker = mapSearch.vars.markers[id];
		}
		if (id > -1 && marker) {
			mapSearch.vars.infoOpen.push(id);
			mapSearch.vars.infoWindows[id].open(mapSearch.map, marker);
			if (scrollIntoView) {
				bui.window.scrollTop($('#' + cids.container).offset().top);
			}
		}
	},

	reorderMarker: function (id, color, index, length) {
		id = Number(id);
		var marker = mapSearch.vars.markers[id];
		var infoWin = mapSearch.vars.infoWindows[id];
		if (marker && infoWin) {
			infoWin.content = infoWin.content.replace(/<span class="index">\d+\.<\/span>/, '<span class="index">' + index + '.</span>');
			marker.icon = mapSearch.generateMarker(mapSearch.markers.flag.image, color, index);
			marker.zIndex = length - index;
			marker.setMap(mapSearch.map);
			if (bui.utils.inArray(mapSearch.vars.infoOpen, id)) {
				mapSearch.closeInfoWindows();
				mapSearch.openInfoWindow(marker);
			}
		}
	},

	setRegion: function (region) {
		region = region.toLowerCase();
		var cids = mapSearch.settings.clientIds;

		$('#' + cids.container + ' .' + cids.regionClass + ' input').attr('checked', false);
		$('#' + cids.container + ' #' + cids.regionPrefix + region).attr('checked', true);
		mapSearch.showPromo(region);
	},

	setStatus: function (msg, type) {
		var cids = mapSearch.settings.clientIds;

		if (msg) {
			mapSearch.vars.state = type;
			$('#' + cids.container + ' #' + cids.hidLatLong).val('');
			$('#' + cids.container + ' #' + cids.hidZoom).val('');
			$('#' + cids.container + ' #' + cids.statusMsg).html(msg).attr('class', '').addClass(type);
			$('#' + cids.container + ' #' + cids.statusPanel + ':hidden').slideDown('fast');
		} else {
			mapSearch.vars.state = 'ok';
			$('#' + cids.container + ' #' + cids.statusPanel + ':visible').hide();
		}
	},

	showPromo: function (region) {
		if (region !== 'uk' && region !== 'rotw') {
			region = 'rotw';
		}

		var cids = mapSearch.settings.clientIds;
		$('#' + cids.container + ' .' + cids.promoClass + ':visible').each(function () {
			var vp = $(this);
			if (vp.attr('id') !== cids.promoClass + '_' + region) {
				vp.fadeOut(500, function () {
					$('#' + cids.container + ' #' + cids.promoClass + '_' + region + ':hidden').fadeIn(500);
				});
			}
		});
	},

	updateMarkers: function () {
		if (mapSearch.vars.resultsSortChanged) {
			var cids = mapSearch.settings.clientIds;

			var r = $('#' + cids.searchResultsContainer + ' .' + cids.searchResultsContainer + '-record');
			r.each(function () {
				var r = $(this);
				var index = r.find('input[name="index"]').val();
				var pageId = r.find('input[name="pageId"]').val();
				var twoForOne = r.find('input[name="twoForOne"]').val();
				var teeTimes = r.find('input[name="teeTimes"]').val();
				var color = mapSearch.getFlagColor(twoForOne, teeTimes);
				mapSearch.reorderMarker(pageId, color, index, r.length);
			});
			mapSearch.vars.resultsSortChanged = false;
		}
	}
};

