function MapApp (userSettings) {
	//TODO
		// AUTOMATISCH CENTREREN OP POI BIJ ZOOMEN VAN CITYLEVEL NAAR STREETLEVEL
		// PROVINCE CONTROLS INBRENGEN
	
	var settings = $.extend({
		canvas: $("div#mapCanvas")[0],
		dataSource:"mapAppData.php",
		totalContainer:"span#total",
		txt: {
			txtMeerinfo: "Meer info",
			txtPrijs: "Prijs",
			txtHierzoomen: "Zoom in",
			txtSluit: "Sluiten",
			txtBevat: "bevat",
			txtResultaten: "resultaten",
			txtLaden:"Bezig met laden..."
		},
		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() {
		
		$("body").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.31345, 4.58267), 10);
		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();
		
		var tm = 0;
		
		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;
			$("button#update").click();
			$(settings.totalContainer).html(poiMarkers.length);
			//alert(poiMarkers.length);
		}
		settings.onComplete();
		preloader.hidePreloader();
	}
	function filterMarkers () {
		var fd = 0;
		$.each(poiMarkers, function(i, value) {
			if (
			((value.prijs > filters.minPrice && value.prijs < filters.maxPrice) || !value.prijs) &&
			(value.soort === filters.hk) &&
			($.inArray(String(value.type), filters.types) != -1)
			) {
				fd++;
				value.setIgnore(false);
			}
			else {
				value.setIgnore(true);
			}
		});
		$("a#mapAppGem").click();
		//alert(fd);
		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;
		var page = "detail";
		if (String(document.location).search("nieuwbouw.php")>-1) {
			page = "Nieuwbouw_detail";
		}
		$.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 pandType;
					switch (val.props.type) {
						case "01":
							pandType = "Appartement";
							break;
						case "00":
							pandType = "Huis";
							break;
						case "07":
							pandType = "Grond";
							break;
						case "03":
							pandType = "Commercieel";
							break;
						case "05":
							pandType = "Garage";
							break;
						case "06":
							pandType = "Opbrengsteigendom";
							break;
						default:
							pandType = "Huis";
							break;
					}
					var num = pandType == "Grond" ? "":val.nummer;
					var psoiHtml = "<p class='addr'>";
					if (val.props.DisplayAddress == "1") {
						psoiHtml += "<b>"+val.straat  +" "+ num +"<br /><span class='zwet'>"+ value.cZip +" "+ value.cName +"</span></b>";
					}
					psoiHtml += "<br /><div class='gMapFotoWrapke'><a href='http://www.huva.be/"+ page +".php?id="+val.props.id+"'><img class='iwpic' src='"+ val.props.pic + "' /></a></div><strong>"+ (val.props.soort == "L" ? "Te Huur": "Te Koop") +":</strong> &euro; "+val.props.prijs +"<br /><a href='http://www.evosys.be/Virtual/huva/nieuw/"+ page +".php?id="+val.props.id+"' class='deeskaartOptions smalerKaart'><b>"+ settings.txt.txtMeerinfo +"</b></a><span class='mapTypeke'>&nbsp;"+ pandType +"</span></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();	
	}
}
