Index: main/trunk/greenstone3/web/interfaces/default/js/map-scripts-editor.js
===================================================================
--- main/trunk/greenstone3/web/interfaces/default/js/map-scripts-editor.js	(revision 32781)
+++ main/trunk/greenstone3/web/interfaces/default/js/map-scripts-editor.js	(revision 32798)
@@ -1,47 +1,8 @@
-var debug = false;
-var shiftKeyPressed = false;
-var beingDragged = false;
-var resizeEntry = false;
-var allowDeselect = true;
-var colors = ['#1E90FF', '#FF1493', '#4B0082', '#32CD32', '#FF8C00', '#000000'];
-var selectedColor;
-var colorButtons = {};
-var thicknessValue = 1;
-var opacityValue = 0.4;
-var draggableState = true
-var overlays = [];
-var entryType = [];
-var selectedShapes = [];
-var listenersArray = [];
-var mapsArray = [];
-var controlsId = null;
-var drawingManager;
-var selectedShape;
-var map = null;
-var dragS, dragN;
-var dsNorth, dsSouth, dsEast, dsWest;
-//var gaj, gal, maj, mal;
-var counter = 0;
-var branchNum = 1;
-var mouseState = "up";
-var thicknessRangeListener = thicknessValue;
-var resizable = false;
-var dontResize = false;
-
-var mapEditorHistory = new MapEditorHistory();
-
-var polyOptions = {
-	fillColor: '#CA4A2F',
-	strokeWeight: thicknessValue,
-	fillOpacity: opacityValue,
-	editable: true,
-	draggable: draggableState,
-	geodesic: false
-};
-
-function MapEditor() {
+
+
+function MapEditor(id) {
+	this.id = id;
 	this.shiftKeyPressed = false;
 	this.beingDragged = false;
-	this.resizeEntry = false;
 	this.allowDeselect = true;
 	this.colors = ['#1E90FF', '#FF1493', '#4B0082', '#32CD32', '#FF8C00', '#000000'];
@@ -50,203 +11,212 @@
 	this.thicknessValue = 1;
 	this.opacityValue = 0.4;
-	this.draggableState = true
 	this.overlays = [];
-	this.entryType = [];
 	this.selectedShapes = [];
 	this.listenersArray = [];
 	this.mapsArray = [];
-	this.controlsId = null;
 	this.drawingManager;
 	this.selectedShape;
 	this.map = null;
-	this.dragS, dragN;
-	this.dsNorth, dsSouth, dsEast, dsWest;
-	// gaj, gal, maj, mal;
 	this.counter = 0;
 	this.branchNum = 1;
 	this.mouseState = "up";
-	this.thicknessRangeListener = thicknessValue;
+	this.thicknessRangeListener = this.thicknessValue; // ????
 	this.resizable = false;
 	this.dontResize = false;
-	
-	this.mapEditorHistory = new MapEditorHistory();
-	
 	this.polyOptions = {
 		fillColor: '#CA4A2F',
-		strokeWeight: thicknessValue,
-		fillOpacity: opacityValue,
+		strokeWeight: this.thicknessValue,
+		fillOpacity: this.opacityValue,
 		editable: true,
-		draggable: this.draggableState,
-		geodesic: false
-};
-}
-
-//MapEditor.prototype.initMapEditorControls = function(id) {
-//};
-
-	
-function initMapEditorControls(id) {
-	console.log(id);
-	//change draggable
-	var draggableCB = document.querySelector("input[name=draggableCB]");	
-	
+		geodesic: false,
+		draggable: true
+	};
+	this.mapEditorHistory = new MapEditorHistory(this);
+}
+
+MapEditor.prototype.initMapEditorControls = function () {
+	var that = this;
+	console.log(this.id);
+
+	var draggableCB = document.querySelector("input[name=draggableCB]");
 	draggableCB.addEventListener('change', function () {
 		if (this.checked) {
-			draggableState = false;
-			for (var i = 0; i < overlays.length; i++) {
-				overlays[i].draggable = draggableState;
-				polyOptions.draggable = draggableState;
+			for (var i = 0; i < that.overlays.length; i++) {
+				console.log("checked");
+				that.overlays[i].draggable = false;
+				that.polyOptions.draggable = false;
 			}
 		} else {
-			draggableState = true;
-			for (var i = 0; i < overlays.length; i++) {
-				overlays[i].draggable = draggableState;
-				polyOptions.draggable = draggableState;
-			}
-		}
-	});
-
+			for (var i = 0; i < that.overlays.length; i++) {
+				console.log("not checked");
+				that.overlays[i].draggable = true;
+				that.polyOptions.draggable = true;
+			}
+		}
+	});
+	
+	
 	//Update thickness
-	var thicknessSlider = document.getElementById("thicknessRange" +"-"+ id);
-	var thicknessSliderOutput = document.getElementById("thicknessRangeVal" +"-"+ id);
+	var thicknessSlider = document.getElementById("thicknessRange" + "-" + this.id);
+	var thicknessSliderOutput = document.getElementById("thicknessRangeVal" + "-" + this.id);
 	thicknessSliderOutput.innerHTML = thicknessSlider.value / 20;
