
	google.load("maps", "2");
	
	Object.size = function(obj) {
	    var size = 0, key;
	    for (key in obj) {
	        if (obj.hasOwnProperty(key)) size++;
	    }
	    return size;
	};
	
	var map;
	var map_data;
	
	var marker = new Array();
	var marker2 = new Array();
	var duplicates = new Array();
	var points = new Array();
	var geocoder;
    var count = 0;
    
	function initialize() {
    	if (google.maps.BrowserIsCompatible()) {
			var defaultSW = new google.maps.LatLng(39.707, -14.238); // SW
			var defaultNE = new google.maps.LatLng(53.305, 12.931); // NE
			var defaultCenter = new google.maps.LatLng(46.935261, 2.48291); // the center ???
			var defaultZoom = 5; // default zoom level
			var aberration = 0.2; // this value is a good choice for germany (?!)
			var minRes = 5; // tested for germany
			var maxRes = 17; // may be a lower value

			var allowedBounds = new google.maps.LatLngBounds(defaultSW,defaultNE);
			
			var sellers_side = 0;
			var page_path = location.pathname;
			if (page_path.search('agents') >= 0) {
				sellers_side = 1;
			}

			if (sellers_side == 1) {
				map = new google.maps.Map2(document.getElementById("map_area"));
			} else {
				map = new google.maps.Map2(document.getElementById("map_google"));
				document.getElementById("map_google").appendChild(tooltip);
			    tooltip.style.visibility="hidden";
			}
			geocoder = new GClientGeocoder()
			geocoder.setBaseCountryCode('fr');

			// Get the list of map types
			var mt = map.getMapTypes();

			// Overwrite the getMinimumResolution() and getMaximumResolution() methods
			for (var i=0; i<mt.length; i++) {
				mt[i].getMinimumResolution = function() {return minRes;}
				mt[i].getMaximumResolution = function() {return maxRes;}
			}

			map.removeMapType(G_HYBRID_MAP);
			map.removeMapType(G_SATELLITE_MAP);
			map.addControl(new google.maps.LargeMapControl());
			map.addControl(new google.maps.MapTypeControl());

			map.setCenter(defaultCenter, defaultZoom);

			// If the map position is out of range, move it back
			function checkBounds() {
				// Perform the check and return if OK
				var currentBounds = map.getBounds();
				var cSpan = currentBounds.toSpan(); // width and height of the bounds
				var offsetX = cSpan.lng() / (2+aberration); // we need a little border
				var offsetY = cSpan.lat() / (2+aberration);
				var C = map.getCenter(); // current center coords
				var X = C.lng();
				var Y = C.lat();

				// now check if the current rectangle in the allowed area
				var checkSW = new google.maps.LatLng(C.lat()-offsetY,C.lng()-offsetX);
				var checkNE = new google.maps.LatLng(C.lat()+offsetY,C.lng()+offsetX);
				
				if (allowedBounds.containsLatLng(checkSW) &&
					allowedBounds.containsLatLng(checkNE)) {
					return; // nothing to do
				}

				var AmaxX = allowedBounds.getNorthEast().lng();
				var AmaxY = allowedBounds.getNorthEast().lat();
				var AminX = allowedBounds.getSouthWest().lng();
				var AminY = allowedBounds.getSouthWest().lat();

				if (X < (AminX+offsetX)) {X = AminX + offsetX;}
				if (X > (AmaxX-offsetX)) {X = AmaxX - offsetX;}
				if (Y < (AminY+offsetY)) {Y = AminY + offsetY;}
				if (Y > (AmaxY-offsetY)) {Y = AmaxY - offsetY;}

				map.setCenter(new google.maps.LatLng(Y,X));
				return;
			}
			
			google.maps.Event.addListener(map, "move", function() {
				checkBounds();
			});
			
			//google.maps.Event.addListener(map, "click", function(overlay,point){add_marker(overlay,point);});
			//google.maps.Event.addListener(map, "dblclick", function(overlay,point){add_marker(overlay,point);});
		}
	}

	function hashLength(objArray) {
		cnt = 0;
		aCnt = 0;

		for (var i in objArray) {
		    aCnt++;
		}
		if(aCnt==0) {
		    while(objArray[cnt++]!=null) {
		    	aCnt++;
		    }
		    aCnt = objArray.length;
		}
	    return aCnt;
	}
	
	
	function addPins (map_data, marker) {
		var lng;
		var lat;
		var length;
		var id;
		var type;
		var count;
		var point_count = 0;
		var icon_image;
		var url = "http://www.breeze-france.com/img/";
		var pins = new Array('A','B','C','D','E','F','G','H','I','J');
		
		var single_pin = 0;
		var page_path = location.pathname;
		if (page_path.search('view_property') >= 0) {
			single_pin = 1;
		}
		
		if (typeof map_data === 'undefined' || Object.size(map_data) == 0) {
			drawRegions(map);
			return;
		}
		
		for (var lat in map_data) {
			for(var lng in map_data[lat]) {
				if(map_data[lat][lng].length == 1) {
					id = map_data[lat][lng][0][0];
					type = map_data[lat][lng][0][1];

					count = map_data[lat][lng][0][2];
					contract = map_data[lat][lng][0][3];
					
					if (lat != 0 && lng != 0) {
    					icon_image = new google.maps.Icon();
    					switch (type) {
							case "house":
								switch(contract) {
									case "rent":
										if(single_pin == 1) {
											icon_image.image = url + 'images/pins/pin_2.png';
										} else {
											icon_image.image = url + 'images/pins/buyer_side/pin_2_' + pins[count] + '.png';
										}
									break;
									
									case "buy":
									default:
										if(single_pin == 1) {
											icon_image.image = url + 'images/pins/pin_1.png';
										} else {
											icon_image.image = url + 'images/pins/buyer_side/pin_1_' + pins[count] + '.png';
										}
									break;
									
								}
								icon_image.iconSize = new google.maps.Size(39,59);
							    icon_image.iconAnchor = new google.maps.Point(14, 57);
								icon_image.infoWindowAnchor = new google.maps.Point(14, 0);
							break;    
							case "apartment":
								switch(contract) {
									case "rent":
										if(single_pin == 1) {
											icon_image.image = url + 'images/pins/pin_4.png';
										} else {
											icon_image.image = url + 'images/pins/buyer_side/pin_4_' + pins[count] + '.png';
										}
									break;
									
									case "buy":
									default:
										if(single_pin == 1) {
											icon_image.image = url + 'images/pins/pin_3.png';
										} else {
											icon_image.image = url + 'images/pins/buyer_side/pin_3_' + pins[count] + '.png';
										}
									break;
									
								}
								icon_image.iconSize = new google.maps.Size(39,59);
								icon_image.iconAnchor = new google.maps.Point(14, 57);
								icon_image.infoWindowAnchor = new google.maps.Point(14, 0);
							break;
							default:
								switch(contract) {
									case "rent":
										if(single_pin == 1) {
											icon_image.image = url + 'images/pins/pin_seller_2-1.png';
										} else {
											icon_image.image = url + 'images/pins/seller_side/pin_seller_2-2_' + pins[count] + '.png';
										}
									break;
									
									case "buy":
									default:
										if(single_pin == 1) {
											icon_image.image = url + 'images/pins/pin_seller_2-2.png';
										} else {
											icon_image.image = url + 'images/pins/seller_side/pin_seller_2-1_' + pins[count] + '.png';
										}
									break;
									
								}
								icon_image.iconSize = new google.maps.Size(44,41);
								icon_image.iconAnchor = new google.maps.Point(14, 40);
								icon_image.infoWindowAnchor = new google.maps.Point(14, 0);
							break;
						}

						var latlng = new google.maps.LatLng(lat,lng);
						
						var options = { icon:icon_image };
						
						marker[count] = new google.maps.Marker(latlng, options);
						points[point_count] = latlng;
						point_count++;
						marker[count].bindInfoWindow($('map_info_'+count));
						map.addOverlay(marker[count]);
					}
				} else { // ! if(map_data[lat][lng].length == 1)
					if(lat != 0 && lng != 0) {
						var bubble_info;
						var marker_count;

						for (var i = 0;i<map_data[lat][lng].length;i++) {
							id = map_data[lat][lng][i][0];
							type = map_data[lat][lng][i][1];
		
							count2 = map_data[lat][lng][i][2];
							contract = map_data[lat][lng][i][3];
							
							if (i==0) {
								bubble_info = $('map_info_short_'+count2);
								marker_count = count2;
							} else {
								bubble_info.insert($('map_info_short_'+count2));
								if(i==1) {
									duplicates[marker_count] = new Array();
									duplicates[marker_count].push(count2);
								} else {
									duplicates[marker_count].push(count2);
								}
							}
						}
						icon_image = new google.maps.Icon();
						icon_image.image = url + 'images/cluster.png';
						icon_image.iconSize = new google.maps.Size(30,41);
						icon_image.iconAnchor = new google.maps.Point(14, 40);
						icon_image.infoWindowAnchor = new google.maps.Point(14, 0);
						
						var latlng = new google.maps.LatLng(lat,lng);
						
						var options = { icon:icon_image };
						
						marker[marker_count] = new google.maps.Marker(latlng, options);
						points[point_count] = latlng;
						point_count++;
						marker[marker_count].bindInfoWindow(bubble_info);
						map.addOverlay(marker[marker_count]);
					}

				}
			}
		}
		//resizeMap(map, marker);
		fitMap(map, points);
	}
	
	function show_pin(id) {
		var marker_id = id;
		for (var index in duplicates) {
			for(var i = 0;i<duplicates[index].length;i++) {
				if(duplicates[index][i]==id) {
					marker_id = index;
				}
			}
		}
		var marker_info = $('map_info_'+id).cloneNode(true);
		marker[marker_id].openInfoWindow(marker_info);
	}
	
	function fitMap( map, points ) {
       var bounds = new google.maps.LatLngBounds();
       for (var i=0; i< points.length; i++) {
          bounds.extend(points[i]);
       }
       map.setZoom(map.getBoundsZoomLevel(bounds));
       map.zoomOut();
       map.setCenter(bounds.getCenter());
    }

