function MapApp (userSettings) {
	//TODO
		// AUTOMATISCH CENTREREN OP POI BIJ ZOOMEN VAN CITYLEVEL NAAR STREETLEVEL
		// PROVINCE CONTROLS INBRENGEN
	//INIT -> init() ->initMapControls()
	//				 ->getPsOI()->createMarkers()->correctMarking()->showMarkers()->FILTERSSUBMIT
	//FILTERSSUBMIT ->filterMarkers()->resetCityMarkers()->showMarkers()
	var settings = $.extend({
		canvas: $("div#mapCanvas")[0],
		dataSource:"tempData.php",
		totalContainer:"span#total",
		txt: {
			txtMeerinfo: "More info",
			txtPrijs: "Price",
			txtHierzoomen: "Zoom in",
			txtSluit: "Close",
			txtBevat: "contains",
			txtResultaten: "Results",
			txtLaden:"Loading, please wait..."
		},
		onComplete:function() {}
	}, userSettings ? userSettings: {});
	var json;
	var activeView;
	var activeCities = new Object();
	var cityMarkers = new Array();
	var poiMarkers = new Array();
	var preloader = new PreLoader();
	var filters = "";
	var zoomLevel;
	var infoWindow = new InfoWindow();
	var minZoom = 10;
	var maxZoom = 19;
	var totalPoints = 0;
	var startup = true;
	
	this.map;
	var mapApp = this;

	init();

	//PUBLIC METHODS
	this.setFilters = function(_filters) {
		filters = _filters;
		filterMarkers();
	}
	this.getFilters = function () {
		return filters;	
	}
	this.getCityPsOI = function(_cName) {
		var ret = 0;
		var c = getCityBycName(_cName);
		return c == false ? 0: c.getPsOI();
	}
	this.setFocusCity = function(city) {
		var c = getCityBycName(city);
		focusMap(new GLatLng(c.lat(),c.lng()), 13);
	}
	//PRIVATE METHODS
	function focusMap(p, z) {
		this.map.setCenter(p, z);
	}
	function getCityBycName (name) {
		var city = false;
		$.each(cityMarkers, function(i, value) {
			if (value.getCName() == name) {
				city = value;
				return false;
			}
		});
		return city;
	}
	function init() {
		
		$("#appWrapper").bind("infoWindowZoomRequest", function(e) {
			var level = e.zoomTarget;

			if (level == "relative") {
				map.setCenter(e.zoomPoint, map.getZoom());
				$("a#mapAppIn").click();
			}
			else if (level == "city") {
				map.setCenter(e.zoomPoint, 12);
			}
			else if (level == "street") {
				map.setCenter(e.zoomPoint, 17);
			}
				
		});
		
		this.map = new GMap2(settings.canvas);
		this.map.setCenter(new GLatLng(51.34230131542749, 3.288860321044922), 13);
		this.map.disableDoubleClickZoom();
		this.map.enableContinuousZoom();
		
		activeCities.alpha = new Array();
		activeCities.zip = new Array();
		
		initMapControls();
		
		GEvent.addListener(this.map, "zoomend", function() {
			infoWindow.hideOverlay();									 
			correctMarking();
		});
		GEvent.addListener(this.map, "moveend", function() {
			correctMarking();	 
		});
		GEvent.addListener(this.map, "movestart", function() {
			infoWindow.hideOverlay();
		});		
		getPsOI();
	}
	function initMapControls() {
		$("a#mapAppUit,a#mapAppIn").bind("click", mapZoomHandler);
		$("a#mapAppGem,a#mapAppStr").bind("click", mapZoomToHandler);
		
		if ($.browser.msie && $.browser.version == "6.0") {
			map.setMapType(G_HYBRID_MAP);
			$("div.viewControls a[title=sat], div.viewControls a[title=map]").hide();
			$("div#appWrapper").before("<div class='ie6Error'>Uw browser versie is verouderd, dit verhindert u om ten volle te gebruik te maken van deze website. En kan uw surfsnelheid sterk beinvloeden. <a href='http://www.microsoft.com/belux/nl/windows/internet-explorer/worldwide-sites.aspx'>Klik hier om te updaten naar de laatste versie van uw favoriete browser.</a></div>");
		}
		else {
			$("div.viewControls a").bind("click", mapTypeHandler);
		}
	}
	function mapZoomToHandler(e) {
		if ($(e.target).attr("id") === "mapAppGem") {
			map.setZoom(minZoom);
		}
		else if ($(e.target).attr("id") === "mapAppStr") {
			map.setZoom(13);
		}
		return false;
	}
	function mapZoomHandler(event) {
		
		if ($(event.currentTarget).attr("id") === "mapAppUit") {
			zoomLevel--;
		}
		else if ($(event.currentTarget).attr("id") === "mapAppIn") {
			zoomLevel++;
		}
		zoomLevel = zoomLevel>maxZoom? maxZoom: zoomLevel;
		zoomLevel = zoomLevel<minZoom? minZoom: zoomLevel;
		map.setZoom(zoomLevel);
		return false;
	}
	function mapTypeHandler(event) {
		var mapT = $(event.currentTarget).attr("title");
		switch(mapT) {
			case "sat":
				map.setMapType(G_HYBRID_MAP);
				break;
			case "map":
				map.setMapType(G_NORMAL_MAP);
				break;
			default:
				break;
		}
		return false;
	}
	function getPsOI() {
		preloader.showPreloader();
		$.get(settings.dataSource, {"operation":"VASTGOED"},
				function(data, status) {
					createMarkers(data);
			}, "json");	
	}
	function correctMarking() {
		zoomLevel = this.map.getZoom();
		if (zoomLevel >= 12 ) {
			activeView = "street";
		}
		else if (zoomLevel < 12 && zoomLevel > 9) {
			activeView = "city";
		}
		else if (zoomLevel <= 9) {
			activeView = "city";
		}
		showMarkers();
	}
	function showMarkers() {
		var bounds = this.map.getBounds();
		var sw = bounds.getSouthWest();
		var ne = bounds.getNorthEast();
		if (activeView === "street") {
			$.each(cityMarkers, function(i, value){
				value.kill();
			});
			$.each(poiMarkers, function(i, value) {
				var min = sw.lng();
				var max = ne.lng();
				var num = value.lng();
				var minL = sw.lat();
				var maxL = ne.lat();
				var numL = value.lat();				
				if (!(min > num || max < num) && !(minL > numL || maxL < numL) && !value.getIgnore()) {
					value.show();
				}
				else {
					value.kill();
				}
			});
		}
		else if (activeView === "city") {
			$.each(poiMarkers, function(i, value){
				value.kill();
			});
			$.each(cityMarkers, function(i, value) {
				var min = sw.lng();
				var max = ne.lng();
				var num = value.lng();
				var minL = sw.lat();
				var maxL = ne.lat();
				var numL = value.lat();				
				if (!(min > num || max < num) && !(minL > numL || maxL < numL) && !value.getIgnore()) {
					value.show();
				}
				else {
					
					value.kill();
				}
			});
		}
		if (startup) {	
			startup = false;
			$("form[name=zoek]").submit();
		}
		
		
		settings.onComplete();
		preloader.hidePreloader();
	}
	function filterMarkers () {
		$.each(poiMarkers, function(i, value) {
			if (
			($.inArray(value.type, filters.types) > -1) &&
			($.inArray(value.regio.replace("u00e9", "é"), filters.regios) > -1) &&
			($.inArray(value.prijsKlasse, filters.prijsKlasse) > -1)
			) {
				value.setIgnore(false);
			}
			else {
				if ($.inArray(value.type, filters.types) == -1) {
					//console.log("wrong type");
				}
				if ($.inArray(value.regio.replace("u00e9", "é"), filters.regios) == -1) {
					//console.log("wrong regio");
				}
				if ($.inArray(value.prijsKlasse, filters.prijsKlasse) == -1) {
					//console.log(value.prijsKlass);
				}				
				value.setIgnore(true);
			}
		});
		resetCityMarkers();
	}
	function resetCityMarkers() {
		totalPoints = 0;
		$.each(cityMarkers, function(i, value) {
			var name = value.getName();
			var count = 0;
			$.each(poiMarkers, function(j, val){
				if (val.parentName == name && val.getIgnore() == false && val.lat() && val.lng()) {	
					count++;
				}
			});
			if (count > 0) {
				value.setPsOI(count);
				value.setIgnore(false);
			}
			else {
				value.setIgnore(true);
			}
			//getCityvals(name);
		});
		
		//reset total
		var i = 0;
		var ic = 0;
		$.each(poiMarkers, function(j, val){
			if (!val.getIgnore() && val.lat() && val.lng()) {
				totalPoints++;
			}
		});
		
		$(settings.totalContainer).html(totalPoints);
		showMarkers();
	}

	function createMarkers(json) {
		var mapke = this.map;
		$.each(json, function(name, value) {
			
			//alle city's met succes op de kaart zetten
			//alle psoi's binnen de city's op de kaart zetten
			//vervolgens showMarkers() aanroepen -> binnen showmarkers afhankelijk van de activeview alle citymarkers of psoimarkers tonen met coordinaten binnen de viewport
			
			var pc = 0;
			var city = value.cName;
			
			if (value.vastgoed !== undefined && value.succes) {
				var PsOICount = value.vastgoed.length;
				
				$.each(value.vastgoed, function(nam, val) {
					var lat = val.lat;
					var lng = val.lng;
					var psoiHtml = "<p class='addr'><b>"+val.straat  +" "+ val.nummer +"<br /><span class='zwet'>"+ value.cZip +" "+ value.cName +"</span></b><br /><div class='gMapFotoWrapke'><a target='_parent' href='../detail.php?estateID="+val.props.id+"'><img class='iwpic' src='"+ val.props.pic + "' /></a></div><strong>"+ settings.txt.txtPrijs +":</strong> &euro; "+val.props.prijs +"<br /><a target='_parent' href='../detail.php?estateID="+val.props.id+"' class='deeskaartOptions smalerKaart'><b>"+ settings.txt.txtMeerinfo +"</b></a></p>";
					//var psoiHtml = city;
					if (lat && lng) {
						pc++;
						poiMarkers.push(new POIMarker(lat, lng, mapke, psoiHtml, lat + lng, val.props.type, infoWindow));
						$.each(val.props, function(i, vali){
							//alle props instellen
							poiMarkers[poiMarkers.length - 1][i] = vali;
						});
						poiMarkers[poiMarkers.length - 1].parentName = name;
					}
					
				});
				var cityHtml = "<p class=\"caps\"><strong>"+ value.cName +"<br />"+ settings.txt.txtBevat +" "+ pc +" "+ settings.txt.txtResultaten +"</p>";
				var cm = new CityMarker(value.lat, value.lng, mapke, cityHtml, name, pc, value.cName, infoWindow);
				cm.setTxtObj(settings.txt);
				cityMarkers.push(cm);
			}
		});//each
		correctMarking();	
	}
}
