var map;
var lat = 59.5;
var lng = 18;
var zoom = 9;

var baseUrl = '';
var userUrl = '';
var addUrl = '';

function SetBaseUrl(url) {
	baseUrl = url;
}

function SetUserId(userId) {
	if (userId != '' && userId > 0) {
		userUrl = userId+'/'
	}
	else {
		userUrl = "";
	}
}

function SetAddUrl(add) {
	addUrl = add+".jpg";
}

function initialize(mapElementId) {
	if (GBrowserIsCompatible()) {
		map = new GMap2(document.getElementById(mapElementId));
		CenterMap(lat, lng, zoom);
		map.addControl(new GLargeMapControl());
		map.addControl(new GMapTypeControl());
		map.addControl(new GScaleControl());
		map.setMapType(G_HYBRID_MAP);
		changed_view(1); // Show start points
		// Happens repeatedly when dragging...
		GEvent.addListener(map, "move", function() {
			dragging_move();
		});
		// Data is updated when these Events happen:
		GEvent.addListener(map, "moveend", function() {
			dragging_ended();
		});
		GEvent.addListener(map, "zoomend", function() {
			var zoom = map.getZoom()
			var intZoomTxt = document.getElementById("intZoom");
			if (intZoomTxt != undefined && intZoomTxt != null) {
				intZoomTxt.value = zoom;
			}
			changed_view(1);
		});
	}
}

function CenterMap(lngNew, latNew, zoomNew) {
	if (GBrowserIsCompatible()) {
		if (map != null) {
			map.setCenter(new GLatLng(latNew, lngNew), zoomNew);
		}
		else {
			lng = lngNew;
			lat = latNew;
			zoom = zoomNew;
		}
	}
}

// - - - Updating of moves, dragging and end-of-drag:
var time_last_drag_move = -1;
var time_diff_drag_abs	= 1100;		// 1.1 of a second (I think).
var old_drag_lon = -1;
var old_drag_lat = -1;

var lastZoom = -1;
var lastBounds;
// Important -- stores shown data pts.
var cached_Mks = {};

function dragging_move() {
	var now = new Date();
	now = now.getTime();
	if (now - time_last_drag_move > time_diff_drag_abs) {
		changed_view(0);
		time_last_drag_move = now;
		return;
	}
}

function dragging_ended() {
	time_last_drag_move = -1;
	changed_view(0);
}

function changed_view(zoomp) {
	var bounds = map.getBounds();
	var southWest = bounds.getSouthWest();
	var nE = bounds.getNorthEast();
	// Seems to send events for both zoom and move when zooming, so
	// zoom event is probably not needed. But take it anyway so it
	// works if changes...
	if (map.getZoom() == lastZoom && typeof(lastBounds) == 'object') {
		var tmp = lastBounds.getSouthWest();
		// If size changes, should change all 4 points?
		if (southWest.lng()==tmp.lng() && southWest.lat()==tmp.lat()) {
			tmp = lastBounds.getNorthEast();
			if (nE.lng() == tmp.lng() && nE.lat() == tmp.lat()) {
				return;
			}
		}
	}
	if (zoomp) {
		// Throw away all data when changing zoom:
		clear_all_overlays();
	}
	// Remember old:
	lastBounds = new GLatLngBounds(southWest, nE);
	lastZoom  = map.getZoom();
	var bounds = map.getBounds();
	var southWest = bounds.getSouthWest();
	var northEast = bounds.getNorthEast();
	get_json_pts('ne='+ northEast.toUrlValue() + '&sw='	+ southWest.toUrlValue());
}

function clear_all_overlays() {
	map.clearOverlays();
	cached_Mks = {};
}

function get_json_pts(area) {
	//var request = GXmlHttp.create(); (Didn't work...)
	var request = mk_xmlhttpreq();
	// Handle set names!!
	var urltxt  = baseUrl+'points.php?' + area + '&z=' + map.getZoom(); 

	request.open('GET',urltxt , true);
	request.onreadystatechange = mkUpdateFun(request);
	request.send(null);
}

// Create Google Marker:
var zoffset = 0;
// Z index idea from Esa Ilmari and (as usual) econym.demon.co.uk
function mkMarker(point, tag, opts, url, multi) {
	var marker;
	var icon	= opts['icon'];
	// - - - Make GMarker object (with options):
	var markerOptions = {};
	if (opts['z']) {
		var z = opts['z'];
		markerOptions['zIndexProcess']= function(marker,b) {
			zoffset++;
			return z * (10000000 + zoffset);
		};
	}
	if (tag)  { markerOptions['title']= tag; }
	if (icon) { markerOptions['icon'] = icon; }
	marker = new GMarker(point, markerOptions);

	if (url != null) {
		GEvent.addListener(marker, "click", function() {
			document.location.href=url;
		});
	}

	if (multi != null) {
		GEvent.addListener(marker, "click", function() {
			marker.openInfoWindowHtml(multi);
		});
	}

	return marker;
}

