// Google map functions and classes

// Map constants
// start location and zoom
var centerLatitude = 56.95;
var centerLongitude = -4.23;
var startZoom = 7; // 100k grid
// tile stuff
var tileStartSize = 25;
var tileTrim = 180;
var selectTrim = 100;
// grid stuff
var largeGridSide = 100000; // 100k grid
var medGridSide = 10000; // medium grid side
var tile1k2GridSide = 1000;  // small tile
var tile25k2GridSide = 5000;
// zoom stuff
var findZoom = 9; // mid zoom - 5k/10kgrid
var findZoom2 = 12;
var select25k2Zoom = 12;  // tile zoom - 5k grid
var select1k2Zoom = 14;  // tile zoom - 1k grid

// Map variables
var tileSize = tileStartSize;
var tileGridSide = tile25k2GridSide; // tile grid size
var selectZoom = select25k2Zoom;  // tile zoom 


// other map globals
var map; // the Google map
var osgb; // OS map point
var llabel; // last label
var gridOverlays = [];  // set of grid overlays holding grid, grid labels and find tile marker

// set up objects
var tiles5k = new Tiles();  // create selected tiles ogject to hold all tiles

var tileStatus = 0;

function init() {  // set up maps and grids

	if (GBrowserIsCompatible()) {
		map = new GMap2(document.getElementById("map")); // create map
		map.addControl(new GLargeMapControl());  // add controls
		map.addControl(new GMapTypeControl()); 
		map.addControl(new GScaleControl());
		map.addMapType(G_PHYSICAL_MAP); // add terrain display option
		
		var location = new GLatLng(centerLatitude, centerLongitude);  // set up location and zoom
		map.setCenter(location, startZoom);
		geocoder = new GClientGeocoder();  // add Google search geocoder
		
		panelon(); // turn on right hand map panel
		grid();	// add the grid lines
		
		 // process mouse clicks
		GEvent.addListener(map, 'click', function(overlay, latlng) { // clicking on the map gives lat/long and OS grid ref and selects tiles
			wgs84=new GT_WGS84();//create a wgs84 coordinate of the click point
			wgs84.setDegrees(latlng.lat(), latlng.lng());
			osgb=wgs84.getOSGB();//convert to OSGB

			if (map.getZoom() >= selectZoom) { // if tile level, select tile, no zoom change
				tiles5k.selectTile(osgb); // select a tile
			} else { // if large grid, find grid centre and change zoom
				if (map.getZoom() < findZoom) {  // for small scale map - 100k grid
					centreEast = Math.floor(osgb.eastings/largeGridSide)*largeGridSide + largeGridSide/2;
					centreNorth = Math.floor(osgb.northings/largeGridSide)*largeGridSide + largeGridSide/2;
					tileZoom = findZoom;
				} else {  // for medium scale map - 5k grid
					centreEast = Math.floor(osgb.eastings/tileGridSide)*tileGridSide + tileGridSide/2;
					centreNorth = Math.floor(osgb.northings/tileGridSide)*tileGridSide + tileGridSide/2;
					tileZoom = selectZoom;	
				}
				osgb = new GT_OSGB(); // create new osgb coordinate and set new zoom and centre
				osgb.setGridCoordinates(centreEast, centreNorth);
				wgs84 = osgb.getWGS84();
				map.setCenter(new GLatLng(wgs84.latitude, wgs84.longitude), tileZoom);
			}
	
			// display click position for reference and debug
			document.getElementById("clickpoint").innerHTML = "Click point:<br />"+displayLat(latlng.lat(), 4)+" "+displayLong(latlng.lng(), 5)+"<br />"+osgb.getGridRef(5);//get a grid reference with 5 digits of precision
		});
		

		// redraw the map if it is zoomed
		GEvent.addListener(map, 'zoomend', function(oldLevel, newLevel) { // detect zoom 
			document.getElementById("zoomlevel").innerHTML = "Zoom is: "+newLevel;
			if (newLevel >= selectZoom) // change instructions on zoom
				document.getElementById("instructions1").innerHTML = "Click on a tile to select it.<br /> A selected tile can be added to the basket or removed from the basket."; 	
			else
				document.getElementById("instructions1").innerHTML = "To find a tile:<ul><li>navigate using the map zoom and pan controls</li><li>or enter a post code or address </li><li>or enter a lat/long<br />(e.g. N55.9, W3.39) </li></ul>"; 		
			clearGrid();				
			grid();	// add grid lines
		});
		
		// redraw the map if it is dragged
		GEvent.addListener(map, 'moveend', function() { // detect drag
			clearGrid();
			grid();	// add grid lines
		});			
	}
	
	
/********************************   startup functions - load shopping basket values if set   
	var eg_lat = 55.986;  //test locations - 47 Echline gardens
	var eg_long = -3.413;
	var eg_lat2 = 55.986; 
	var eg_long2 = -3.484;
*/
	if (order_lat[0] != 0) { // load basket tiles if order is set and page has been reloaded
		for (loop = 0; loop < order_lat.length; loop++) {
			load_tile(order_lat[loop], order_long[loop], order_type[loop]);
		}
		newCenterMarker(order_lat[0], order_long[0], "fred", order_type[0]);  // display last tile
		clearGrid();
		grid();
	}
	
	keyboardhandler = new GKeyboardHandler(map);  // add keyboard handling		
}	
//******************************************************************


