﻿var map, geocoder = null; 
var centerLatitude = 0.0;
var centerLongitude = 0.0; 
var startZoom = 1;
var lineColor=0;//'FF6633'
var deselectCurrent = function() {};
var removePolyline = function() {};
var diagramType = 0; // 0=polyline, 1=polygon
var activeMap = 0;
var menuActive = 0;
var activeMarker;
var earthRadius = 6378137; // in metres
var mapRightClickListener;
var mapClickListener;
var overMenuFlag;
var currRightClickMenu;
var activeDiv;
var polygonDiv;
var latlngs = [];
var icon;
var param1;
var selection = "";

function formatLat(value)
	{
	var val = value.toFixed(6);

	if (value >= 0.0)
		{
		if (value >= 10.0)
			{
			return "+" + val;
			}
		else
			{
			return "+0" + val;
			}
		}
	else
		{
		val = -val;
		if (value > -10.0)
			{
			return "-0" + val;
			}
		else
			{
			return "-" + val;
			}
		}
	}

function formatLng(value)
	{
	var val = value.toFixed(6);
//	return val;

	if (value > 0.0)
		{
		if (value >= 100.0)
			{
			return "+" + val;
			}
		else if (value >= 10.0)
			{
			return "+0" + val;
			}
		else
			{
			return "+00" + val;
			}
		}
	else
		{
		val = -val;
		if (value <= -100.0)
			{
			return "-" + val;
			}
		else if (value <= -10.0)
			{
			return "-0" + val;
			}
		else
			{
			return "-00" + val;
			}
		}
	}

function saveData()
	{
	var points = latlngs.length;
	var ctext = "";
	var lat;
	var lng;

	for (var i=0; i<points; i++)
		{
		lat = latlngs[i].lat();
		lng = latlngs[i].lng();

		ctext += formatLat(lat) + formatLng(lng) + "/";
		}

	// Area ends with a slash
	if (diagramType == 1)
		{
		ctext = "/" + ctext;
		}

	var target = document.getElementById("latlng");
	if (target) target.value = ctext;
//	window.opener.saveCoordinates(ctext);
	}

// anticipates two 3-element arrays representing 3d vectors, returns a 3-element array representing their cross-product
function crossProduct(a, b) {
	return [(a[1] * b[2]) - (a[2] * b[1]), 
			(a[2] * b[0]) - (a[0] * b[2]), 
			(a[0] * b[1]) - (a[1] * b[0])];
}

// anticipates two 3-element arrays, returns scalar value
function dotProduct(a, b) {
	return (a[0] * b[0]) + (a[1] * b[1]) + (a[2] * b[2]);
}

function spherePointAngle(A, B, C) { // returns angle at B
    return Math.atan2(dotProduct(crossProduct(C, B), A), dotProduct(crossProduct(B, A), crossProduct(B, C)));
}

// returns 3-element array representing cartesian location of a point given by a GLatLng object
function cartesianCoordinates(latlng) {
    var x = Math.cos(latlng.latRadians()) * Math.sin(latlng.lngRadians());
    var y = Math.cos(latlng.latRadians()) * Math.cos(latlng.lngRadians());
    var z = Math.sin(latlng.latRadians());
	return [x, y, z];
}

// Calculate area inside of polygon, in square metres
function polylineArea(latlngs) {
	var id, sum = 0, pointCount = latlngs.length, cartesians = [];
	if (pointCount < 3) return 0;
	
	for (id in latlngs) {
	    cartesians[id] = cartesianCoordinates(latlngs[id]);
	}
	
	// pad out with the first two elements
	cartesians.push(cartesians[0]);
	cartesians.push(cartesians[1]);
		
	for(id = 0; id < pointCount; id++) {
		var A = cartesians[id];
		var B = cartesians[id + 1];
		var C = cartesians[id + 2];
		sum += spherePointAngle(A, B, C);
	}

	var alpha = Math.abs(sum - (pointCount - 2) * Math.PI);
    alpha -= 2 * Math.PI * Math.floor(alpha / (2 * Math.PI));
    alpha = Math.min(alpha, 4 * Math.PI - alpha);    	
    
    return Math.round(alpha * Math.pow(earthRadius, 2));
}
function deleteMarker() 
	{
//	alert(activeMarker);
	map.removeOverlay(activeMarker);
	latlngs.splice(activeMarker.ID,1);
	redrawPolyline();
	menuActive=0;
	}
	
