var Quarters = function() {
	var gm, defaultCenter = [42.6976246, 23.3222924], // Sofia
			defaultZoomLevel = 12, strokeColor = '#000000', strokeWidth = 2,
			strokeOpacity = 0.7, fillColor = '#0000FF', fillOpacity = 0.6,
			polygons = [], polygonData = [], markers = [], markerData = [], mapContainer, map,
			defaultIcon, geocoder, addressSearchContainer, addressSearchField;
	
	function asLatLng(latLngArray) {
		if(latLngArray[0].toString().replace(/\s*/, '') === '' || latLngArray.length < 2) return null;
		return new gm.LatLng(latLngArray[0], latLngArray[1]);
	}
	
	function initialize() {
		gm = google.maps;
		mapContainer = document.getElementById('powernet_quarters');
		
		map = new gm.Map2(mapContainer);
		map.setUIToDefault();
		map.setCenter(asLatLng(defaultCenter), defaultZoomLevel);
		
		buildDefaultIcon();
		buildStoredPolygons();
		buildStoredMarkers();
		setupAddressSearch();
		
		$(window).unload(gm.Unload);
	}
	
	function storePolygon(opts) {
		opts.strokeColor = opts.strokeColor == '' ? strokeColor : '#'+opts.strokeColor;
		opts.fillColor = opts.fillColor == '' ? fillColor : '#'+opts.fillColor;
		polygonData.push(opts);
	}
	
	function storeMarker(opts) {
		markerData.push(opts);
	}
	
	function buildDefaultIcon() {
		var options = POWERNET_MAP_MARKER_OPTIONS;
		defaultIcon = new gm.Icon(G_DEFAULT_ICON);
		defaultIcon.image = options.image;
		defaultIcon.transparent = options.transparent;
		defaultIcon.imageMap = options.imageMap;
		defaultIcon.iconSize = new gm.Size(options.iconSize[0], options.iconSize[1]);
		defaultIcon.shadow = options.shadow;
		defaultIcon.shadowSize = new gm.Size(options.shadowSize[0], options.shadowSize[1]);
		defaultIcon.iconAnchor = new gm.Point(options.iconAnchor[0], options.iconAnchor[1]);
		defaultIcon.infoWindowAnchor = new gm.Point(options.infoWindowAnchor[0], options.infoWindowAnchor[1]);
	}
	
	function buildStoredPolygons() {
		$.each(polygonData, function(i, opts) {
			var coords = latlngsFromGeometryString(opts.geometry);
			var polygon = new gm.Polygon(coords, opts.strokeColor, strokeWidth, strokeOpacity, opts.fillColor, fillOpacity);
			var infoWindowHtml = tmpl('quarter_info_window_template', opts);
			map.addOverlay(polygon);
			gm.Event.addListener(polygon, 'click', function() {
				map.openInfoWindowHtml(polygon.getBounds().getCenter(), infoWindowHtml);
			});
			gm.Event.addListener(polygon, 'mouseover', function() {
				polygon.setStrokeStyle({ opacity: 1 });
				polygon.setFillStyle({ opacity: 0.8 });
			});
			
			gm.Event.addListener(polygon, 'mouseout', function() {
				polygon.setStrokeStyle({ opacity: strokeOpacity });
				polygon.setFillStyle({ opacity: fillOpacity });
			});
			polygons.push(polygon);
		});
	}
	
	function buildStoredMarkers() {
		$.each(markerData, function(i, opts) {
			var latlng = latlngsFromGeometryString(opts.geometry)[0];
			var marker = new gm.Marker(latlng, { icon: defaultIcon, title: opts.name });
			var infoWindowHtml = tmpl('office_info_window_template', opts);
			gm.Event.addListener(marker, 'click', function() {
				marker.openInfoWindowHtml(infoWindowHtml);
			});
			map.addOverlay(marker);
			markers.push(marker);
		});
	}
	
	function latlngsFromGeometryString(geom) {
		return $.map(geom.replace(/(POLYGON|POINT)\(+(.*?)\)+/, '$2').split(','), function(pair) {
			// pairs are in lng lat format (reversed)
			var latlng = pair.split(' ');
			return new gm.LatLng(latlng[1], latlng[0]);
		});
	}
	
	function setupAddressSearch() {
		geocoder = new gm.ClientGeocoder();
		geocoder.setBaseCountryCode('bg');
		addressSearchContainer = document.getElementById('address_search');
		addressSearchField = document.getElementById('address_search_field');
		
		$(addressSearchField).keypress(function(event) {
			$('#address_search_error').slideUp('slow');
			if(event.which == 13) { // 'enter' key
				event.preventDefault();
				// do nothing if field is blank
				if(addressSearchField.value.replace(/\s+/, '') == '') return;
				doAddressSearch();
			}
		});
	}
	
	function doAddressSearch() {
		addressSearchField.disabled = true;
		geocoder.setViewport(map.getBounds());
		geocoder.getLocations(addressSearchField.value, addressSearchResultsHandler);
		$(addressSearchContainer).addClass('loading');
	}
	
	function addressSearchResultsHandler(response) {
		if(response.Status.code == G_GEO_SUCCESS) {
			if(response.Placemark && response.Placemark.length) {
				// center on the first result
				var placemark = response.Placemark[0];
				var coordinates = new gm.LatLng(placemark.Point.coordinates[1], placemark.Point.coordinates[0]);
				var zoomLevel = map.getZoom();
				
				// sometimes google suggests a bounding box around the most accurate result
				if(placemark.ExtendedData && placemark.ExtendedData.LatLonBox) {
					var box = placemark.ExtendedData.LatLonBox;
					var bounds = new gm.LatLngBounds(new gm.LatLng(box.south, box.west), new gm.LatLng(box.north, box.east));
					var zoomLevel = map.getBoundsZoomLevel(bounds);
				}
				
				map.setCenter(coordinates, zoomLevel);
			}
		} else if(response.Status.code == G_GEO_UNKNOWN_ADDRESS) {
			if($('#address_search_error').length == 0) {
				$('<div id="address_search_error"></div').appendTo(addressSearchContainer).hide();
			}
			$('#address_search_error').html('Адресът не може да бъде намерен.').slideDown('slow');
		}
		
		addressSearchField.disabled = false;
		$(addressSearchContainer).removeClass('loading');
	}
	
	return {
		initialize: initialize,
		storePolygon: storePolygon,
		storeMarker: storeMarker
	};
}();