function load_tile(eg_lat, eg_long, eg_type) {
	// work out centres
//	if (tileSize != eg_type) // set tile size for
//		changeTileSize();
/*	
	if (eg_type == 1) {
		tileSize = 1; // set tile size for 1k2
		document.getElementById('tiletype').innerHTML = '<b>Tile  Size = 1km<sup>2</sup>&nbsp;&nbsp;</b><input name="submit3" type="submit" value="Change To 25km2" />';	
		tileGridSide = tile1k2GridSide; // tile grid size
		selectZoom = 14;  // tile zoom - 1k grid
		tileTrim = 36;
		selectTrim = 20;	
	} else {
		tileSize = 25; 
		document.getElementById('tiletype').innerHTML = '<b>Tile  Size = 25km<sup>2</sup></b><input name="submit3" type="submit" value="Change To 1km2" />';	
		tileGridSide = 5000; // tile grid size
		selectZoom = 12;  // tile zoom - 5k grid
		tileTrim = 180;
		selectTrim = 100;	
	}
*/	
	wgs84=new GT_WGS84();//create a wgs84 coordinate
	wgs84.setDegrees(eg_lat, eg_long);
	eg_osgb=wgs84.getOSGB();//convert to OSGB
	botEast = Math.floor(eg_osgb.eastings/tileGridSide)*tileGridSide;  //SW corner
	botNorth = Math.floor(eg_osgb.northings/tileGridSide)*tileGridSide;
	if (eg_type == 1)
		set1kTile();
	else
		set25kTile();
	tiles5k.selectTile(eg_osgb);
	tileCentre = new GLatLng(wgs84.latitude, wgs84.longitude);	
	tiles5k.addTile(tileCentre);
/*			
	osgb = new GT_OSGB(); // create new osgb centre coordinate
	osgb.setGridCoordinates(botEast + tileGridSide/2, botNorth + tileGridSide/2);
	wgs84 = osgb.getWGS84();

	tileCentre = new GLatLng(wgs84.latitude, wgs84.longitude);	
	*/
}
	
	
// set new centre with marker from lat/long or tile name click
function newCenterMarker(latitude, longitude, tooltip, tiletype) {  //  remove overlays and ..........
	//map.clearOverlays();
	if (tiletype == 1)
		set1kTile();
	else
		set25kTile();

	if (tooltip == null)
		tooltip = "Lat: "+latitude+", Long: "+longitude;
	var location = new GLatLng(latitude, longitude);  // set up location and zoom
	map.setCenter(location, selectZoom);
	var markerpoint = new GLatLng(latitude, longitude);
	var marker = new GMarker(markerpoint, {title:tooltip});
	map.addOverlay(marker);
	clearGrid();
	gridOverlays.push(marker);  // store grid overlays
}