-	
+
 	thicknessSlider.oninput = function () {
-		shapeSpecsChangeMD();
+		that.shapeSpecsChangeMD();
 		thicknessSliderOutput.innerHTML = this.value / 20;
-		thicknessValue = this.value / 20;		
-		polyOptions.strokeWeight = thicknessValue;
-		setSelectedThickness(thicknessValue);
+		that.thicknessValue = this.value / 20;
+		that.polyOptions.strokeWeight = that.thicknessValue;
+		that.setSelectedThickness(that.thicknessValue);
 
 	}
 	//Update opacity
-	var opacitySlider = document.getElementById("colourOpacity" +"-"+ id);
-	var opacitySliderOutput = document.getElementById("opacityRangeVal" +"-"+ id);
-	opacitySliderOutput.innerHTML = Math.round(opacitySlider.value) /100;
+	var opacitySlider = document.getElementById("colourOpacity" + "-" + this.id);
+	var opacitySliderOutput = document.getElementById("opacityRangeVal" + "-" + this.id);
+	opacitySliderOutput.innerHTML = Math.round(opacitySlider.value) / 100;
 
 	opacitySlider.oninput = function () {
-		shapeSpecsChangeMD();
+		that.shapeSpecsChangeMD();
 		opacitySliderOutput.innerHTML = "% " + this.value;
-		opacityValue = this.value / 100;		
-		polyOptions.fillOpacity = opacityValue;
-		setSelectedOpacity(opacityValue);
-	}
-
-	document.getElementById("color-palette1" +"-"+ id).addEventListener("mousedown", shapeSpecsChangeMD);
-	document.getElementById("thicknessRange" +"-"+ id).addEventListener("mouseup", shapeSpecsChangeMU);
-	document.getElementById("colourOpacity"  +"-"+ id).addEventListener("mouseup", shapeSpecsChangeMU);
-	document.onmousemove = mouseMove;
-	document.onmousedown = mouseDown;
-	document.onmouseup = mouseUp;
-}
-
-
-function settingThePath() {
-	listenersArray = []
-	counter = 0;
-	branchNum = 1;
-
-	for (var i = 0; i < selectedShapes.length * 2; i++) {
-		for (var j = 1; j < 5; j++) {
-			var path = "//*[@id='map']/div/div/div[1]/div[3]/div/div[3]/div[" + branchNum + "]/div[" + j + "]/div";
-			listenersArray[counter] = getElementByXpath(path);
-			if (listenersArray[counter] !== undefined && listenersArray[counter] !== null) {
-				listenersArray[counter].addEventListener("mousemove", function () {
-					resizable = true;
-					shapeResize();
+		that.opacityValue = this.value / 100;
+		that.polyOptions.fillOpacity = that.opacityValue;
+		that.setSelectedOpacity(that.opacityValue);
+	}
+
+	document.getElementById("color-palette1" + "-" + this.id).addEventListener("mousedown", function() { that.shapeSpecsChangeMD() });
+	document.getElementById("thicknessRange" + "-" + this.id).addEventListener("mouseup", function () { that.shapeSpecsChangeMU() });
+	document.getElementById("colourOpacity" + "-" + this.id).addEventListener("mouseup", function() { that.shapeSpecsChangeMU() } );
+	document.onmousemove = function (ev) {
+		//How can I know the state of mouse from here
+		if (that.mouseState == 'down') {
+			//console.log('mouse down state')
+		}
+		if (that.mouseState == 'up') {
+			//console.log('mouse up state')
+		}
+	}
+
+	document.onmousedown = function (ev) {
+		that.mouseState = "down";
+		//    console.log('Down State you can now start dragging');
+		//do not write any code here in this function
+	}
+
+	document.onmouseup = function (ev) {
+		that.mouseState = "up";
+		//    console.log('up state you cannot drag now because you are not holding your mouse')
+		//do not write any code here in this function
+	}
+}
+
+MapEditor.prototype.settingThePath = function () {
+	var that = this;
+	this.listenersArray = []
+	this.counter = 0;
+	this.branchNum = 1;
+	
+	for (var i = 0; i < this.selectedShapes.length * 2; i++) {
+		for (var j = 1; j < 6; j++) {
+			var path = "//*[@id='map-" + this.id + "']/div/div/div[1]/div[3]/div/div[3]/div[" + this.branchNum + "]/div[" + j + "]/div";
+			this.listenersArray[this.counter] = this.getElementByXpath(path);
+			if (this.listenersArray[this.counter] !== (undefined || null)) {
+				this.listenersArray[this.counter].addEventListener("mousemove", function () {
+					that.resizable = true;
+					that.shapeResize();
 				});
-				listenersArray[counter].addEventListener("mouseout", function () {
-					if (mouseDown) {
-						resizable = true;
-						shapeResize();
+				this.listenersArray[this.counter].addEventListener("mouseout", function () {
+					if (this.mouseDown) {
+						that.resizable = true;
+						that.shapeResize();
 					}
 				});
 			}
-			counter++;
-		}
-		branchNum++;
-	}
-}
-
-
-
-function shapeResize() {
-	if (mouseState == "down") {
-		if (selectedShapes.length > 0) {
-			if (resizable) {
-				if(dontResize == false){
-					mapEditorHistory.historyOverlayPush();
+			this.counter++;
+		}
+		this.branchNum++;
+	}
+}
+
+MapEditor.prototype.shapeResize = function () {
+	if (this.mouseState == "down") {
+		if (this.selectedShapes.length > 0) {
+			if (this.resizable) {
+				if (this.dontResize == false) {
+					this.mapEditorHistory.historyOverlayPush();
 				}
-				
-			}
-		}
-	}
-}
-
-function shapeSpecsChangeMD() {
-
-	if (selectedShapes.length > 0) {
-		mapEditorHistory.historyOverlayPush();
-	}
-}
-
-function shapeSpecsChangeMU() {
-	if (selectedShapes.length > 0) {
-		mapEditorHistory.presentOverlayPush ();
-	}
-}
-
-function makeColorButton(color) {
+
+			}
+		}
+	}
+}
+
+MapEditor.prototype.shapeSpecsChangeMD = function () {
+	console.log(this.selectedShapes);
+
+	if (this.selectedShapes.length > 0) {
+		this.mapEditorHistory.historyOverlayPush();
+	}
+}
+
+MapEditor.prototype.shapeSpecsChangeMU = function () {
+	if (this.selectedShapes.length > 0) {
+		this.mapEditorHistory.presentOverlayPush();
+	}
+}
+
+MapEditor.prototype.makeColorButton = function (color) {
+	var that = this;
+
 	var button = document.createElement('span');
 	button.className = 'color-buttons1';
 	button.style.backgroundColor = color;
 	google.maps.event.addDomListener(button, 'click', function () {
-		selectColor(color);
-		setSelectedShapeColor(color);
-		shapeSpecsChangeMU();
+		that.selectColor(color);
+		that.setSelectedShapeColor(color);
+		that.shapeSpecsChangeMU();
 	});
 	return button;
 }
-function buildColorPalette(id) {
-	console.log("colour palette build");
-	var colorPalette = document.getElementById("color-palette1" +"-"+ id);
-	for (var i = 0; i < colors.length; ++i) {
-		var currColor = colors[i];
-		var colorButton = makeColorButton(currColor);
+
+MapEditor.prototype.buildColorPalette = function () {
+	var colorPalette = document.getElementById("color-palette1" + "-" + this.id);
+	for (var i = 0; i < this.colors.length; ++i) {
+		var currColor = this.colors[i];
+		var colorButton = this.makeColorButton(currColor);
 		colorPalette.appendChild(colorButton);
-		colorButtons[currColor] = colorButton;
-	}
-	selectColor(colors[0]);
+		this.colorButtons[currColor] = colorButton;
+	}
+	this.selectColor(this.colors[0]);
 };
-function selectColor(color) {
-	selectedColor = color;
-	for (var i = 0; i < colors.length; ++i) {
-		var currColor = colors[i];
-		colorButtons[currColor].style.border = currColor == color ? '2px solid #789' : '2px solid #fff';
+
+MapEditor.prototype.selectColor = function (color) {
+	this.selectedColor = color;
+	for (var i = 0; i < this.colors.length; ++i) {
+		var currColor = this.colors[i];
+		this.colorButtons[currColor].style.border = currColor == color ? '2px solid #789' : '2px solid #fff';
 	}
 
 	// Retrieves the current options from the drawing manager and replaces the
 	// stroke or fill color as appropriate.
-	var polylineOptions = drawingManager.get('polylineOptions');
+	var polylineOptions = this.drawingManager.get('polylineOptions');
 	polylineOptions.strokeColor = color;
-	drawingManager.set('polylineOptions', polylineOptions);
-
-	var rectangleOptions = drawingManager.get('rectangleOptions');
+	this.drawingManager.set('polylineOptions', polylineOptions);
+
+	var rectangleOptions = this.drawingManager.get('rectangleOptions');
 	rectangleOptions.fillColor = color;
-	drawingManager.set('rectangleOptions', rectangleOptions);
-
-	var circleOptions = drawingManager.get('circleOptions');
+	this.drawingManager.set('rectangleOptions', rectangleOptions);
+
+	var circleOptions = this.drawingManager.get('circleOptions');
 	circleOptions.fillColor = color;
-	drawingManager.set('circleOptions', circleOptions);
-
-	var polygonOptions = drawingManager.get('polygonOptions');
+	this.drawingManager.set('circleOptions', circleOptions);
+
+	var polygonOptions = this.drawingManager.get('polygonOptions');
 	polygonOptions.fillColor = color;
-	drawingManager.set('polygonOptions', polygonOptions);
-}
-
-function initMapEditor(id) {
+	this.drawingManager.set('polygonOptions', polygonOptions);
+}
+
+MapEditor.prototype.initMapEditor = function () {
 	var that = this;
-	
-	map = new google.maps.Map(document.getElementById("map-" + id), {
+
+	this.map = new google.maps.Map(document.getElementById("map-" + this.id), {
 			center: {
 				lat: -37.7891,
@@ -254,31 +224,28 @@
 			},
 			zoom: 14,
-			mapId: id,
+			mapId: this.id,
 		});
-	mapsArray.push(map);	
-	console.log(map);	
+	this.mapsArray.push(this.map);
 	// Add a style-selector control to the map.
-	var styleControl = document.getElementById('style-selector-control' +"-"+ id);
-	map.controls[google.maps.ControlPosition.TOP_LEFT].push(styleControl);
+	var styleControl = document.getElementById('style-selector-control' + "-" + this.id);
+	this.map.controls[google.maps.ControlPosition.TOP_LEFT].push(styleControl);
 
 	// Set the map's style to the initial value of the selector.
-	var styleSelector = document.getElementById('style-selector' +"-"+ id);
-	console.log(styleSelector);
-	//map = google.maps.Map(document.getElementById('map' +"-"+ id));
-	console.log(map);
-	map.setOptions({
+	var styleSelector = document.getElementById('style-selector' + "-" + this.id);
+	//console.log(styleSelector);
+	//map = google.maps.Map(document.getElementById('map' +"-"+ this.id));
+	this.map.setOptions({
 		styles: styles[styleSelector.value]
-		
-	});
-	
+
+	});
+
 	// Apply new JSON when the user selects a different style.
 	styleSelector.addEventListener('change', function () {
-		console.log(id);
-		mapsArray.indexOf(map).setOptions({
+		that.map.setOptions({
 			styles: styles[styleSelector.value]
 		});
 	});
 
-	drawingManager = new google.maps.drawing.DrawingManager({
+	this.drawingManager = new google.maps.drawing.DrawingManager({
 			drawingMode: google.maps.drawing.OverlayType.RECTANGLE,
 			drawingControl: true,
@@ -288,108 +255,116 @@
 			},
 			markerOptions: {
-				draggable: draggableState
+				draggable: true
 			},
-			circleOptions: polyOptions,
-			polylineOptions: polyOptions,
-			polygonOptions: polyOptions,
-			rectangleOptions: polyOptions,
+			circleOptions: this.polyOptions,
+			polylineOptions: this.polyOptions,
+			polygonOptions: this.polyOptions,
+			rectangleOptions: this.polyOptions,
 		});
 
-	drawingManager.setMap(map);
-
-	google.maps.event.addListener(drawingManager, "drawingmode_changed", function () {
-		if(shiftKeyPressed != true && drawingManager.drawingMode !== null){
-			deselectAll();
-		}
-		settingThePath();
+	this.drawingManager.setMap(this.map);
+
+	google.maps.event.addListener(this.drawingManager, "drawingmode_changed", function () {
+		if (that.shiftKeyPressed != true && that.drawingManager.drawingMode !== null) {
+			that.deselectAll();
+		}
+		that.settingThePath();
 
 	})
 
 	// store reference to added overlay
-	google.maps.event.addListener(drawingManager, 'overlaycomplete', function (e) {
-		allowDeselect = true;
-		mapEditorHistory.historyOverlayPush();
-		overlays.push(e.overlay); // store reference to added overlay
+	google.maps.event.addListener(this.drawingManager, 'overlaycomplete', function (e) {
+		
+		that.allowDeselect = true;
+		that.mapEditorHistory.historyOverlayPush();
+		that.overlays.push(e.overlay); // store reference to added overlay
 		var newShape = e.overlay;
 		newShape.type = e.type;
-		mapEditorHistory.presentOverlayPush();
-
+		that.mapEditorHistory.presentOverlayPush();
+		
 		if (e.type !== google.maps.drawing.OverlayType.MARKER) {
-			addShapeListeners(newShape, e);
-			setSelection(newShape, e);
+			that.addShapeListeners(newShape, e);
+			that.setSelection(newShape, e);
 		} else {
-
-			addMarkerListeners(newShape, e);
-			setSelection(newShape, e);
-		}
+			that.addMarkerListeners(newShape, e);
+			that.setSelection(newShape, e);
+		}
+		
 	});
 
 	//Clears selection if clicked on the map when shift is not presseed
-	google.maps.event.addListener(map, 'click', function (e) {
+	google.maps.event.addListener(this.map, 'click', function (e) {
 		var c = document.body.childNodes;
 		if (e.target && e.target.matches("a.classA")) {
 			console.log("Anchor element clicked!");
 		}
-		if (shiftKeyPressed == false) {
-			clearSelection();
-			selectedShape = null;
-		}
-	});
-	
-	google.maps.event.addListener(map, 'mousedown', function (e) {
-		dontResize = true;
-	});	
-	
-	google.maps.event.addListener(map, 'mouseup', function (e) {
-		dontResize = false;
-	});	
-	
-	//Keyboard shortcuts
-	document.addEventListener('keydown', function () {
-		if (event.code == 'KeyY' && (event.ctrlKey || event.metaKey) || (event.code == 'KeyZ' && event.code == 'ShiftLeft' && (event.ctrlKey || event.metaKey))) {
-			mapEditorHistory.redo();
+		if (that.shiftKeyPressed == false) {
+			that.clearSelection();
+			that.selectedShape = null;
+		}
+	});
+
+	google.maps.event.addListener(this.map, 'mousedown', function (e) {
+		that.dontResize = true;
+	});
+
+	google.maps.event.addListener(this.map, 'mouseup', function (e) {
+		that.dontResize = false;
+	});
+
+	//Keyboard shortcuts		
+	var mapAndControls = document.getElementById("map-and-controls-" + this.id);
+	mapAndControls.addEventListener('keydown', function () {
+		if (event.code == 'KeyY' && (event.ctrlKey || event.metaKey) ||
+			(event.code == 'KeyZ' && event.code == 'ShiftLeft' && (event.ctrlKey || event.metaKey))) {
+			that.mapEditorHistory.redo();
 		}
 		if (event.code == 'KeyZ' && (event.ctrlKey || event.metaKey)) {
-			if (shiftKeyPressed == false) {
-				//undo();
-				mapEditorHistory.undo();
-				//mapEditorHistory.undo(overlays, draggableState); // ***** when we only have MapEditorHistory as a class
-				//that.mapEditorHistory.undo(that.overlays); // ***** when we have both MapEditorHistory and MapEditor as classes
-				
+			if (that.shiftKeyPressed == false) {
+				that.mapEditorHistory.undo();
 			}
 		}
 		if (event.code == 'KeyA' && (event.ctrlKey || event.metaKey)) {
 			event.preventDefault();
-			drawingManager.setDrawingMode(null);
-			selectAll();
-			
+			that.drawingManager.setDrawingMode(null);
+			that.selectAll();
+
 		}
 		if (event.code == 'KeyD' && (event.ctrlKey || event.metaKey)) {
 			event.preventDefault();
-			deselectAll();
+			that.deselectAll();
 		}
 		if (event.code == 'Digit0' || event.code == 'Numpad0' || event.code == 'Backquote') {
 
-			drawingManager.setDrawingMode(null);
+			that.drawingManager.setDrawingMode(null);
 		} else if (event.code == 'Digit1') {
-			drawingManager.setDrawingMode('marker');
+			that.drawingManager.setDrawingMode('marker');
 		} else if (event.code == 'Digit2') {
-			drawingManager.setDrawingMode('circle');
+			that.drawingManager.setDrawingMode('circle');
 		} else if (event.code == 'Digit3') {
-			drawingManager.setDrawingMode('polygon');
+			that.drawingManager.setDrawingMode('polygon');
 		} else if (event.code == 'Digit4') {
-			drawingManager.setDrawingMode('polyline');
+			that.drawingManager.setDrawingMode('polyline');
 		} else if (event.code == 'Digit5') {
-			drawingManager.setDrawingMode('rectangle');
+			that.drawingManager.setDrawingMode('rectangle');
 		} else if (event.code == 'KeyQ') {
-			printHistory();
+			that.printHistory();
 		}
 		//							console.log(event.code);
 	});
 
+	/*
+	var mapHtml = document.getElementById("map-" + this.id);
+	var controlHtml = document.getElementById("ControlPanel-" + this.id);
+	controlHtml.addEventListener('click', function () {
+		console.log("*** ControlPanel clicked");
+	    mapHtml.focus() 
+	});
+	*/
+	
 	//Sets shift as pressed
-	document.addEventListener('keydown', function () {
+	mapAndControls.addEventListener('keydown', function () {
 		if (event.code == 'ShiftLeft' || event.code == 'ShiftRight') {
-			shiftKeyPressed = true;
+			that.shiftKeyPressed = true;
 
 		}
@@ -398,16 +373,16 @@
 
 	//Sets shift as unpressed
-	document.addEventListener('keyup', function () {
+	mapAndControls.addEventListener('keyup', function () {
 		if (event.code == 'ShiftLeft' || event.code == 'ShiftRight') {
-			shiftKeyPressed = false;
-		}
-
-	});
-
-	buildColorPalette(id);
+			that.shiftKeyPressed = false;
+		}
+
+	});
+
+	this.buildColorPalette();
 }
 
 //Deletes a vertex if clicked on it
-function vertexAndPolyDel(e, newShape) {
+MapEditor.prototype.vertexAndPolyDel = function (e, newShape) {
 	var vertex = e.vertex;
 	if (e.vertex !== undefined) {
@@ -429,52 +404,52 @@
 }
 
-function addMarkerListeners(newShape, e) {
+MapEditor.prototype.addMarkerListeners = function (newShape, e) {
+	var that = this;
 	//cLICK EVENT IF A MARKER IS CREATED
 	google.maps.event.addListener(newShape, 'click', function (e) {
-		setSelection(newShape, e);
+		that.setSelection(newShape, e);
 	});
 
 	google.maps.event.addListener(newShape, 'dragstart', function (e) {
-		beingDragged = true;
-		mapEditorHistory.historyOverlayPush();
+		that.beingDragged = true;
+		that.mapEditorHistory.historyOverlayPush();
 
 	});
 
 	google.maps.event.addListener(newShape, 'dragend', function () {
-		beingDragged = false;
-		mapEditorHistory.presentOverlayPush ();
-		allowDeselect = false;
-	});
-}
-
-function addShapeListeners(newShape, e) {
+		that.beingDragged = false;
+		that.mapEditorHistory.presentOverlayPush();
+		that.allowDeselect = false;
+	});
+}
+
+MapEditor.prototype.addShapeListeners = function (newShape, e) {
+	var that = this;
 	// Add an event listener that selects the newly-drawn shape when the user
 	// mouses down on it.
 	google.maps.event.addListener(newShape, 'click', function (e) {
 
-		vertexAndPolyDel(e, newShape);
+		that.vertexAndPolyDel(e, newShape);
 
 	});
 
 	google.maps.event.addListener(newShape, 'dragstart', function (e) {
-		allowDeselect = false;
-		mapEditorHistory.historyOverlayPush();
-	});
-
-
+		that.allowDeselect = false;
+		that.mapEditorHistory.historyOverlayPush();
+	});
 
 	google.maps.event.addListener(newShape, 'dragend', function () {
-		beingDragged = false;
-		mapEditorHistory.presentOverlayPush ();
-		settingThePath();
-		
-		allowDeselect = false;
-		setSelection(newShape, e);
+		that.beingDragged = false;
+		that.mapEditorHistory.presentOverlayPush();
+		that.settingThePath();
+
+		that.allowDeselect = false;
+		that.setSelection(newShape, e);
 	});
 
 	//Store information after the event ends
 	google.maps.event.addListener(newShape, 'bounds_changed', function (e) {
-		if (beingDragged == false) {
-			mapEditorHistory.presentOverlayPush ();
+		if (that.beingDragged == false) {
+			that.mapEditorHistory.presentOverlayPush();
 		}
 	});
@@ -486,8 +461,8 @@
 		}
 		if (e.vertex !== undefined || e.edge !== undefined) {
-			mapEditorHistory.historyOverlayPush()
-		}
-		if (drawingManager.drawingMode == null) {
-			setSelection(newShape, e);
+			that.mapEditorHistory.historyOverlayPush()
+		}
+		if (that.drawingManager.drawingMode == null) {
+			that.setSelection(newShape, e);
 		}
 	});
@@ -495,52 +470,53 @@
 	google.maps.event.addListener(newShape, 'mouseup', function (e) {
 		if (e.vertex !== undefined || e.edge !== undefined) {
-			mapEditorHistory.presentOverlayPush ()
+			that.mapEditorHistory.presentOverlayPush()
 		} else {
-			//setSelection(newShape, e);
-		}
-		
-	});
-}
-function clearSelection() {
-	if (selectedShape) {
-		if (selectedShape.type !== 'marker') {
-			selectedShape.setEditable(false);
-			if (shiftKeyPressed == false) {
-				for (var i = 0; i < selectedShapes.length; i++) {
-					selectedShapes[i].setEditable(false);
+			//that.setSelection(newShape, e);
+		}
+
+	});
+}
+MapEditor.prototype.clearSelection = function () {
+	if (this.selectedShape) {
+		if (this.selectedShape.type !== 'marker') {
+			this.selectedShape.setEditable(false);
+			if (this.shiftKeyPressed == false) {
+				for (var i = 0; i < this.selectedShapes.length; i++) {
+					this.selectedShapes[i].setEditable(false);
 				}
-				selectedShapes = [];
-			}
-		}
-		selectedShape = null;
+				this.selectedShapes = [];
+			}
+		}
+		this.selectedShape = null;
 	}
 }
 
 //Set selection for the selected overlay
-function setSelection(shape, e) {
+MapEditor.prototype.setSelection = function (shape, e) {
+	//var that = this;
 	if (shape.type !== 'marker') {
-		if (shiftKeyPressed == false) {
-			if(e !== null) {
+		if (this.shiftKeyPressed == false) {
+			if (e !== null) {
 				if (e.vertex == undefined) {
 					if (e.edge == undefined) {
-						clearSelection();
+						this.clearSelection();
 						shape.setEditable(true);
 					}
-				}				
-			}
-		}
-		if (selectedShapes.includes(shape)) {
-			if(e !== null){
+				}
+			}
+		}
+		if (this.selectedShapes.includes(shape)) {
+			if (e !== null) {
 				if (e.vertex == undefined) {
 					if (e.edge == undefined) {
-						allowDeselect = true;
-						removeFromSelectedShapes(shape);
+						this.allowDeselect = true;
+						this.removeFromSelectedShapes(shape);
 					}
 				}
 			}
 		} else {
-			allowDeselect = false;
+			this.allowDeselect = false;
 			shape.setEditable(true);
-			selectedShapes.push(shape);
+			this.selectedShapes.push(shape);
 		}
 
@@ -550,30 +526,29 @@
 		var fCol = shape.fillColor;
 		var sCol = shape.strokeColor;
-		//updateMenuValues(thi, opa, fCol, sCol);
+		this.updateMenuValues(thi, opa, fCol, sCol);
 
 	} else if (shape.type == 'marker') {
-		clearSelection();
-	}
-	selectedShape = shape;
-	settingThePath();
-}
-
-function removeFromSelectedShapes(shape) {
-	if (selectedShapes.includes(shape)) {
-		if (allowDeselect) {
-			const index = selectedShapes.indexOf(shape);
-			selectedShapes.splice(index, 1);
+		this.clearSelection();
+	}
+	this.selectedShape = shape;
+	this.settingThePath();
+}
+
+MapEditor.prototype.removeFromSelectedShapes = function (shape) {
+	if (this.selectedShapes.includes(shape)) {
+		if (this.allowDeselect) {
+			const index = this.selectedShapes.indexOf(shape);
+			this.selectedShapes.splice(index, 1);
 			shape.setEditable(false);
 		}
-		allowDeselect = true;
-	} 
+		this.allowDeselect = true;
+	}
 }
 
 //Set selected thickness
-function setSelectedThickness(sWeight) {
-	if (selectedShapes.length > 0) {
-		//mapEditorHistory.historyOverlayPush();
-		for (var i = 0; i < selectedShapes.length; i++) {
-			selectedShapes[i].set('strokeWeight', sWeight);
+MapEditor.prototype.setSelectedThickness = function (sWeight) {
+	if (this.selectedShapes.length > 0) {
+		for (var i = 0; i < this.selectedShapes.length; i++) {
+			this.selectedShapes[i].set('strokeWeight', sWeight);
 		}
 	}
@@ -581,9 +556,9 @@
 
 //Set selected opacity
-function setSelectedOpacity(fOpacity) {
-
-	if (selectedShapes.length > 0) {
-		for (var i = 0; i < selectedShapes.length; i++) {
-			selectedShapes[i].set('fillOpacity', fOpacity);
+MapEditor.prototype.setSelectedOpacity = function (fOpacity) {
+
+	if (this.selectedShapes.length > 0) {
+		for (var i = 0; i < this.selectedShapes.length; i++) {
+			this.selectedShapes[i].set('fillOpacity', fOpacity);
 		}
 	}
@@ -591,106 +566,116 @@
 
 //set selected fill colour
-function setSelectedShapeColor(color) {
-	if (selectedShapes.length > 0) {
-		for (var i = 0; i < selectedShapes.length; i++) {
-			selectedShapes[i].set('fillColor', color);
-			selectedShapes[i].set('strokeColor', color);
-		}
-	}
-}
-function getElementByXpath(path) {
+MapEditor.prototype.setSelectedShapeColor = function (color) {
+	if (this.selectedShapes.length > 0) {
+		for (var i = 0; i < this.selectedShapes.length; i++) {
+			this.selectedShapes[i].set('fillColor', color);
+			this.selectedShapes[i].set('strokeColor', color);
+		}
+	}
+}
+
+MapEditor.prototype.getElementByXpath = function (path) {
 	return document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
 }
 
-function updateMenuValues(thi, opa, fCol, sCol, id) {
+MapEditor.prototype.updateMenuValues = function (thi, opa, fCol, sCol) {
 	//Update thickness slider and value on the settings menu
-	var thicknessSliderOutput = document.getElementById("thicknessRangeVal" +"-"+ id);
+	var thicknessSliderOutput = document.getElementById("thicknessRangeVal" + "-" + this.id);
 	thicknessSliderOutput.innerHTML = thi;
-	document.getElementById("thicknessRange" +"-"+ id).value = thi * 20;
+	document.getElementById("thicknessRange" + "-" + this.id).value = thi * 20;
 
 	//Update the opacity slider and value on the settings menu
-	var opacitySliderOutput = document.getElementById("opacityRangeVal" +"-"+ id);
+	var opacitySliderOutput = document.getElementById("opacityRangeVal" + "-" + this.id);
 	opacitySliderOutput.innerHTML = "% " + opa * 100;
-	document.getElementById("colourOpacity" +"-"+ id).value = opa * 100;
-
-	if (drawingManager.drawingMode == null) {
-		selectColor(fCol);
-	}
-}
-function selectAll() {
-	shiftKeyPressed = true;
+	document.getElementById("colourOpacity" + "-" + this.id).value = opa * 100;
+
+	if (this.drawingManager.drawingMode == null) {
+		this.selectColor(fCol);
+	}
+}
+MapEditor.prototype.selectAll = function () {
+	this.shiftKeyPressed = true;
 	var e = new Object();
 	e.vertex = undefined;
-	selectedShapes = [];
-	for (var i = 0; i < overlays.length; i++) {
-		setSelection(overlays[i], e);
-	}
-	shiftKeyPressed = false;
-}
-
-function deselectAll() {
-	for (var i = 0; i < selectedShapes.length; i++) {
-		selectedShapes[i].setEditable(false);
-	}
-	selectedShapes = [];
-}
-
-function printHistory() {
-	console.log("prev", mapEditorHistory.prevOverlays);
-	console.log("present ", mapEditorHistory.presentOverlays);
-	console.log("undone ", mapEditorHistory.undoneOverlays);
-	console.log(mouseState);
-}
-
-function mouseMove(ev) {
-
-	//How can I know the state of mouse from here
-	if (mouseState == 'down') {
-		//console.log('mouse down state')
-	}
-
-	if (mouseState == 'up') {
-		//console.log('mouse up state')
-	}
-}
-
-function mouseDown(ev) {
-	mouseState = "down";
-	//    console.log('Down State you can now start dragging');
-	//do not write any code here in this function
-}
-
-function mouseUp(ev) {
-	mouseState = "up";
-	//    console.log('up state you cannot drag now because you are not holding your mouse')
-	//do not write any code here in this function
-}
-
-function deleteSelectedShape() {
+	this.selectedShapes = [];
+	for (var i = 0; i < this.overlays.length; i++) {
+		this.setSelection(this.overlays[i], e);
+	}
+	this.shiftKeyPressed = false;
+}
+MapEditor.prototype.deselectAll = function () {
+	for (var i = 0; i < this.selectedShapes.length; i++) {
+		this.selectedShapes[i].setEditable(false);
+	}
+	this.selectedShapes = [];
+}
+
+MapEditor.prototype.printHistory = function () {
+	//console.log("prev", this.mapEditorHistory.prevOverlays);
+	//console.log("present ", this.mapEditorHistory.presentOverlays);
+	//console.log("undone ", this.mapEditorHistory.undoneOverlays);
+	//console.log(this.selectedShapes);
+	console.log(this.overlays);
+	
+	var json_overlays = ShapesUtil.overlayToJSON(this.overlays);
+	
+	console.log("JSON overlay:\n" + JSON.stringify(json_overlays));
+	
+}
+
+MapEditor.LOAD = function (json_str) {
+	
+    var map_editor = Object.values(gsmap_store)[0]
+	
+	var new_overlays = ShapesUtil.JSONToOverlays(json_str);
+	
+	for (var i=0; i<map_editor.overlays.length; i++) {
+		map_editor.overlays[i].setMap(null);
+	}
+	
+	map_editor.overlays = new_overlays;
+	
+	for (var i=0; i<map_editor.overlays.length; i++) {
+		map_editor.overlays[i].setMap(map_editor.map);
+	}
+	
+}
+
+MapEditor.prototype.deleteSelectedShapes = function () {
 	//console.log("this fires");
-	mapEditorHistory.historyOverlayPush();
-	for (var i = 0; i < selectedShapes.length; i++) {
-		selectedShapes[i].setMap(null);
-
-		if (overlays.includes(selectedShapes[i])) {
-			const index = overlays.indexOf(selectedShapes[i]);
-			overlays.splice(index, 1);
-			selectedShapes[i].setEditable(false);
-		}
-	}
-	selectedShapes = [];
+	this.mapEditorHistory.historyOverlayPush();
+	for (var i = 0; i < this.selectedShapes.length; i++) {
+		this.selectedShapes[i].setMap(null);
+
+		if (this.overlays.includes(this.selectedShapes[i])) {
+			const index = this.overlays.indexOf(this.selectedShapes[i]);
+			this.overlays.splice(index, 1);
+			this.selectedShapes[i].setEditable(false);
+		}
+	}
+	this.selectedShapes = [];
 	//console.log("this fires");
-	mapEditorHistory.presentOverlayPush ();
-}
-
-function deleteAllShape(nId) {
-	console.log(nId);
-	//console.log("this fires");
-	mapEditorHistory.historyOverlayPush();
-	for (var i = 0; i < overlays.length; i++) {
-		overlays[i].setMap(null);
-	}
-	overlays = [];
-	//console.log("this fires");
-	mapEditorHistory.presentOverlayPush ();
-}
+	this.mapEditorHistory.presentOverlayPush();
+}
+
+MapEditor.prototype.draggableState = function () {
+	
+	var draggableCB = document.querySelector("input[name=draggableCB]");
+	draggableCB.addEventListener('change', function () {
+		if (this.checked) {
+			this.overlays.draggable = false;
+		} else {
+			this.overlays.draggable = false;
+		}
+	});
+}
+
+MapEditor.prototype.deleteAllShapes = function () {
+	//console.log("deleteAllShape() this.id = " + this.id);
+	this.mapEditorHistory.historyOverlayPush();
+	for (var i = 0; i < this.overlays.length; i++) {
+		this.overlays[i].setMap(null);
+	}
+	this.overlays = [];
+	this.mapEditorHistory.presentOverlayPush();
+}
