﻿function AddSearchMarker(gv_x, gv_y, pos_x, pos_y, html)
{
    //theMap.addMarkersToMap2(gv_x, gv_y, pos_x, pos_y, html);

    var coords = {'x' : gv_x, 'y' : gv_y };
    var gvurl_grid_x = parseFloat(coords.x + (pos_x) / 256);
    var gvurl_grid_y = parseFloat(coords.y + (pos_y) / 256);


    var mapWindow = new MapWindow(html);

    // creates the marker
    var marker = new Marker(all_images, new XYPoint(gvurl_grid_x,gvurl_grid_y));
    theMap.addMarker(marker, mapWindow);
    
//    theMap.addMapWindow(mapWindow, new XYPoint(gvurl_grid_x,gvurl_grid_y));
    //theMap.centerAndZoomAtGVCoord(new XYPoint(gvurl_grid_x,gvurl_grid_y),1);
}

// ------------------------------------
//
//             MapWindow
//
// ------------------------------------

function MapWindow(text, options)
{
		this.text = text;
		this.options = options;
}

MapWindow.prototype.getGMapOptions = function()
{
		var width = 252;
		if (this.options && this.options.width)
				width = this.options.width;
				
		return {maxWidth: width};
}

GVMap.prototype.clickMarker = function(marker)
{
		// Simulate a GMap click event on the centre of this marker
		gvMapClickHandler(this, marker.gmarker, marker.gmarker.getPoint());
}

GVMap.prototype.addMarker = function(marker, mapWindow)
{
		if (this.GMap != null)
		{
				// Create the GMarker
				var markerImg = marker.icons[0];
				
				var gicon = new GIcon();
				gicon.image = markerImg.mainImg.URL;

				gicon.iconSize = new GSize(markerImg.mainImg.width, markerImg.mainImg.height);
				
				if (markerImg.shadowImg)
				{
						gicon.shadow = markerImg.shadowImg.URL;
						gicon.shadowSize = new GSize(markerImg.shadowImg.width, markerImg.shadowImg.height);
				}
				else
				{
						gicon.shadowSize = gicon.iconSize;
				}
						
				// Work out hotspot of marker
				var hotspotX = gicon.iconSize.width / 2;
				
				if (marker.options.horizontalAlign == "left")
						hotspotX = 0;
				else if (marker.options.horizontalAlign == "right")
						hotspotX = gicon.iconSize.width;
						
				var hotspotY = gicon.iconSize.height/ 2;
				
				if (marker.options.verticalAlign == "top")
						hotspotY = 0;
				else if (marker.options.verticalAlign == "bottom")
						hotspotY = gicon.iconSize.height;
						
				if (marker.options.offsetX != 0)
				    hotspotX += marker.options.offsetX;
				    
				if (marker.options.offsetY != 0)
				    hotspotY += marker.options.offsetY;
				    
						
				gicon.iconAnchor = new GPoint(hotspotX, hotspotY);
				
				// TODO: need to change this? It's probably ok for most cases
				gicon.infoWindowAnchor = gicon.iconAnchor;

				// Add the GMarker to the map
				var point = marker.gvCoord.GetGLatLng();
				
				// The GV marker 'owns' the GMarker, and we insert a link from GMarker
				// back to GV marker to assist callback/event processing
				var isClickable = false;
				if (mapWindow ||
						marker.options.centerOnClick || 
						marker.options.clickHandler ||
						marker.options.onMouseOverHandler ||
						marker.options.onMouseOutHandler)
				{
						// Mouse over/out events are not clicks, but if we're not clickable or draggable, then
						// GMaps doesn't send us any events.
						isClickable = true;
				}
						
				var markerZIndex = 0;
				
				if (marker.options.zLayer)
						markerZIndex = marker.options.zLayer;
						
				var gmarkeroptions = 
						{
								icon: gicon, 
								clickable: isClickable, 
								draggable: false,
								zIndexProcess: function() { return markerZIndex; }
						};
				
				marker.gmarker = new GMarker(point, gmarkeroptions);
				
				marker.gmarker.gvMarker = marker;
				
				if (mapWindow)
				{
						GEvent.addListener(marker.gmarker, "click", 
								function() 
								{
										marker.gmarker.openInfoWindowHtml(mapWindow.text, mapWindow.getGMapOptions());
										this.currentMapWindow = mapWindow;
								});
				}
				
				if (marker.options.onMouseOverHandler)
				{
						GEvent.addListener(marker.gmarker, "mouseover",
								function()
								{
										marker.options.onMouseOverHandler(marker);
								});
				}
				
				if (marker.options.onMouseOutHandler)
				{
						GEvent.addListener(marker.gmarker, "mouseout",
								function()
								{
										marker.options.onMouseOutHandler(marker);
								});
				}
				
				
				this.GMap.addOverlay(marker.gmarker);
				marker.gmarker.openInfoWindow(mapWindow.text,  mapWindow.options);
				
				
				
		}
}