function showAddress(address) {  // use the Google geocoder to find an address lat long
  if (geocoder) {
	geocoder.getLatLng(address, function(point) {
		if (!point) {
		  alert(address + " not found");
		} else {
		  clearGrid(); // get rid of previous markers
		  map.setCenter(point, selectZoom);
		  var marker = new GMarker(point, {title:address});
		  
		  //var marker = new GMarker(point, {draggable: true});
		  map.addOverlay(marker);
		  gridOverlays.push(marker);  // store grid overlays
		  grid();
		}
	  }
	);
  }
}


function grid() { // add the various OS grids depending on zoom level

	  //display viewport coords
	 //document.getElementById("viewport").innerHTML = "Viewport is:<br />"+map.getBounds();
	 document.getElementById("zoomlevel").innerHTML = "Zoom is: "+map.getZoom();
	 viewport1 = map.getBounds(); // get viewport
	 sw = viewport1.getSouthWest();  // get corner
	 ne = viewport1.getNorthEast();  // get corner 
	 
	var gridSide = 0;
		
	if (map.getZoom() <= findZoom) {	
		gridSide = medGridSide;
	} else if (tileSize == 1 && map.getZoom() < findZoom2) {
			gridSide = medGridSide;
		} else {
			gridSide = tileGridSide; // smaller grid
		}
	
	if (map.getZoom() < findZoom) { // if large scale map
		east1 = 0;
		north1 = 500000;
		east3 = 800000;
		north3 = 1400000;
		gridSide = largeGridSide;		
	} else {	
		wgs84=new GT_WGS84();  //create a wgs84 coordinate
		wgs84.setDegrees(sw.lat(), sw.lng());
		osgb=wgs84.getOSGB();  //convert to OSGB
		east1 = Math.floor(osgb.eastings/gridSide) * gridSide;  // round 
		north1 = Math.floor(osgb.northings/gridSide) * gridSide;	 
		 
		wgs84=new GT_WGS84();  //create a wgs84 coordinate
		wgs84.setDegrees(ne.lat(), ne.lng());
		osgb=wgs84.getOSGB();  //convert to OSGB
		east3 = Math.ceil(osgb.eastings/gridSide) * gridSide + gridSide/2;
		north3 = Math.ceil(osgb.northings/gridSide) * gridSide + gridSide/2;	 
	}

	 var index= 0;
	 // draw northings
	 for (north = north1; north < north3; north += gridSide) {
		 var tile = [];
		 for (east = east1; east < east3; east += gridSide) {
				
			osgb=new GT_OSGB(); 	//create a osgb coordinate
			osgb.setGridCoordinates(east, north);
			//label = tileLabel(osgb);
			wgs84 = osgb.getWGS84();	//convert to a wgs84 coordinate
			tile[index] = new GLatLng(wgs84.latitude, wgs84.longitude);

			if (map.getZoom() >= selectZoom - 1) { // apply tile labels if zoomed in
				//addLabel(tile[index],osgb.getTileRef());
				addLabel(tile[index],tileLabel(osgb));
			}
			index++;
		 }
		 lineOverlay = new GPolyline(tile,'black', '1')
		 map.addOverlay(lineOverlay); // add box
		 gridOverlays.push(lineOverlay);  // store grid overlays
	 }	 
	 // draw eastings
	 for (east = east1; east < east3; east += gridSide) {
		 var tile = [];
		 for (north = north1; north < north3; north += gridSide) {
			 
		osgb=new GT_OSGB(); 	//create a osgb coordinate
		osgb.setGridCoordinates(east, north);
		wgs84 = osgb.getWGS84();	//convert to a wgs84 coordinate
		tile[index++] = new GLatLng(wgs84.latitude, wgs84.longitude); 			 

		 }
		 lineOverlay = new GPolyline(tile,'black', '1')
		 map.addOverlay(lineOverlay); // add box
		 gridOverlays.push(lineOverlay);  // store grid overlays		 
		 //map.addOverlay(new GPolyline(tile,'black', '1')); // add box
	 }
 }
 
