﻿var getElement = function(id){ return (document.all ? document.all[id] : document.getElementById(id)); }

var mapManager = function(o){ if(this.init){ this.init(o); } };
mapManager.prototype = {
	map:null,
	id:null,
	mapelement:null,
	markers:null,
	markersQueue:null,
	mapSettings:null,
	mapBounds:null,
	resize:false,
	controls:null,
	bgcolor:null,
	attachInfoWindow:null,
	useLoader:false,
	lat:null,
	lon:null,
	init: function(o){
		this.markers = new Object();
		if(o.id){ this.id = o.id; }
		if(o.resize){ this.resize = o.resize; }
		if(o.bgcolor){ this.bgcolor = o.bgcolor; }
		if(o.lat){ this.lat = o.lat; }
		if(o.lon){ this.lon = o.lon; }
		if(o.attachInfoWindow){ this.attachInfoWindow = o.attachInfoWindow; }
		if(o.smallcontrols){ this.controls = ["GSmallZoomControl3D"]; }
		else{ this.controls = ["GLargeMapControl3D","GMapTypeControl"]; }
		if(o.useLoader){
			this.useLoader = o.useLoader;
			this.markersQueue = new Array();
		}
	},
	resetMap: function(){
		if(this.map){ this.map.clearOverlays(); }
		this.markers = new Object();
		this.mapBounds = null;
	},
	createMap: function(latitude, longitude){
		if(this.useLoader){
			var mgr = this;
			google.load("maps", "2", {callback: function(){
				mgr.doCreateMap(latitude, longitude);
				mgr.loadMarkersQueue();
			}});
		}
		else{ this.doCreateMap(latitude, longitude); }
	},
	doCreateMap: function(latitude, longitude){
		if(latitude != null){ this.lat = latitude; }
		if(longitude != null){ this.lon = longitude; }
		if(!this.map && this.id && GBrowserIsCompatible()){
			this.mapelement = getElement(this.id);
			if(!this.mapelement){ return; }
			this.map = new GMap2(this.mapelement,{backgroundColor:this.bgcolor});
			for(var i = 0; this.controls != null && i < this.controls.length; i++){
				this.map.addControl(eval("new " + this.controls[i] + "()"));
			}
			if(this.lat != null && this.lon != null){ this.map.setCenter(new GLatLng(this.lat, this.lon), 7); }
		}
	},
	moveTo: function(latitude, longitude){
		if(this.map){
			this.map.closeInfoWindow();
			this.map.checkResize();
			this.map.panTo(new GLatLng(latitude, longitude));
		}
	},
	loadMarkersQueue: function(){
		if(this.markersQueue){
			var count = this.markersQueue.length;
			while(this.markersQueue.length > 0 && count > 0){
				var o = this.markersQueue.pop();
				count--;
				this.updateMarkers(o);
			}
			this.renderMapBounds();
		}
	},
	updateMarkers: function(o){
		if(this.useLoader && !this.map){ this.markersQueue.push(o); }
		if(!o || !this.map){ return; }
		if(!this.markers[o.id]){
			var icon = new GIcon();
			icon.image = o.img;
			icon.iconSize = new GSize(o.width, o.height);
			icon.iconAnchor = new GPoint(o.width/2, o.height);
			icon.infoWindowAnchor = new GPoint(o.width/2, o.height);
			this.markers[o.id] = new GMarker(new GLatLng(o.lat, o.lon), {clickable:true, icon:icon, title:o.title});
			this.map.addOverlay(this.markers[o.id]);
			if(this.resize){ this.extendMapBounds(new GLatLng(o.lat, o.lon)); }
		}
		var marker = this.markers[o.id];
		if(marker){
			marker.closeInfoWindow();
			if(!o.visible){ marker.hide(); }
			else{ marker.show(); }
			if(this.attachInfoWindow){
				this.attachInfoWindow(this.map, marker, o.html);
			}
			else{
				var mgr = this;
				marker.showInfoWindow = function(e){
					if(e == true && mgr.mapelement){ mgr.mapelement.scrollIntoView(); }
					mgr.map.openInfoWindowHtml(marker.getLatLng(),'<div class="googleMapResult">' + o.html + '</div>');
				};
				GEvent.addListener(marker, 'click', marker.showInfoWindow);
			}
		}
		return marker;
	},
	addMarker: function(o){
		if(!o || !this.map){ return; }
		var icon = new GIcon();
		icon.image = o.img;
		icon.iconSize = new GSize(o.width, o.height);
		var anchor = (o.left != null && o.top != null ? new GPoint(o.left, o.top) : new GPoint(o.width/2, o.height));
		icon.iconAnchor = anchor;
		icon.infoWindowAnchor = anchor;
		var marker = new GMarker(new GLatLng(o.lat, o.lon), {clickable:true, icon:icon, title:o.title});
		this.map.addOverlay(marker);
		if(marker){
			marker.closeInfoWindow();
			if(this.attachInfoWindow){
				this.attachInfoWindow(this.map, marker, o.html);
			}
			else{
				var mgr = this;
				marker.showInfoWindow = function(e){
					if(e == true && mgr.mapelement){ mgr.mapelement.scrollIntoView(); }
					mgr.map.openInfoWindowHtml(marker.getLatLng(),o.html);
				};
				GEvent.addListener(marker, 'click', marker.showInfoWindow);
			}
		}
		return marker;
	},
	showMarker: function(id){
		var marker = this.markers[id];
		if(marker){ marker.show(); }
	},
	hideMarker: function(id){
		var marker = this.markers[id];
		if(marker){ marker.hide(); }
	},
	extendMapBounds: function(point){
		if(this.map){
			if(!this.mapBounds){ this.mapBounds = new GLatLngBounds(point, point); }
			else{ this.mapBounds.extend(point); }
		}
	},
	renderMapBounds: function(){
		if(this.map && this.mapBounds){
			this.map.checkResize();
			var zoomRect = this.mapBounds;
			var zoomLevel = this.map.getBoundsZoomLevel(zoomRect);
			var ne = zoomRect.getNorthEast();
			var sw = zoomRect.getSouthWest();
			var centerPoint = zoomRect.getCenter();
			this.map.setZoom((zoomLevel > 6 ? 6 : zoomLevel));
			this.map.panTo(centerPoint);
			this.map.setCenter(centerPoint);
			var neBounds = this.map.fromLatLngToDivPixel(ne);
			if(neBounds.y < 34){
				var swBounds = this.map.fromLatLngToDivPixel(sw);
				var sizeMap = this.map.getSize();
				var yDiff = sizeMap.height - (swBounds.y + 1);
				if(yDiff > 34){ yDiff = 33; }
				if(yDiff > 0){ this.map.panBy(new GSize(0, yDiff)); }
			}
		}
	},
	checkResize: function(){
		if(this.map){ this.map.checkResize(); }
	}
}