GVMap.prototype.removeMarker = function(marker)
{
		if (this.GMap != null)
		{
				if (marker.gmarker)
				{
						this.GMap.removeOverlay(marker.gmarker);
						marker.gmarker = null;
				}
		}
}

GVMap.prototype.removeAllMarkers = function()
{
		if (this.GMap != null)
		{
				this.GMap.clearOverlays();
		}
}
GVMap.prototype.addMarkersToMap2 = function(gv_x, gv_y, pos_x, pos_y, html)
{
    var coords = {'x' : gv_x, 'y' : gv_y };
    var gvurl_grid_x = parseFloat(coords.x + (pos_x) / 256);
    var gvurl_grid_y = parseFloat(coords.y + (pos_y) / 256);

    var markerSet = [];
    var Mgr = this.GMarkerManager;
    var mapWindow = new MapWindow(html);
    var marker = new Marker(all_images, new XYPoint(gvurl_grid_x,gvurl_grid_y));
    theMap.addMarker(marker, mapWindow);
    
    markerSet.push(marker);
    Mgr.addMarkers(markerSet, gvConvertGVZoomToGMapZoom(4));
	Mgr.refresh();  
}

GVMap.prototype.addMarkersToMap = function(dataEnabledTiles, x, y)
{
	// Store this block of tile info
	this.dataMarkers[x][y] = dataEnabledTiles;
	
	var Mgr = this.GMarkerManager;
	var markerSet = [];
	
	for (i in dataEnabledTiles)
	{
		var tileInfo = dataEnabledTiles[i];
		
		if (tileInfo.dataEnabled == true)
		{
			// This tile is data enabled so add a marker to indicate this.
			var tileOffset = 0.15;
			var marker = this.createDataMarker(tileInfo.x + tileOffset, 
												tileInfo.y + tileOffset);
	
			markerSet.push(marker);
		}
	}
	
	if (markerSet.length > 0)
	{
		// >1 markers fetched, so add them to the map
		Mgr.addMarkers(markerSet, gvConvertGVZoomToGMapZoom(1), gvConvertGVZoomToGMapZoom(gvDataMarkerMaxZoom));
		Mgr.refresh();
	}
}


// ------------------------------------
//
//              Marker
//
// ------------------------------------

function Marker(icons, pos, options)
{
		this.icons = icons;
		this.gvCoord = pos;
		this.options= new MarkerOptions(options);
		
};

function MarkerOptions(options)
{
        this.offsetX=-2;
        this.offsetY=4;
		this.clickHandler=false;
		this.onMouseOverHandler=false;
		this.onMouseOutHandler=false;
		this.centerOnClick=false;
		this.autopanOnClick=true;
		this.autopanPadding=45;
		this.verticalAlign="middle";
		this.horizontalAlign="center";
		this.zLayer=0;
		
		if (options)
				Object.extend(this, options);
		
};

GVMap.prototype.createDataMarker = function(x, y)
{
		if (this.GMap != null)
		{
				// Create the GMarker
				var gicon = new GIcon();
				gicon.image = gvDataMarkerIcon;

				gicon.iconSize = new GSize(17, 45);
				gicon.shadowSize = gicon.iconSize;
						
				gicon.iconAnchor = new GPoint(8, 22);
				gicon.infoWindowAnchor = gicon.iconAnchor;

				var gmarkeroptions = 
						{
								icon: gicon, 
								clickable: false, 
								draggable: false
						};
				
				var gvPos = new XYPoint(x, y);
				var point = gvPos.GetGLatLng();
				
				var gmarker = new GMarker(point, gmarkeroptions);

		return gmarker;        
		}
		
		return null;
}





