var IUCNGoogleMaps = EosGoogleMaps.extend({
	initialize: function(elementId, location, zoomLevel, options){
		this.parent(elementId, location, zoomLevel, options);
		this.hideOutOfBoundsMarkers = false;
		this.map.addMapType(G_PHYSICAL_MAP);
		mapTypes = G_DEFAULT_MAP_TYPES;
		for(var i = 0; i < mapTypes.length; i++){
			mapTypes[i].getMaximumResolution = function(latlng){ return 12;};
			mapTypes[i].getMinimumResolution = function(latlng){ return 1;};
		}
		G_PHYSICAL_MAP.getMaximumResolution = function(latlng){ return 12;};
		G_PHYSICAL_MAP.getMinimumResolution = function(latlng){ return 1;};
		this.slowJS = false;
		this.polylines = new Hash();
		this.projectMarkers = [];
		this.countryMarkers = [];
		this.fogPoly = false;
		this.currentCountryMarker = false;
		this.currentContinentLoaction = false;
		this.addFog();
		this.iucnFilter = new ProjectFilter(this);
		this.addPolyLines();
		this.defaultLocation= this.getDefaultCoordinates(location);
		this.defaultZoomLevel = zoomLevel;
		this.currentHover = null;
	},
	
	getDefaultCoordinates: function(location) {
		var coordinates = location.split(',');
		coordinates[0] = coordinates[0].toFloat();
		coordinates[1] = coordinates[1].toFloat();
		return coordinates;
	},
	
	reset: function() {
		this.goToCoordinates(this.defaultLocation, this.defaultZoomLevel);
		this.clearMarkers();
		this.currentHover = null;
		this.polylines.empty();
	},
	
	getGoogleCountryname: function(countryName) {
		return countryName.split(',').reverse().join(' ');
	},
	
	addPolyLines: function(newContinent) {
		//postObject.action = 'IUCNGetContinents';
		var postObject = new Hash({
			action: 'IUCNGetContinents'
		});
		postObject.merge(this.iucnFilter.getConditions());
		var getRequest = new Json.Remote('/sbeos/ajax/JsonCall.php',
			{
				onComplete: function(result) {
					result.options.each(function(item) {
						conditions = this.iucnFilter.getConditions();
						// not a continent with no name
						// OR there is a continent condition and its not the current continent
						//console.log(newContinent);
						//console.log(item.name);
						if (this.getContinentName(item.name) != '') {
							if  (!this.iucnFilter.getConditions().continent || (this.iucnFilter.getConditions().continent && this.getContinentName(this.iucnFilter.getConditions().continent) != this.getContinentName(item.name))) {
								this.addMarker(
									this.getContinentName(item.name),
									item.location,
									{
										events: new Hash({
											'click': this.loadContinent.bindAsEventListener(this, [item.name, item.location])
										}),
										tooltip: item.name,
										icon: '/images/countIcon.php?size='+item.count+'&file=.png',
										iconmap: [23,35,32,30,36,22,36,15,32,7,23,1,14,1,6,7,2,15,2,22,6,30,14,35,23,35],
										iconAnchor: [20,20],
										iconsizeX: 40,
										iconsizeY: 41
									}
								);
							}
						}
					}.bind(this));
				}.bind(this)
			}
		).send(postObject.obj);
	},
	
	getContinentName: function(name) {
		return name.replace(/\s/g,'').replace(/\W/g,'');
	},
	
	loadContinent: function(event, continent, location) {
		this.clearOtherContinents(continent);
		this.iucnFilter.addFacetCondition('continent', continent);
		this.currentContinentLoaction = location;
		this.goToCoordinates(location, 3);
		if (this.getMarkerById(this.getContinentName(continent))) {
			this.removeMarker(this.getContinentName(continent));
		}
		this.addPolyLinesForContinent(continent);
		this.addProjectCountsForContinent(continent);
	},
	
	clearOtherContinents: function(continentToKeep) {
		this.removeCountryMarkers();
		this.removePolylines();
		this.addPolyLines(continentToKeep);
	},
	
	addFog: function() {
		GPolyline.prototype.containsPoint = function (pointer) {
			if (!this.getBounds().containsLatLng(pointer)) {
				return false;
			} else {
				/*
				// This is an attempt at giving the below a actual variable names
				// how ever it does not work, surounding countries also return true
				var vertexCount = this.getVertexCount();
				var nextVertexPosition = 0;
				var retval = false;
				var pointerLng = pointer.lng();
				var pointerLat = pointer.lat();
				var currentVertexLat, currentVertexLng, nextVertexLat, nextVertexLng;
				for (var i = 0; i < vertexCount; i++) {
					nextVertexPosition = i + 1;
					if (nextVertexPosition == vertexCount) {
						nextVertexPosition = 0;
					}
					currentVertexLat = this.getVertex(i).lat(); 
					nextVertexLat = this.getVertex(nextVertexPosition).lat();
					if ((nextVertexLat < pointerLat && currentVertexLat >= pointerLat)|| (nextVertexLat < pointerLat && currentVertexLat >= pointerLat)) {
						currentVertexLng = this.getVertex(i).lng();
						nextVertexLng = this.getVertex(nextVertexPosition).lng();
						if (currentVertexLng > pointerLng && nextVertexLng > pointerLng) {
							continue;
						}
						if (currentVertexLng <= pointerLng && nextVertexLng <= pointerLng) {
							retval = !retval;
						} else {
							if (currentVertexLng + (pointerLat - currentVertexLat) / (nextVertexLat - currentVertexLat) * (nextVertexLng - currentVertexLng) < pointerLng) {
								retval = !retval;
							}
						}
					}
					
				}
				return retval;
				*/
				var b = this.getVertexCount();
				var g = 0;
				var n = false;
				var o = pointer.lng();
				var m = pointer.lat();
				var e, f, a, c;
				for (var h = 0; h < b; h++) {
					g = h + 1;
					if (g == b) {
						g = 0;
					}
					e = this.getVertex(h).lat();
					a = this.getVertex(g).lat();
					if ((e < m && a >= m) || (a < m && e >= m)) {
						f = this.getVertex(h).lng();
						c = this.getVertex(g).lng();
						if (f > o && c > o) {
							continue;
						}
						if (f <= o && c <= o) {
							n = !n;
						} else {
							if (f + (m - e) / (a - e) * (c - f) < o) {
								n = !n;
							}
						}
					}
				}
				return n;
			}
		};
		GPolyline.prototype.encodedPoints = null;
		
		GEvent.addListener(this.map, "mousemove", function(event) {
			//if (this.currentCountryMarker === false) {
				this.polylines.each(function(polyLine) {
					if (polyLine.containsPoint(event) && this.currentHover != polyLine.countryName) {
						this.addToFog(polyLine);
						found = true;
					}
				}.bind(this));
			//}
		}.bind(this));
		GEvent.addListener(this.map, "click", function(landmass, pointer) {
			if (pointer) {
				this.polylines.each(function(polyLine) {
					if (polyLine.containsPoint(pointer)) {
						this.countryClick.attempt([pointer, polyLine], this);
					}
				}.bind(this));
			}
		}.bind(this));
		GEvent.addListener(this.map, "mouseout", function(event) {
			if (this.currentCountryMarker) {
				var poly = this.getPloygonByCountryName(this.currentCountryMarker);
				this.addToFog(poly);
			}
		}.bind(this));
	},
	
	removeFog: function() {
		if (this.fogPoly) {
			this.map.removeOverlay(this.fogPoly);
			this.currentHover = false;
		}
	},
	
	addToFog: function(ExtraLandMass) {
		this.removeFog();
		var lines = new Array();
		lines.push(
			{
				points: "_qxeO~~ggN~brl_@??__qo]_crl_@??~~po]",
				levels: "PPPPP",
				color: "#000000",
				opacity: 0.0,
				weight: 1,
				numLevels: 18,
				zoomFactor: 2
			}
		);
		lines.push(
			{
				points: "_qxeO__hgN~brl_@??_gjaR_crl_@??~fjaR",
				levels: "PPPPP",
				color: "#000000",
				opacity: 0.0,
				weight: 1,
				numLevels: 18,
				zoomFactor: 2
			}
		);
		lines.push(
			{
				points: "_qxeO~fsia@~brl_@??_gjaR_crl_@??~fjaR",
				levels: "PPPPP",
				color: "#000000",
				opacity: 0.0,
				weight: 1,
				numLevels: 18,
				zoomFactor: 2
			}
		);
		
		
		if (ExtraLandMass) {
			this.currentHover = ExtraLandMass.countryName;
			lines.extend(ExtraLandMass.encodedPoints);
		}
		
		this.fogPoly = new GPolygon.fromEncoded({
			polylines: lines,
			fill: true,
			color: "#000000",
			opacity: 0.2,
			outline: true
		});
		this.map.addOverlay(this.fogPoly);
	},
	
	addPolyLinesForContinent: function(continent) {
		var request = new Json.Remote('/'+this.getContinentName(continent)+'.json',
			{
				onComplete: this.addLandMass.bindAsEventListener(this)
			}
		).send();
	},
	
	addProjectCountsForContinent: function(continent) {
		var postObject = new Hash({
			action: 'IUCNGetProjectCountForContinent'
		});
		postObject.merge(this.iucnFilter.getConditions());
		var getRequest = new Json.Remote('/sbeos/ajax/JsonCall.php',
			{
				onComplete: function(result) {
					result.each(function(item) {
						if ((item.location[0] > -1 && item.location[0] < 1) || (item.location[1] > -1 && item.location[1] < 1)) {
							item.location = item.location[0]+','+item.location[1];
						}
						var hide = this.iucnFilter.conditions.hasKey('country');
						
						this.addMarker(
							this.getContinentName(item.country),
							item.location,
							{
								icon: '/images/countIcon.php?size='+item.count+'&file=.png',
								iconsizeX: 40,
								iconsizeY: 41,
								iconmap: [23,35,32,30,36,22,36,15,32,7,23,1,14,1,6,7,2,15,2,22,6,30,14,35,23,35],
								iconAnchor: [20,20],
								tooltip: item.country,
								hidden: hide,
								events: new Hash({
									click: this.loadCountryProjects.bindAsEventListener(this, [item.country])
								})
							}
						);
						this.countryMarkers.push(this.getContinentName(item.country));
					}.bind(this));
					//this.updateFieldEntries(result);
				}.bind(this)
			}
		).send(postObject.obj);
	},
	
	removeCountryMarkers: function() {
		this.countryMarkers.each(function(markerId) {
			if (this.getMarkerById(markerId)) {
				this.removeMarker(markerId);
			}
		}.bind(this));
		this.countryMarkers = [];
	},
	
	hideCountryMarkers: function() {
		this.countryMarkers.each(function(markerId) {
			//console.log('remove '+markerId);
			if (this.getMarkerById(markerId)) {
				this.hideMaker(markerId);
			}
		}.bind(this));
		//this.countryMarkers = [];
	},
	
	loadCountryProjects: function(event, country) {
		var countryPoly = this.getPloygonByCountryName(country);
		if (countryPoly) {
			this.goToCoordinates(countryPoly.getBounds().getCenter(), this.map.getBoundsZoomLevel(countryPoly.getBounds()));
		} else {
			var countryPoly = this.getPloygonByCountryName(this.getGoogleCountryname(country));
			if (countryPoly) {
				this.goToCoordinates(countryPoly.getBounds().getCenter(), this.map.getBoundsZoomLevel(countryPoly.getBounds()));
			}
		}
		
		this.showCurrentMarker();
		
		this.iucnFilter.addFacetCondition('country', country);
		var postObject = new Hash({
			action: 'IUCNGetProjectsForCountry'
		});
		postObject.merge(this.iucnFilter.getConditions());
		
		if (this.getMarkerById(this.getContinentName(country))) {
			postObject.set('country', this.getMarkerById(this.getContinentName(country)).sbtooltip.innerHTML);
			this.currentCountryMarker = this.getContinentName(country);
			//this.hideMaker(this.currentCountryMarker);
		}
		this.hideCountryMarkers();
		
		var getRequest = new Json.Remote('/sbeos/ajax/JsonCall.php',
			{
				onComplete: this.createProjectMaker.bindAsEventListener(this)
			}
		).send(postObject.obj);
	},
	
	showCurrentMarker: function() {
		if (this.currentCountryMarker) {
			//this.showMarker(this.currentCountryMarker);
			this.currentCountryMarker = false;
		}
	},
	
	createProjectMaker: function(projects) {
		projects.projectsMap.each(function(project, index) {
			if (project.ip_latitude == 0 && project.ip_longitude == 0) {
				projectLocation = this.getGoogleCountryname(this.iucnFilter.conditions.get('country'));
			} else {
				if ((project.ip_latitude > -1 && project.ip_latitude < 1) || (project.ip_longitude > -1 && project.ip_longitude < 1)) {
					projectLocation = project.ip_latitude+','+project.ip_longitude;
				} else {
					projectLocation = [project.ip_latitude,project.ip_longitude];
				}
			}
			if (project.markerTooltip != null) {
				var type='Collection';
			} else {
				var type='';
			}
			
			this.addMarker(
				this.getContinentName(project.ip_title),
				projectLocation,
				{
					html: project.html,
					htmlOptions: {
						maxWidth: 332,
						maxHeight: 260
					},
					icon: '/images/countIcon.php?type=id'+type+'&size='+(project.marker)+'&file=.png',
					tooltip: project.markerTooltip,
					iconsizeX: 58,
					iconsizeY: 50,
					iconmap: [15,43,18,43,18,40,31,26,33,19,33,11,29,5,21,-0,12,-0,4,4,0,13,0,20,3,27,15,40,15,43],
					iconAnchor: [20,47]
				}
			);
			this.projectMarkers.push(this.getContinentName(project.ip_title));
		}.bind(this));
		this.updateFieldEntries(projects);
	},
	
	removeProjectMarkers: function() {
		this.projectMarkers.each(function(markerId) {
			if (this.getMarkerById(markerId)) {
				this.removeMarker(markerId);
			}
		}.bind(this));
		this.projectMarkers = [];
	},
	
	updateFieldEntries: function(projects) {
		this.iucnFilter.clearFieldEntry();
		this.iucnFilter.updateFieldEntries(projects.paging, projects);
	},
	
	addLandMass: function(items) {
		items.each(function (country) {
			if ($chk(country)) {
				country.enc.each(function(line,index) {
					var encodedPolyline = new GPolyline.fromEncoded(line);
					encodedPolyline.encodedPoints = country.enc;
					encodedPolyline.countryName = country.name;
					this.addPolylineOverlay(country.name+index, encodedPolyline);
				}.bind(this));
			}
		}.bind(this));
	},
	
	addPolylineOverlay: function(id, polyline) {
		this.polylines.set(id, polyline);
		this.addOverlay(polyline);
	},
	
	removePolylines: function() {
		this.polylines.each(function(polyline, id) {
			this.removeOverlay(polyline);
		}.bind(this));
		this.polylines.empty();
	},
	
	getPloylineById: function(id) {
		return this.polylines.get(id);
	},
	
	getPloygonByCountryName: function(name) {
		var keys = this.polylines.keys();
		var length = keys.length;
		var regex = new RegExp('[^A-Za-z ]', 'g');
		for (var i = 0; i < length; i++) {
			if (keys[i].replace(regex,'' ) == name.replace(regex,'') || this.getContinentName(keys[i]).replace(regex,'') == name) {
				var polylines = this.getPloylineById(keys[i]);
				var polygon =  new GPolygon.fromEncoded({
					polylines: polylines.encodedPoints,
					fill: true,
					color: "#000000",
					opacity: 0.2,
					outline: true
				});
				polygon.encodedPoints = polylines.encodedPoints;
				polygon.countryName = polylines.countryName;
				return polygon;
			}
		}
	},
	
	countryClick: function(event, encodedPolyline) {
		if (this.markers.hasKey(this.getContinentName(encodedPolyline.countryName))) {
			this.iucnFilter.addFacetCondition('country', encodedPolyline.countryName);
			var event = this.loadCountryProjects.bind(this, [event,encodedPolyline.countryName]);
			event();
			this.goToCoordinates(encodedPolyline.getBounds().getCenter(), this.map.getBoundsZoomLevel(encodedPolyline.getBounds()));
		}
	},
	
	refreshProjects: function(conditions) {
		this.markers.each(function(value,key) {
			this.removeMarker(key);
		}.bind(this));
		
		// continents
		this.addPolyLines();
		
		
		// country projects
		if (conditions.hasKey('country')) {
			this.loadCountryProjects({}, conditions.get('country'));
		}
		// contintent counties
		if (conditions.hasKey('continent')) {
			this.addProjectCountsForContinent(conditions.get('continent'));
		}
	},
	
	goToPage: function(page) {
		// get projects, on compelte, updateFieldEntries
		var postObject = new Hash({
			action: 'IUCNGetProjectsForCountry',
			page: page,
			noMarkers: true
		});
		postObject.merge(this.iucnFilter.getConditions());
		
		var getRequest = new Json.Remote('/sbeos/ajax/JsonCall.php',
			{
				onComplete: this.updateFieldEntries.bind(this)
			}
		).send(postObject.obj);
	}
});