function changeActiveStatus(state)
	{
	activeMap=state;
	if (activeMap!=0) activeDiv.firstChild.nodeValue='Active';
	else activeDiv.firstChild.nodeValue='InActive';
	redrawPolyline() 
	}
function initializePoint(id) 
	{
	icon = new GIcon();
	icon.image = "http://www.fieldjournal.org/gmap/box.png";
	icon.iconSize = new GSize(11,11);
	icon.iconAnchor = new GPoint(6,6);

	var markerOptions =
		{
		draggable: true,
		icon: icon
		};

	var marker = new GMarker(latlngs[id],markerOptions);
	
//	latlngs[id].GMarker=marker;
	marker.ID=id;
	var listItem = document.createElement('li');
	var listItemLink = listItem.appendChild(document.createElement('a'));
	listItemLink.href = "#";
	listItemLink.innerHTML = '<strong>' + id + ". " + latlngs[id].lat() + ',' + latlngs[id].lng() + '</strong>';
	listItemLink.listID=id;
//	var listItemDelete = listItem.appendChild(document.createElement('a'));
//	listItemDelete.href = "#";
//	listItemDelete.innerHTML = "<button onclick=deleteMarker>Delete</button>";
	
	var focusPoint = function() 
		{
		deselectCurrent();
		listItem.className = 'current';
		deselectCurrent = function() { listItem.className = ''; }
		map.panTo(latlngs[id]);
		return false;
		}
	listItemLink.onclick = focusPoint;
//	listItemDelete.onclick = deleteMarker;

//	document.getElementById('sidebar-list').appendChild(listItem);

	map.addOverlay(marker);  
	
	marker.enableDragging();
	GEvent.addListener(marker, 'dragend', function() 
		{
    	listItemLink.innerHTML = '<strong>' + listItemLink.listID + ". " + latlngs[id].lat() + ',' + latlngs[id].lng() + '</strong>';
//		listItemDelete.innerHTML = "<button onclick=deleteMarker>Delete</button>";
		latlngs[id] = marker.getPoint();
		redrawPolyline();
		});
	}
function handleMapDoubleClick(marker, latlng) 
	{
//	alert('DblClk');
	}

function handleMapClick(marker, latlng) 
	{
	if (!marker && activeMap!=0 && menuActive==0) 
		{
		latlngs.push(latlng);		
		initializePoint(latlngs.length - 1);
		redrawPolyline();
		}
	}
function handleLineClick(latlng) 
	{
	var i;
	
	if (activeMap!=0 && menuActive==0)
		{
//	map.openInfoWindowHtml(latlng,"<h4> 1 px </h4>" + latlng)
		for (i=0; i<latlngs.length-1; ++i)
			{
			var ll1= new GLatLng(Math.min(latlngs[i].lat(),latlngs[i+1].lat()),Math.min(latlngs[i].lng(),latlngs[i+1].lng()));
			var ll2= new GLatLng(Math.max(latlngs[i].lat(),latlngs[i+1].lat()),Math.max(latlngs[i].lng(),latlngs[i+1].lng()));
			var rect = new GLatLngBounds(ll1,ll2);

			if (rect.containsLatLng(latlng))
				{
				latlngs.splice(i+1,0,latlng);
				initializePoint(i+1);
				redrawPolyline();
				return;
				}
			}
		latlngs.splice(1,0,latlng);
		initializePoint(1);
		redrawPolyline();
		}
	}