GVMap.prototype.getDataTileChunkPos = function(x, y)
{
	var xChunk = Math.floor(x / gvDataMarkerChunkSize) * gvDataMarkerChunkSize;
	var yChunk = Math.floor(y / gvDataMarkerChunkSize) * gvDataMarkerChunkSize;
	
	return {"x" : xChunk, "y" : yChunk };
}

GVMap.prototype.getDataTileInfo = function(x, y)
{
	var ChunkPos = this.getDataTileChunkPos(x, y);
	
	tilesInfo = this.dataMarkers[ChunkPos.x][ChunkPos.y];

	if (tilesInfo && (tilesInfo !== true))
	{
		for (i in tilesInfo)
		{
			var tileInfo = tilesInfo[i];
			
			if ((tileInfo.x == x) && (tileInfo.y == y))
			{
				// Found the right tile
				return tileInfo;
			}
		}
		
		// Tile is not data enabled
		return {"x": x, "y" : y, "dataEnabled" : false };
	}
	
	// tile not found - return error
	return {error: true};	
}

GVMap.prototype.ensureMarkersUpToDate = function()
{
	if (this.options && this.options.disableDataInfo)
	{
		// Data markers disabled
		return;
	}

	// Check zoom settings - if too far out, we don't do tile markers
	if (this.getCurrentZoomLevel() > gvDataMarkerMaxZoom)
	{
	    
		return;
	}	
	// Ok, work out which tile chunks are visible, and fetch any that we don't yet have
	var viewBounds = this.getViewportBounds();
	
	var xMin = viewBounds.xMin;
	var xMax = viewBounds.xMax;
	var yMin = viewBounds.yMin;
	var yMax = viewBounds.yMax;
	
	xMin = Math.floor(xMin / gvDataMarkerChunkSize) * gvDataMarkerChunkSize;
	yMin = Math.floor(yMin / gvDataMarkerChunkSize) * gvDataMarkerChunkSize;

	xMax = (Math.floor(xMax / gvDataMarkerChunkSize) + 1) * gvDataMarkerChunkSize;
	yMax = (Math.floor(yMax / gvDataMarkerChunkSize) + 1) * gvDataMarkerChunkSize;
	
	for (x = xMin; x <= xMax; x += gvDataMarkerChunkSize)
	{
		for (y = yMin; y <= yMax; y += gvDataMarkerChunkSize)
		{
			this.showMarkersForTile(x, y);
		}
	}
}

function gvAddDynamicScript(scriptURL, onLoadHandler)
{
		var script = document.createElement('script');
		script.src = scriptURL;
		script.type = "text/javascript";

		if (onLoadHandler)
		{
			// Install the specified onload handler

		// Need to use ready state change for IE as it doesn't support onload for scripts
		script.onreadystatechange = function () 
		{
//			alert(script.src + ": " + script.readyState);
		
			if ((script.readyState == 'complete')  || (script.readyState == 'loaded'))
			{
				onLoadHandler();
			}
		}

		// Standard onload for Firefox/Safari/Opera etc
		script.onload = onLoadHandler;
	}
			
		document.body.appendChild(script);
}


function gotoGVURL(x,y) 
{
		// Work out region co-ords, and local co-ords within region
		var int_x = Math.floor(x);
		var int_y = Math.floor(y);

		var local_x = Math.round((x - int_x) * 256);
		var local_y = Math.round((y - int_y) * 256);

		// Add a dynamic script to get this region name, and then trigger a URL change
		// based on the results
		var scriptURL = "https://cap.gridaverse.com/cap/0/b713fe80-283b-4585-af4d-a3b7d9a32492?var=gvRegionName&grid_x=" + int_x + "&grid_y="+ int_y;

		// Once the script has loaded, we use the result to teleport the user into GV    
		var onLoadHandler = function () 
		{
			if (gvRegionName.error)
			{
				alert("The co-ordinates of the GVURL (" + x + ", " + y + ") were not recognised as being in a SecondLife region.");
		}
		else
		{
					var url = "secondlife://" + gvRegionName.replace(/\s/, "_") + "/" + local_x + "/" + local_y;
	//      alert(url);
					document.location = url;
		}
		};

		gvAddDynamicScript(scriptURL, onLoadHandler);
}