function clearGrid() { //  remove all overlays from map
	while(gridOverlays.length > 0) {
		map.removeOverlay(gridOverlays.pop()); 
	}
}

function windowHeight() {
// Standard browsers (Mozilla, Safari, etc.)
if (self.innerHeight)
return self.innerHeight;
// IE 6
if (document.documentElement && document.documentElement.clientHeight)
return y = document.documentElement.clientHeight;
// IE 5
if (document.body)
return document.body.clientHeight;
// Just in case.
return 0;
}

function displayLat(lat, precision) {
	var m = Math.pow(10, precision);
	lat = Math.round(lat * m) / m;	
	if (lat < 0)
		return Math.abs(lat) + " S";
	else
		return lat + " N";
}

function displayLong(long, precision) {
	var m = Math.pow(10, precision);
	long = Math.round(long * m) / m;	
	if (long < 0)
		return Math.abs(long) + " W";
	else
		return long + " E";
}

	
function roundTo(num, precision) {  // round to so many decimal places for displaying lat long
	var m = Math.pow(10, precision);
	return Math.round(num * m) / m;
}

function tileLabel(osgb) {
	if (tileSize == 25)
		return osgb.getTileRef();
	else
		return osgb.getGridRef(2).split(" ").join("");
}


// tiles class ****************************************************

function Tiles() {
	this.selectedTiles = [];  // selected tiles
	this.tileIds = [];  //  selected tiles by OS grid id
	this.lastTile = 0;  // last tile selected
	this.tileCentres = [];  // delected tiles cetres
	this.lastCentre = new GLatLng(0,0);  // centre of last tile to be clicked on
	this.tileTypes = []; // 25 or 1
}