function removeChildren(s) { while (s.hasChildNodes()) { s.removeChild(s.childNodes[0]); }}

function redrawPolyline() 
	{
	var pointCount = latlngs.length;
	var id;
	var polyline;

	var lineColor = '#00aa00';
	var fillColor = '#00ff00';

	map.clearOverlays();

	// Plot polyline, adding the first element to the end, to close the loop.
	if (diagramType==1)
		{
		latlngs.push(latlngs[0]);
		polyline = new GPolygon(latlngs, lineColor, 5, 0.8, fillColor, 0.3);
		}
	else
		{
		polyline = new GPolyline(latlngs, lineColor, 5, 0.8);
		}

	map.addOverlay(polyline);
	GEvent.addListener(polyline,'click',handleLineClick);
	
	if (activeMap==1)
		{
		for (id = 0; id < pointCount; id++) 
			{
			initializePoint(id);
			}
		}

	// Calculate total length of polyline (length for 2, perimeter for > 2)
	if (pointCount >= 2) 
		{
		var length = 0;
		for(id = 0; id < pointCount; id++) 
			{
			length += latlngs[id].distanceFrom(latlngs[id + 1]);
			}
		}

	if (diagramType == 1)
		latlngs.pop();
    
	removePolyline(); // zap old polyline
	
	// set us up to zap the current polyline when we draw the next one.
	removePolyline = function()
		{
		map.removeOverlay(polyline);
		}	
	}


function redrawPolyline2() 
	{
	var pointCount = latlngs.length;
	var id;
	var polyline;

	var lineColor = '#00aa00';
	var fillColor = '#00ff00';
//	var lineColor = '#0000ff';
//	var fillColor = '#0000ff';

//	removeChildren(document.getElementById('sidebar-list'));
//	document.getElementById('sidebar-list').childNodes.splice(0,pointCount);
	map.clearOverlays();
    // Plot polyline, adding the first element to the end, to close the loop.
	if (diagramType==1)
		{
		latlngs.push(latlngs[0]);
//    var polyline = new GPolyline(latlngs, lineColor, 2, 0.8);
//		polyline = new GPolygon(latlngs, lineColor, 2, 0.8, 'CCCCCC', 0.5);
		polyline = new GPolygon(latlngs, lineColor, 5, 0.8, fillColor, 0.3);
		}
	else
		{
		polyline = new GPolyline(latlngs, lineColor, 5, 0.8);
		}
//	polyline.click = "handlePolylineClick";
    map.addOverlay(polyline);
	GEvent.addListener(polyline,'click',handleLineClick);
	
	if (activeMap==1)
		{
		for (id = 0; id < pointCount; id++) 
			{
			initializePoint(id);
			}
		}
    // Calculate total length of polyline (length for 2, perimeter for > 2)
    if (pointCount >= 2) 
		{
        var length = 0;
        for(id = 0; id < pointCount; id++) 
			{
            length += latlngs[id].distanceFrom(latlngs[id + 1]);
			}

/*
        if (pointCount > 2) {
            document.getElementById('length-title').innerHTML = 'Perimeter';
            document.getElementById('length-data').innerHTML = Math.round(length) / 1000;
        } else {
            document.getElementById('length-title').innerHTML = 'Length';
            document.getElementById('length-data').innerHTML = Math.round(length) / 2000;
        }
*/
    }
	if (diagramType==1)
		latlngs.pop();
    
/*
    if (pointCount >= 3) {
        document.getElementById('area-data').innerHTML = polylineArea(latlngs) / 1000000; // show value in square km.
	}
*/	
	removePolyline(); // zap old polyline
	
	// set us up to zap the current polyline when we draw the next one.
	removePolyline = function() {
	  map.removeOverlay(polyline);
	}	
}

function windowHeight() 
	{
	// Standard browsers (Mozilla, Safari, etc.)
	if (self.innerHeight)
		return self.innerHeight;
	// IE 6
	if (document.documentElement && document.documentElement.clientHeight)
		return document.documentElement.clientHeight;
	// IE 5
	if (document.body)
		return document.body.clientHeight;
	// Just in case.
	return 0;
	}