/**
 * Draw French regions on the map
 * 
 * @param gmap Google map
 */
	function drawRegions(gmap) {
		if ((typeof mapRegions !== 'undefined') && (typeof polygonsCoords !== 'undefined')) {
			for (var regionCode in mapRegions) {
				if (typeof polygonsCoords['polygon_' + regionCode] !== 'undefined') {
					var regionPolygon = addPolygon(polygonsCoords['polygon_' + regionCode].coords, gmap);
					var regionData = mapRegions[regionCode];
					regionPolygon.tooltip = '<div class="tooltip">' + regionData['name'] + ' (' + regionData['property_count'] + ')' + '<\/div>';
					regionPolygon.regionCode = regionCode;

					GEvent.addListener(regionPolygon, 'click', function() {
						document.location.href = baseSearchRegionUrl + this.regionCode;
					});
					GEvent.addListener(regionPolygon, 'mouseover', function() {
						this.setFillStyle({ color: '#88036A', opacity: 0.2 });
						showTooltip(this);
					});
					GEvent.addListener(regionPolygon, 'mouseout', function(a, b) {
						this.setFillStyle({ color: '#6C8CC8', opacity: 0.2 });
						hideTooltip();
					});
				}
			}
		}
	}

/**
 * Add a polygon on the Google Map
 * 
 * @param poly Polygon data
 * @param gmap Google map instance
 */	
	function addPolygon(poly, gmap) {
		var coordinates = [];
		var polygon;
		for (var i=0; i < poly.length; i++) {
			coordinates[i] = new google.maps.LatLng(poly[i][0], poly[i][1]);
		}
		polygon = new google.maps.Polygon(coordinates, '#FFFFFF', 0.7, 1, '#6C8CC8', 0.2, { mouseOutTolerance: 0 });
		gmap.addOverlay(polygon)
		return polygon;
	}
	
	var tooltip = document.createElement("div");
/**
 * Displays a tooltip for the polygon
 * Quick and dirty tooltip from econym.org.uk/gmap/example_maptips2.htm
 * 
 * @param polygon
 */
    function showTooltip(polygon) {
    	tooltip.innerHTML = polygon.tooltip;
    	var point = map.getCurrentMapType().getProjection().fromLatLngToPixel(map.getBounds().getSouthWest(), map.getZoom());
    	var offset = map.getCurrentMapType().getProjection().fromLatLngToPixel(polygon.getBounds().getCenter(), map.getZoom());
    	
    	var pos = new GControlPosition(G_ANCHOR_BOTTOM_LEFT, new GSize(offset.x - point.x,- offset.y + point.y)); 
    	pos.apply(tooltip);
    	tooltip.style.visibility="visible";
    }

/**
 * Hide the displayed tooltip
 * 
 */
	function hideTooltip() {
		tooltip.style.visibility = "hidden";
	}