Tiles.prototype.selectTile = function(osgb) {
	this.trim = tileTrim; // allow a small padding around the selection polyline to prevent overwriting others	
	this.pts = [];	// selected polyline
	this.index = tileLabel(osgb);  // create tile reference index for tiles 

	// test if valid tile
	showUser(this.index)
	//setTimeout("alert(tileStatus)",1250);
	

	
	if (this.lastTile) { // if last tile selection highlighted
		map.removeOverlay(this.lastTile); // remove last tile highlight
	}
	
	botEast = Math.floor(osgb.eastings/tileGridSide)*tileGridSide;  //SW corner
	botNorth = Math.floor(osgb.northings/tileGridSide)*tileGridSide;
	//alert(this.index);

	osgb = new GT_OSGB(); // create new osgb coordinate
	osgb.setGridCoordinates(botEast + this.trim, botNorth + this.trim);
	wgs84 = osgb.getWGS84();
	this.pts[0] = new GLatLng(wgs84.latitude, wgs84.longitude);
	
	osgb = new GT_OSGB(); // create new osgb coordinate
	osgb.setGridCoordinates(botEast + tileGridSide - this.trim, botNorth + this.trim);
	wgs84 = osgb.getWGS84();
	this.pts[1] = new GLatLng(wgs84.latitude, wgs84.longitude);					
	
	osgb = new GT_OSGB(); // create new osgb coordinate
	osgb.setGridCoordinates(botEast + tileGridSide - this.trim, botNorth + tileGridSide - this.trim);
	wgs84 = osgb.getWGS84();
	this.pts[2] = new GLatLng(wgs84.latitude, wgs84.longitude);				
	
	osgb = new GT_OSGB(); // create new osgb coordinate
	osgb.setGridCoordinates(botEast + this.trim, botNorth + tileGridSide - this.trim);
	wgs84 = osgb.getWGS84();
	this.pts[3] = new GLatLng(wgs84.latitude, wgs84.longitude);						
	
	this.pts[4] = this.pts[0]; // add polylines
	 
	this.lastTile = new GPolyline(this.pts,'red', '6') // store this tile so that it can be removed
	map.addOverlay(this.lastTile); // draw tile

	

	// create selected polyline in case it is needed
	this.trim = selectTrim;
	
	osgb = new GT_OSGB(); // create new osgb coordinate
	osgb.setGridCoordinates(botEast + this.trim, botNorth + this.trim);
	wgs84 = osgb.getWGS84();
	this.pts[0] = new GLatLng(wgs84.latitude, wgs84.longitude);
	
	osgb = new GT_OSGB(); // create new osgb coordinate
	osgb.setGridCoordinates(botEast + tileGridSide - this.trim, botNorth + this.trim);
	wgs84 = osgb.getWGS84();
	this.pts[1] = new GLatLng(wgs84.latitude, wgs84.longitude);					
	
	osgb = new GT_OSGB(); // create new osgb coordinate
	osgb.setGridCoordinates(botEast + tileGridSide - this.trim, botNorth + tileGridSide - this.trim);
	wgs84 = osgb.getWGS84();
	this.pts[2] = new GLatLng(wgs84.latitude, wgs84.longitude);				
	
	osgb = new GT_OSGB(); // create new osgb coordinate
	osgb.setGridCoordinates(botEast + this.trim, botNorth + tileGridSide - this.trim);
	wgs84 = osgb.getWGS84();
	this.pts[3] = new GLatLng(wgs84.latitude, wgs84.longitude);						
	
	this.pts[4] = this.pts[0]; // complte square polylines
	
	osgb = new GT_OSGB(); // create new osgb coordinate
	osgb2 = new GT_OSGB(); // create new osgb coordinate	
	osgb.setGridCoordinates(botEast + tileGridSide/2, botNorth + tileGridSide/2);
	osgb2.setGridCoordinates(botEast, botNorth);	
	wgs84 = osgb.getWGS84();
	wgs842 = osgb2.getWGS84();	
	tileCentre = new GLatLng(wgs84.latitude, wgs84.longitude);		
	tileLabelAnchor = new GLatLng(wgs842.latitude, wgs842.longitude);	 

	if (this.selectedTiles[this.index]) { // tile already selected
		document.getElementById("tile").innerHTML = "<form method='post' action='javascript:tiles5k.removeTile();clearGrid();grid();'><b>Selected Tile:</b><br /><span class='blue'>"+this.index+"</span><br /> <input type='submit' value='Remove From Basket' /></form>"; 
		if (!this.lastCentre.equals(tileCentre)) { // cannot remove label if it label is being clicked on
			removeLastLabel(); // remove the last label added by clicking
		}
		this.lastCentre = tileCentre;
		addLabel(tileLabelAnchor,"<a href='javascript:tiles5k.removeTile();clearGrid();grid();' class='blue'>Remove "+tileLabel(osgb)+" From Basket</a>"); 
		
	} else { // process selected new tile
		document.getElementById("tile").innerHTML = "<form method='post' name='addtile'  action='javascript:tiles5k.addTile(tileCentre);clearGrid();grid();'><b>Selected Tile:</b><br /><span class='red'>"+this.index+"</span> <br /><input type='submit' value='Add To Basket' name='addbutton'/></form>"; 
		if (!this.lastCentre.equals(tileCentre)) { // cannot remove label if it label is being clicked on
			removeLastLabel(); // remove the last label added by clicking
		}
		this.lastCentre = tileCentre;		
		addLabel(tileLabelAnchor,"<a id='tileadd' href='javascript:tiles5k.addTile(tileCentre);clearGrid();grid();' class='red'> Add "+tileLabel(osgb)+" To Basket </a>");
	}	
}