function addMapRightClickListener() 
	{
	if (mapRightClickListener == null) 
		{
		mapRightClickListener = GEvent.addListener(map, "singlerightclick", function(point, src, overlay) 
			{
//				map.openInfoWindowHtml(point,"<h4> 1 px </h4>" + point)
//			if (activeMap!=0)
				{
				currMarker = overlay;
				activeMarker=overlay;
//				activeMap=0;
				menuActive=1;
				currRightClickMenu = new RightClickMenu(currMarker.getPoint(),currMarker.roomId, currMarker.roomNumber);
				map.addOverlay(currRightClickMenu);
				}
			});
		}
	}

function addMapClickListener() 
	{
	if (mapClickListener == null) 
		{
		mapClickListener = GEvent.addListener(map, "click", function(overlay, point) 
			{
			var onMenu = overMenuFlag;
			var menu = currRightClickMenu;
			if (menu != null && !onMenu) 
				{
				removeRightClickMenu();
				} // if
			menuActive=0;
			});
		} // if
	} // func

function removeRightClickMenu() 
	{
	if (currRightClickMenu != null) 
		{
		map.removeOverlay(currRightClickMenu);
		currRightClickMenu = null;
		overMenuFlag = false;
		}
//	activeMap=1;
	menuActive=0;
	}

function RightClickMenu(point) 
	{
	this.latlng_ = point;
	}

	RightClickMenu.prototype = new GOverlay();
	RightClickMenu.prototype.initialize = function(map) 
		{
//		if (activeMap!=0)
			{
			var div = document.createElement("div");
			div.style.backgroundColor = "white";
			div.style.position = "absolute";
			
			var table = document.createElement("table");
			table.style.border = "1px solid blue";
			var deleteRow = table.insertRow(0);
			var deleteCol = deleteRow.insertCell(0);
			deleteCol.style.fontFamily = "arial";
			deleteCol.style.fontSize = "11px";
			deleteCol.style.color = "blue";
			deleteCol.style.whiteSpace = "nowrap";
			deleteCol.innerHTML = "Poista";
			GEvent.addDomListener(deleteCol, "click", function() { deleteMarker(); removeRightClickMenu(); });
			GEvent.addDomListener(deleteCol, "mouseover", function() {
				deleteCol.style.backgroundColor = "#AAE281";
				overMenuFlag = true;
			});
			GEvent.addDomListener(deleteCol, "mouseout", function() {
				deleteCol.style.backgroundColor = "white";
				overMenuFlag = false;
			});
/*
			var moveRow = table.insertRow(1);
			var moveCol = moveRow.insertCell(0);
			moveCol.style.fontFamily = "arial";
			moveCol.style.fontSize = "11px";
			moveCol.style.color = "blue";
			moveCol.style.whiteSpace = "nowrap";
			moveCol.innerHTML = "Move marker";
			//GEvent.addDomListener(moveCol, "click", function() {
				//pickUpRoomMarker();
			//});
			GEvent.addDomListener(moveCol, "mouseover", function() {
				moveCol.style.backgroundColor = "#AAE281";
				overMenuFlag = true;
			});
			GEvent.addDomListener(moveCol, "mouseout", function() {
				moveCol.style.backgroundColor = "white";
				overMenuFlag = false;
			});
*/					
			div.appendChild(table);
	 
			var pane = map.getPane(G_MAP_FLOAT_PANE);
			pane.appendChild(div);
			this.map_ = map;
			this.div_ = div;
			}
	}

	RightClickMenu.prototype.remove = function() {
	  this.div_.parentNode.removeChild(this.div_);
	}

	RightClickMenu.prototype.copy = function() {
	  return new RightClickMenu(this.latlng_);
	}

	RightClickMenu.prototype.redraw = function(force) {
	  if (!force) return;
	  var topLeftPixel = this.map_.fromLatLngToDivPixel(this.latlng_);
	  var top = topLeftPixel.y - 44;
	  var div = this.div_;
	  div.style.top = top + "px";
	  div.style.left = topLeftPixel.x + "px";
	}
	