// Icon stuff:
var aggregI, multipI;
function getAggregIcon(pt) {
	if (pt.typ != '+' && pt.intImageID > 0) {
		var url = baseUrl+'files/settings/albums/'+pt.varAlbumName+'/'+pt.intImageID+addUrl;
		aggregI = new GIcon(G_DEFAULT_ICON, url);
		aggregI.iconSize = GSize(30, 30);
		aggregI.shadow = '';
	} else {
		var url = baseUrl+"img/icons/red/"+pt.varFileName;
		aggregI = new GIcon(G_DEFAULT_ICON, url);
		aggregI.iconSize = GSize(30, 30);
	}

	return aggregI;
}

function getMultiPtIcon(pt) {
	multipI = new GIcon(G_DEFAULT_ICON, baseUrl+"img/gmap/blank-green.png");
	if (pt.typ != '+' && pt.intImageID > 0) {
		var url = baseUrl+'files/settings/albums/'+pt.varAlbumName+'/'+pt.intImageID+addUrl;
		multipI = new GIcon(G_DEFAULT_ICON, url);
		multipI.iconSize = GSize(30, 30);
		multipI.shadow = '';
	}

	if (pt.icon != "") {
		var url = PROJECT_URL+'/img/icons/green/'+pt.icon;
		multipI = new GIcon(G_DEFAULT_ICON, url);
		multipI.iconSize = GSize(30, 30);
	}

	return multipI;
}

// Used to get a unique ID on every op. (If move map twice, so a second
// move is started before last one is finished.)
var uppdateID = 1;
var presentUpd=-1;

function mkUpdateFun(request) {
	var localUpdate = ++uppdateID;
	var f = function() {
		if (request.readyState != 4) { return; }

		// If moves twice before has time to update...
		//if (localUpdate != uppdateID) { return 0; }
		var now = new Date();
		now = now.getTime() % 1000000;
		if (presentUpd > localUpdate) {
			// A later update has already been received...
			return 0;
		}
		presentUpd = localUpdate;
		var jscript = request.responseText;	// (From server.)
		var points  = undefined;
		eval(jscript);						// Set value in 'points'.
		// (Used in loop below, probably faster to get value once.)
		var zoomnow = map.getZoom();
		// N B -- do ugly thing by replacing point info w Marker...
		for (i in points) {
			if (points.errormsg) {
			    delete points;
			    continue;
			}

			if (cached_Mks[i]) {
				// This pt is already visible on map. Don't
				// do anything.
				points[i] = cached_Mks[i];
				cached_Mks[i] = null;
				continue;
			}
			if (points[i].lat > 89.99) { continue; } // Garbage.
			var aggIcon = getAggregIcon(points[i]);
			var mulIcon = getMultiPtIcon(points[i]);
			var m;
			var pll = new GLatLng(points[i].lat,points[i].lon);
			if (points[i].typ == '+') {
				// Multiple-points-Icon
				m = mkMarker(pll, points[i].t, { icon: aggIcon }, null, points[i].multi);
			} else {
				// Handle other types differently. Normal Icon.
				m = mkMarker(pll, points[i].t, { icon: mulIcon}, (adminMode) ? points[i].admurl : points[i].url, null);
			}
			// N B -- Overwrites spec of pt.
			points[i] = m;
			map.addOverlay(m);
		}

		// Delete Markers that aren't visible anymore:
		for (i in cached_Mks) {
			var marker = cached_Mks[i];		// Can be set to null above
			if (marker) { map.removeOverlay(marker); }
		}
		cached_Mks = points;
	};

	return f;
}

// Monopolists have business motivation not to work with standards,
// so they aren't compatible with anyone but themselves.
function mk_xmlhttpreq () {
	var xh = GXmlHttp.create();
	if (xh != null) { return xh; }
	// Std IExploder:
	try {
		xh = new ActiveXObject("Msxml2.XMLHTTP");
		return xh;
	} catch (e) { }
	try {
		xh = new ActiveXObject("Microsoft.XMLHTTP");
		return xh;
	} catch (e) { }
	try {
		xh = new XMLHttpRequest();
		return xh;
	} catch (e) { }
	// Only other way I could find...
	try {
		xh = window.createRequest();
		return xh;
	} catch (e) { }
	return undefined;
}

//Checking for IE8. In this funny brower click on map returns wrong coordinates of clicked point :)
function IsClickAllowed() {
		var ua = navigator.userAgent.toLowerCase();
		return !(ua.indexOf("msie 8.0") != -1 && ua.indexOf("opera") == -1); 
	}