Tiles.prototype.addTile = function(tileCentre) {  //  add selected tile to basket,  add blue tile
	this.selectedTiles[this.index] = new GPolyline(this.pts,'blue', '3', '1');  // draw blue box using this.index from last tile selected
	map.addOverlay(this.selectedTiles[this.index]);
	document.getElementById("tile").innerHTML = "<b>Selected Tile:</b><br /> "+this.index+"<br />tile added"; // update selected tile message
	//this.selectedTiles[index] = this.lastTile;
	this.tileIds[this.index] = this.index;  // add tile to tile store
	this.tileCentres[this.index] = tileCentre;
	this.tileTypes[this.index] = tileSize; // store the tile size as tile type ID
	var tile_string = "";
	var tileCount = 0;
	var tileCount1k = 0;  // disable submit if no tiles displayed
	var tileCount25k = 0;  // disable submit if no tiles displayed
	var temp = "<b>Shopping Basket:</b><br /><br />"; // update basket
	var temp1k = "1km<sup>2</sup> Tiles:<br />";
	var temp25k = "<br />25km<sup>2</sup> Tiles:<br />";
	for (i in this.tileIds) {
		if (this.tileIds[i]) {
			tile_string += this.tileCentres[i].lat() + "," + this.tileCentres[i].lng() + "," + this.tileIds[i] + "," + this.tileTypes[i] + ","; // create basket message
			if (this.tileTypes[i] == 1) {
				temp1k += "<a href='javascript:newCenterMarker("+this.tileCentres[i].lat()+","+this.tileCentres[i].lng()+",\""+this.tileIds[i]+"\"); grid();'>"+this.tileIds[i]+"</a><br />"; // create order
			tileCount1k++;	
			tileCount++;	
			} else {
				temp25k += "<a href='javascript:newCenterMarker("+this.tileCentres[i].lat()+","+this.tileCentres[i].lng()+",\""+this.tileIds[i]+"\"); grid();'>"+this.tileIds[i]+"</a><br />"; // create order
			tileCount25k++;	
			tileCount++;	
			}
		}
	}
	if (tileCount) {
		if (tileCount1k) // add sub totals
			temp += temp1k;
		if (tileCount25k)	
			temp += temp25k ;
		temp += "<br />(click to view the tile)<br /><form action='payment.php' method='post'><input type='submit' value='Purchase Tiles' /></form>";  // this POST is now redundant
	} else
		temp += "Basket Empty";
	
	document.getElementById("basket").innerHTML = temp; // update basket message
	
	var httpReq = GXmlHttp.create(); // set up http request to update shopping basket session variable
	httpReq.open('POST', 'basket.php', true);
	httpReq.onreadystatechange = function() {
			if (httpReq.readyState == 4) {
				if (httpReq.responseText != "OK")
					alert("basket update failed");
			}
	}
	httpReq.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
	httpReq.send("tilestring="+ tile_string + tileCount);
	
}