// A TextualZoomControl is a GControl that displays textual "Zoom In"
// and "Zoom Out" buttons (as opposed to the iconic buttons used in
// Google Maps).
// We define the function first
function TextualZoomControl()
	{
	}

// To "subclass" the GControl, we set the prototype object to
// an instance of the GControl object
TextualZoomControl.prototype = new GControl();

// Creates a one DIV for each of the buttons and places them in a container
// DIV which is returned as our control element. We add the control to
// to the map container and return the element for the map class to
// position properly.
TextualZoomControl.prototype.initialize = function(map)
{
  var container = document.createElement("div");

  activeDiv = document.createElement("div");
  this.setButtonStyle_(activeDiv);
  container.appendChild(activeDiv);
  activeDiv.appendChild(document.createTextNode("Aloita piirto"));
  GEvent.addDomListener(activeDiv, "click", function() 
	{ 
	activeMap=(activeMap == 0);
	if (activeMap != 0) 
		{
		activeDiv.firstChild.nodeValue='Piirto valmis';
		}
	else 
		{
		activeDiv.firstChild.nodeValue='Jatka piirtoa';
		
		// walk through markers and do something to them
//		var marker = map.getFirstMarker();
//		while (marker != null)
			{
//			marker.hide();
//			marker = map.getNextMarker();
			}
		}

	saveData();
	redrawPolyline() 
	});

  polygonDiv = document.createElement("div");
  this.setButtonStyle_(polygonDiv);
  container.appendChild(polygonDiv);
  polygonDiv.appendChild(document.createTextNode("Muuta alueeksi"));
  GEvent.addDomListener(polygonDiv, "click",
	function()
		{
		diagramType = (diagramType == 0);

		if (diagramType != 0) 
			{
			polygonDiv.firstChild.nodeValue='Muuta reitiksi';
			}
		else
			{
			polygonDiv.firstChild.nodeValue='Muuta alueeksi';
			}

		saveData();
		redrawPolyline();
		}
	);

/*
  var polylineDiv = document.createElement("div");
  this.setButtonStyle_(polylineDiv);
  container.appendChild(polylineDiv);
  polylineDiv.appendChild(document.createTextNode("Tallenna"));
  GEvent.addDomListener(polylineDiv, "click", function() { saveData(); });
*/
  
  map.getContainer().appendChild(container);
  return container;
}

// By default, the control will appear in the top left corner of the
// map with 7 pixels of padding.
TextualZoomControl.prototype.getDefaultPosition = function() {
  return new GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(7, 37));
}

// Sets the proper CSS for the given button element.
TextualZoomControl.prototype.setButtonStyle_ = function(button) {
  button.style.textDecoration = "underline";
  button.style.color = "#0000cc";
  button.style.backgroundColor = "white";
  button.style.font = "small Arial";
  button.style.border = "1px solid black";
  button.style.padding = "2px";
  button.style.marginBottom = "3px";
  button.style.textAlign = "center";
  button.style.width = "10em";
  button.style.cursor = "pointer";
}

function handleResize() {

//	var height = windowHeight() - document.getElementById('toolbar').offsetHeight - 100;
	var height = windowHeight();
	document.getElementById('map').style.height = height + 'px';
//	document.getElementById('sidebar').style.height = height + 'px';

}

function changeBodyClass(from, to) {
     document.body.className = document.body.className.replace(from, to);
     return false;
}

function init2()
	{
	}