// Simple JavaScript Templating
// John Resig - http://ejohn.org/ - MIT Licensed
(function(){
  var cache = {};
  
  this.tmpl = function tmpl(str, data){
    // Figure out if we're getting a template, or if we need to
    // load the template - and be sure to cache the result.
    var fn = !/\W/.test(str) ?
      cache[str] = cache[str] ||
        tmpl(document.getElementById(str).innerHTML) :
      
      // Generate a reusable function that will serve as a template
      // generator (and which will be cached).
      new Function("obj",
        "var p=[],print=function(){p.push.apply(p,arguments);};" +
        
        // Introduce the data as local variables using with(){}
        "with(obj){p.push('" +
        
        // Convert the template into pure JavaScript
        str
          .replace(/[\r\t\n]/g, " ")
          .split("<%").join("\t")
          .replace(/((^|%>)[^\t]*)'/g, "$1\r")
          .replace(/\t=(.*?)%>/g, "',$1,'")
          .split("\t").join("');")
          .split("%>").join("p.push('")
          .split("\r").join("\\'")
      + "');}return p.join('');");
    
    // Provide some basic currying to the user
    return data ? fn( data ) : fn;
  };
})();

$(document).ready(function() {
	// load the google maps api
	google.load('maps', '2', { language: 'bg', callback: Quarters.initialize, other_params: 'sensor=false' });
});