Tiles.prototype.removeTile = function() {  // remove tile from basket and remove tile display
	map.removeOverlay(this.selectedTiles[this.index]); // add box
	this.selectedTiles[this.index] = 0;
	this.tileTypes[this.index] = tileSize; // store the tile size as tile type ID
	document.getElementById("tile").innerHTML = "<b>Selected Tile:</b><br />"+this.index+"<br />tile removed"; 
	this.tileIds[this.index] = "";
	var tile_string = "";
	var tileCount = 0;
	var tileCount1k = 0;  // disable submit if no tiles displayed
	var tileCount25k = 0;  // disable submit if no tiles displayed
	var temp = "<b>Shopping Basket:</b><br /><br />"; // update basket
	var temp1k = "1km<sup>2</sup> Tiles:<br />";
	var temp25k = "<br />25km<sup>2</sup> Tiles:<br />";
	for (i in this.tileIds) {
		if (this.tileIds[i]) {
			tile_string += this.tileCentres[i].lat() + "," + this.tileCentres[i].lng() + "," + this.tileIds[i] + "," + this.tileTypes[i] + ","; // create basket message
			if (this.tileTypes[i] == 1) {
				temp1k += "<a href='javascript:newCenterMarker("+this.tileCentres[i].lat()+","+this.tileCentres[i].lng()+",\""+this.tileIds[i]+"\"); grid();'>"+this.tileIds[i]+"</a><br />"; // create order
			tileCount1k++;	
			tileCount++;	
			} else {
				temp25k += "<a href='javascript:newCenterMarker("+this.tileCentres[i].lat()+","+this.tileCentres[i].lng()+",\""+this.tileIds[i]+"\"); grid();'>"+this.tileIds[i]+"</a><br />"; // create order
			tileCount25k++;	
			tileCount++;	
			}
		}
	}
	if (tileCount) {
		if (tileCount1k) // add sub totals
			temp += temp1k;
		if (tileCount25k)	
			temp += temp25k ;
		temp += "<br />(click to view the tile)<br /><form action='payment.php' method='post'><input type='submit' value='Purchase Tiles' /></form>";  // this POST is now redundant
	} else
		temp += "Basket Empty";
		
	document.getElementById("basket").innerHTML = temp;
	
	var httpReq = GXmlHttp.create(); // set up http request to update shopping basket session variable
	httpReq.open('POST', 'basket.php', true);
	httpReq.onreadystatechange = function() {
			if (httpReq.readyState == 4) {
				if (httpReq.responseText != "OK")
					alert("basket update failed");
			}
	}
	httpReq.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
	httpReq.send("tilestring="+ tile_string + tileCount);
}
//****************************************************************
//  map labels stuff
function ToolTip(point,html,width) {
	this.html_ = html;
	this.width_ = (width ? width + 'px' : 'auto');
	this.point_ = point;
	this.lastLabel = 0 // last selected tile label
}

ToolTip.prototype = new GOverlay();

ToolTip.prototype.initialize = function(map) {
	var div = document.createElement("div");
	div.style.display = 'none';
	map.getPane(G_MAP_FLOAT_PANE).appendChild(div);
	this.map_ = map;
	this.container_ = div;
}

ToolTip.prototype.remove = function() {
	this.container_.parentNode.removeChild(this.container_);
}

ToolTip.prototype.copy = function() {
	return new ToolTip(this.html_);
}

ToolTip.prototype.redraw = function(force) {
	if (!force) return;
	var pixelLocation = this.map_.fromLatLngToDivPixel(this.point_);
	//var pixelLocation = this.map_.fromLatLngToDivPixel(new GLatLng( 55.952179, -3.196507));
	this.container_.innerHTML = this.html_;
	this.container_.style.position = 'absolute';
	this.container_.style.left = pixelLocation.x + "px";
	this.container_.style.top = (pixelLocation.y-17) + "px";
	this.container_.style.width = this.width_;
	this.container_.style.font = ' 10px/10px verdana, arial, sans';
	this.container_.style.border = '1px solid black';
	this.container_.style.color = 'black';
	//this.container_.style.background = '#7BEB29';
	this.container_.style.background = 'white';
	this.container_.style.padding = '2px';
	//one line to desired width
	this.container_.style.whiteSpace = 'nowrap';
	if(this.width_ != 'auto') this.container_.style.overflow = 'hidden';
	this.container_.style.display = 'block';
}

addLabel = function(point,content) { // add a new label
//don't show the tool tip if there is a custom info window
	labelOverlay = new ToolTip(point,content)
	map.addOverlay(labelOverlay);
	gridOverlays.push(labelOverlay);  // store grid overlays
	//this.lastLabel = labelOverlay// store this tile label	
	llabel = labelOverlay;
	return labelOverlay; // return overlay so it can be  removed
}

removeLastLabel = function() {  // remove the last new label added
	if (llabel) { // if last label present
		map.removeOverlay(llabel); // remove last selected tile label
	}
}
//****************************************************************
// Ajax functions to send purchase list to server




//****************************************************************
window.onload = init;  // on start up go to top
window.onunload = GUnload;



				
		