function init()
	{
	_mSvgEnabled = false; // Firefox 1.5.0.4/Mac wasn't rendering the SVG.

	map = new GMap2(document.getElementById("gmapframe"), {draggableCursor: 
	'crosshair', draggingCursor: 'pointer'}); 

	map.addControl(new GLargeMapControl());
	map.addControl(new GMapTypeControl());
	map.addControl(new GScaleControl());
	map.addControl(new TextualZoomControl());

	map.setCenter(new GLatLng(centerLatitude, centerLongitude), startZoom);	

	GEvent.addListener(map, 'click', handleMapClick);	
	addMapRightClickListener();
	addMapClickListener();
	
//	param1=getURLParam("area");
//	ParseString(param1);
	ParseString(selection);
	

/*


//	GEvent.addListener(map, 'dblclick', handleMapDoubleClick);	

*/
	}

//window.onresize = handleResize;
//window.onload = gmap_load;
//window.onunload = GUnload;

// Parses the string to points in latlngs-vector
function ParseString(strParam)
	{
	var iPos;
	var i;

	if (strParam.length == 0)
		return;
	
	if (strParam.charAt(0)=='/') 
		{
		diagramType=1; 
		iPos=1;
		}
	else 
		{
		diagramType=0;
		iPos=0;
		}
	var aPoints=strParam.substr(iPos).split("/");
	var avglat=0;
	var avglng=0;
	var maxlat=-180;
	var maxlng=-180;
	var minlat=180;
	var minlng=180;
	
//	alert(aPoints.length);
	
	for (i=0; i<aPoints.length-1; i++)
		{
		var strPt=aPoints[i].substr(1);
		var j;
		var lat1Neg=0;
		var lng1Neg=0;
		var lat1=0.0;
		var lng1=0.0;
		
		if (aPoints[i].charAt(0)=='-') lat1Neg=1;
		if (strPt.indexOf("-")==-1) // '-' not found
			{
			var aPt=strPt.split("+");
			
			if (lat1Neg==1) 
				{
				lat1=0.0-parseFloat(aPt[0]);
				lng1=parseFloat(aPt[1]);
				}
			else
				{
				lat1=parseFloat(aPt[0]);
				lng1=parseFloat(aPt[1]);
				}
			}
		else
			{
			var aPt=strPt.split("-");
			
			if (lat1Neg==1) 
				{
				lat1=0.0-parseFloat(aPt[0]);
				lng1=0.0-parseFloat(aPt[1]);
				}
			else
				{
				lat1=parseFloat(aPt[0]);
				lng1=0.0-parseFloat(aPt[1]);
				}
			}
			
		var ll1=new GLatLng(lat1,lng1);
	
//		alert(ll1);
		if (lat1>maxlat) maxlat=lat1;
		if (lat1<minlat) minlat=lat1;
		if (lng1>maxlng) maxlng=lng1;
		if (lng1<minlng) minlng=lng1;
		avglat+=lat1;
		avglng+=lng1;
		latlngs.push(ll1);
		initializePoint(i);
		}
	avglat/=aPoints.length-1;
	avglng/=aPoints.length-1;
	
	var ll2=new GLatLng(avglat,avglng);
	var rectObj = new GLatLngBounds(new GLatLng(minlat,minlng), new GLatLng(maxlat,maxlng));
	var zoom = map.getBoundsZoomLevel(rectObj);

//	if (zoom > 1)
//		zoom--;

	map.setCenter(ll2,zoom);
	redrawPolyline();
	}

function getURLParam(strParamName)
{
  var strReturn = "";
  var strHref = window.location.href;
  if ( strHref.indexOf("?") > -1 )
	{
    var strQueryString = strHref.substr(strHref.indexOf("?")).toLowerCase();
    var aQueryString = strQueryString.split("&");
    for ( var iParam = 0; iParam < aQueryString.length; iParam++ ){
      if (aQueryString[iParam].indexOf(strParamName.toLowerCase() + "=") > -1 )
		{
        var aParam = aQueryString[iParam].split("=");
        strReturn = aParam[1];
        break;
		}
    }
  }
  return unescape(strReturn);
} 
