// JavaScript Document
	var GridRefFigure = 10;
	var mGridReference;
	var map = null;
	var gmap = null;
	var GeoCoder = null;
	var IsGMapLoaded = false;
    var mGLargeMapControl3D = new GLargeMapControl3D();
    var mGOverviewMapControl = new GOverviewMapControl();
	//<![CDATA[
	//LoadGoogleMap(false);
	//OpenGoogleMap("SJ540823",false);
	//$("#GoogleMapControl").slideDown("normal");
		
	function OpenGoogleMap(GridReference, IsFixed, IsGetGrid){
		if(mGLargeMapControl3D == null){
			alert("To enable Google Map facility please reload RODIS and click NO on security warning");
			return false;
		}
	    mGridReference = GridReference;
		$("#GoogleMapControl").slideDown();
		if(IsGMapLoaded == false) LoadGoogleMap(IsFixed, IsGetGrid);
		map.checkResize();
		var latlng;
		if(GridReference){
			latlng = convertOSGB36toWGS84(OSGridToLatLong(GridReference));
			map.setCenter(new GLatLng(latlng.lat, latlng.lon),getZoomLevelFromGrid(GridReference));	
		}else{
		    map.setCenter(new GLatLng(53.215902,-2.551575),9);
		}
		if (IsFixed == true){
		    map.removeControl(mGLargeMapControl3D);
		    map.removeControl(mGOverviewMapControl);
		    map.disableDragging();
		    map.setMapType(G_HYBRID_MAP);
		    /*
		    GEvent.addListener(map, "move", function(){
		        map.setCenter(new GLatLng(latlng.lat, latlng.lon),17);
		    });
		    */
		}
		map.enableDoubleClickZoom();
	}
	
	
	function FixedMapGridFigure(GridReference){
	    var len;
	    switch(GridReference.substr(2).length){
	        case 2:
	            len = 4;
	        break;
	        case 4:
	            len = 6;
	        break;
	        case 6:
	            len = 8;
	        break;
	        case 8:
	            len = 10;
	        break;
	        case 10:
	            len = 10;
	        break; 
	    }
	    return len;
	}
	function getZoomLevelFromGrid(GridReference){
	    var level;
	    switch(GridReference.substr(2).length){
	        case 2:
	            level = 12;
	        break;
	        case 4:
	            level = 15;
	        break;
	        case 6:
	            level = 17;
	        break;
	        case 8:
	            level = 18;
	        break;
	        case 10:
	            level = 18;
	        break; 
	    }
	    return level;
	}
	function CloseGoogleMap(){
		$("#GoogleMapControl").slideUp("normal");
		IsGMapLoaded = false;
		//GUnload();
	}
	/*Non used function, made for getting the similar location name
	function DisplaySearchLocationMatches(){
		GeoCoder.getLocations(document.getElementById("SearchTerm").value,function(response){
			if(response){
				for(EachAddress in response.Placemark){
					Result += ", "+ EachAddress.address+","+EachAddress.Country.CountryName;
				}
				alert(Result);
			}
		});
	}
	*/
	function SearchLocation(IsGridRef){
		var SearchTerm = document.getElementById("SearchTerm").value;
		//Search using grid reference
		//var RegGridRef = new RegExp("[A-Za-z]{2}[^\s][0-9]{1,12}");
		//var IsGridRef = RegGridRef.exec(SearchTerm); 
		if(IsGridRef == true){
			var latlng = convertOSGB36toWGS84(OSGridToLatLong(SearchTerm));
			map.setCenter(new GLatLng(latlng.lat, latlng.lon),14);
			return false;
		}else{
			//Check if postcode
			//var RegUKPostcode = new RegExp("^([A-PR-UWYZ0-9][A-HK-Y0-9][AEHMNPRTVXY0-9]?[ABEHMNPRVWXY0-9]? {1,2}[0-9][ABD-HJLN-UW-Z]{2}|GIR 0AA)$");
			var RegUKPostcode = new RegExp("^[A-Za-z]{1,2}[0-9A-Za-z]{1,2}[ ]?[0-9]{0,1}[A-Za-z]{2}$");
			var IsUKPostcode = RegUKPostcode.exec(SearchTerm);
			if(!IsUKPostcode){
				//Search using location name
				SearchTerm += ",UK";
				GeoCoder.getLatLng(SearchTerm,function(point){
					if(point){
						map.setCenter(point,14);
					}else{
						alert(SearchTerm +" not found");
					}
				});
			}else{
				//Search using postcode
				usePointFromPostcode(SearchTerm, placeMarkerAtPoint);
			}
		}		
		return false;
	}
	
	function usePointFromPostcode(postcode, callbackFunction) {
		var localSearch = new GlocalSearch();
		localSearch.setSearchCompleteCallback(null, 
			function() {
				if (localSearch.results[0])
				{		
					var resultLat = localSearch.results[0].lat;
					var resultLng = localSearch.results[0].lng;
					var point = new GLatLng(resultLat,resultLng);
					callbackFunction(point);
				}else{
					alert("Postcode not found!");
				}
			});	
			
		localSearch.execute(postcode + ", UK");
	}
	
	function placeMarkerAtPoint(point)
	{
		var icon = new GIcon();
		icon.image = "http://www.google.com/mapfiles/marker.png";
		icon.shadow = "http://www.google.com/mapfiles/shadow50.png";
		icon.iconSize = new GSize(20, 34);
		icon.shadowSize = new GSize(37, 34);
		icon.iconAnchor = new GPoint(10, 34);	
		var marker = new GMarker(point,icon);
		map.setCenter(point, 17);
		map.addOverlay(marker);
	}

	
	function LoadGoogleMap(IsFixed,IsGetGrid) {
		/*
		console.log("LoadGoogleMap");
		console.log("IsFixed: "+ IsFixed);
		console.log("IsGetGrid: "+ IsGetGrid);
      	*/
	  if (GBrowserIsCompatible()) {
		IsGMapLoaded = true;
        map = new GMap2(document.getElementById("GoogleMap"));
		map.addControl(mGLargeMapControl3D);
		map.addControl(new GHierarchicalMapTypeControl());
		map.addControl(mGOverviewMapControl);
	  	//map.addControl(new GMapTypeControl());
		map.addMapType(G_PHYSICAL_MAP);
		//map.addMapType(G_SATELLITE_3D_MAP);
	  	map.addControl(new GScaleControl());
		GeoCoder = new GClientGeocoder();
        map.setCenter(new GLatLng(53.215902,-2.551575),9);
		gmap = map;
		if(IsGetGrid == true){
			GEvent.addListener(map,"click",function(overlay,latlng){
			map.clearOverlays();
			if(latlng){
				$("#gridMessage").show();
	   
				//get the scale
				var LatLngBounds = map.getBounds();
				var SouthWest = LatLngBounds.getSouthWest();
				var NorthEast = LatLngBounds.getNorthEast();
				var Scale = SouthWest.distanceFrom(NorthEast);
				
				//config the grid ref figure
				if (Scale < 100){
					GridRefFigure = 10;
				}else if(Scale > 100 && Scale < 350){
					GridRefFigure = 8;
				}else if(Scale > 350 && Scale < 2000){
					GridRefFigure = 6;
				}else if(Scale > 2000){
					GridRefFigure = 4;
				}
				if(IsFixed == true) GridRefFigure = FixedMapGridFigure(mGridReference);
				
				var OSGrid = GetOSGB(latlng.lat(),latlng.lng());
				
				//Create the grid square on the map
				var GridSquare = new GetLatLongSquareFromGridRef(OSGrid);
				var GridSquarePolygon = new GPolygon([
					new GLatLng(GridSquare.lat1,GridSquare.lon1),
					new GLatLng(GridSquare.lat2,GridSquare.lon2),
					new GLatLng(GridSquare.lat3,GridSquare.lon3),
					new GLatLng(GridSquare.lat4,GridSquare.lon4),
					new GLatLng(GridSquare.lat5,GridSquare.lon5),
					], "#f33f00", 3, 1);
				map.addOverlay(GridSquarePolygon);
				var EN = gridrefLetToNum(OSGrid);
				var message = "<font size='12px'>"+OSGrid+" / "+ EN[0]+","+EN[1]+"<br><button onClick=\"AddGridReference('"+ OSGrid +"');\">Insert Grid reference</button>";
	            /*if(IsFixed == true)*/ message += "<br/>Please zoom in or change to Satellite for greater accuracy"
	            message += "</font>"   			
				//map.openInfoWindow(latlng,message);	
				showGridMessage(message);		
			}
			});
		}else{
			$("#gridMessage").hide();
		}
		
      }

	  
	  
    }
	
	function AddGridReference(GridReference){
		CloseGoogleMap();
		//console.log(getFlashMovie("RODIS"));
		//document.getElementById("RODIS").AddGrid(GridReference);
		var r = RODISFlash("RODIS");
		r.AddGrid(GridReference);
		GUnload();	
		IsGMapLoaded = false;
	}
	
	function showGridMessage(message){
		$("#gridMessage").html(message);
	}
	function GetOSGB(lat,lng){
		var LT = new LatLon(lat,lng,0);
		var OSGB36 = convertWGS84toOSGB36(LT);
		return LatLongToOSGrid(OSGB36);
		//alert(LT.lat); 
	}
	
	function GetLatLongSquareFromGridRef(GridRef){
		var SquareSize = 0;
		switch(GridRefFigure){
			case 4:
				SquareSize = 1000;
			break;
			case 6:
				SquareSize = 100;
			break;
			case 8:
				SquareSize = 10;
			break;
			case 10:
				SquareSize = 1;
			break;
		}
		var EN = gridrefLetToNum(GridRef);
		var E = EN[0];
		var N =  EN[1];
		switch(GridRefFigure){
			case 4:
				E = E.substring(0,4)+"00";
				N = N.substring(0,4)+"00";
			break;
			case 6:
				E = E.substring(0,4)+"00";
				N = N.substring(0,4)+"00";
			break;
			case 8:
				E = E.substring(0,6)+"";
				N = N.substring(0,6)+"";
			break;
		}
		//alert(E+"/"+N+", "+GridRefFigure+"/"+SquareSize);
		var x1 = E;
		var y1 = N;
		var GridRefXY1 = gridrefNumToLet(x1,y1, GridRefFigure);
		var latlng1 = convertOSGB36toWGS84(OSGridToLatLong(GridRefXY1));
		
		var x2 = Number(E)+SquareSize;
		var y2 = Number(N);
		//alert(y2);
		var GridRefXY2 = gridrefNumToLet(x2,y2, GridRefFigure);
		var latlng2 = convertOSGB36toWGS84(OSGridToLatLong(GridRefXY2));
		
		var x3 = Number(E)+SquareSize;
		var y3 = Number(N)+SquareSize;
		var GridRefXY3 = gridrefNumToLet(x3,y3, GridRefFigure);
		var latlng3 = convertOSGB36toWGS84(OSGridToLatLong(GridRefXY3));
		
		var x4 = Number(E);
		var y4 = Number(N)+SquareSize;
		var GridRefXY4 = gridrefNumToLet(x4,y4, GridRefFigure);
		var latlng4 = convertOSGB36toWGS84(OSGridToLatLong(GridRefXY4));
		
		var x5 = Number(E);
		var y5 = Number(N);
		var GridRefXY5 = gridrefNumToLet(x5,y5, GridRefFigure);
		var latlng5 = convertOSGB36toWGS84(OSGridToLatLong(GridRefXY5));
		
		this.lat1 = latlng1.lat;
		this.lon1 = latlng1.lon;
		this.lat2 = latlng2.lat;
		this.lon2 = latlng2.lon;
		this.lat3 = latlng3.lat;
		this.lon3 = latlng3.lon;
		this.lat4 = latlng4.lat;
		this.lon4 = latlng4.lon;
		this.lat5 = latlng5.lat;
		this.lon5 = latlng5.lon;
	}
/*
 * convert geodesic co-ordinates to OS grid reference
 */
 /*
 * construct a LatLon object: arguments in numeric degrees
 *
 * note all LatLong methods expect & return numeric degrees (for lat/long & for bearings)
 */
function LatLon(lat, lon, height) {
  if (arguments.length < 3) height = 0;
  this.lat = lat;
  this.lon = lon;
  this.height = height;
}

function LatLongToEN(p) {
  var lat = p.lat.toRad(), lon = p.lon.toRad();
  //var lat = p.lat, lon = p.lon;
  var a = 6377563.396, b = 6356256.910;          // Airy 1830 major & minor semi-axes
  var F0 = 0.9996012717;                         // NatGrid scale factor on central meridian
  var lat0 = (49).toRad(), lon0 = (-2).toRad();
  //var lat0 = 49, lon0 = -2;  // NatGrid true origin
  var N0 = -100000, E0 = 400000;                 // northing & easting of true origin, metres
  var e2 = 1 - (b*b)/(a*a);                      // eccentricity squared
  var n = (a-b)/(a+b), n2 = n*n, n3 = n*n*n;

  var cosLat = Math.cos(lat), sinLat = Math.sin(lat);
  var nu = a*F0/Math.sqrt(1-e2*sinLat*sinLat);              // transverse radius of curvature
  var rho = a*F0*(1-e2)/Math.pow(1-e2*sinLat*sinLat, 1.5);  // meridional radius of curvature
  var eta2 = nu/rho-1;

  var Ma = (1 + n + (5/4)*n2 + (5/4)*n3) * (lat-lat0);
  var Mb = (3*n + 3*n*n + (21/8)*n3) * Math.sin(lat-lat0) * Math.cos(lat+lat0);
  var Mc = ((15/8)*n2 + (15/8)*n3) * Math.sin(2*(lat-lat0)) * Math.cos(2*(lat+lat0));
  var Md = (35/24)*n3 * Math.sin(3*(lat-lat0)) * Math.cos(3*(lat+lat0));
  var M = b * F0 * (Ma - Mb + Mc - Md);              // meridional arc

  var cos3lat = cosLat*cosLat*cosLat;
  var cos5lat = cos3lat*cosLat*cosLat;
  var tan2lat = Math.tan(lat)*Math.tan(lat);
  var tan4lat = tan2lat*tan2lat;

  var I = M + N0;
  var II = (nu/2)*sinLat*cosLat;
  var III = (nu/24)*sinLat*cos3lat*(5-tan2lat+9*eta2);
  var IIIA = (nu/720)*sinLat*cos5lat*(61-58*tan2lat+tan4lat);
  var IV = nu*cosLat;
  var V = (nu/6)*cos3lat*(nu/rho-tan2lat);
  var VI = (nu/120) * cos5lat * (5 - 18*tan2lat + tan4lat + 14*eta2 - 58*tan2lat*eta2);

  var dLon = lon-lon0;
  var dLon2 = dLon*dLon, dLon3 = dLon2*dLon, dLon4 = dLon3*dLon, dLon5 = dLon4*dLon, dLon6 = dLon5*dLon;

  var N = I + II*dLon2 + III*dLon4 + IIIA*dLon6;
  var E = E0 + IV*dLon + V*dLon3 + VI*dLon5;
	//alert(E);
	//alert(N);
  return [E,N];
}

function LatLongToOSGrid(p) {
  var lat = p.lat.toRad(), lon = p.lon.toRad();
  //var lat = p.lat, lon = p.lon;
  var a = 6377563.396, b = 6356256.910;          // Airy 1830 major & minor semi-axes
  var F0 = 0.9996012717;                         // NatGrid scale factor on central meridian
  var lat0 = (49).toRad(), lon0 = (-2).toRad();
  //var lat0 = 49, lon0 = -2;  // NatGrid true origin
  var N0 = -100000, E0 = 400000;                 // northing & easting of true origin, metres
  var e2 = 1 - (b*b)/(a*a);                      // eccentricity squared
  var n = (a-b)/(a+b), n2 = n*n, n3 = n*n*n;

  var cosLat = Math.cos(lat), sinLat = Math.sin(lat);
  var nu = a*F0/Math.sqrt(1-e2*sinLat*sinLat);              // transverse radius of curvature
  var rho = a*F0*(1-e2)/Math.pow(1-e2*sinLat*sinLat, 1.5);  // meridional radius of curvature
  var eta2 = nu/rho-1;

  var Ma = (1 + n + (5/4)*n2 + (5/4)*n3) * (lat-lat0);
  var Mb = (3*n + 3*n*n + (21/8)*n3) * Math.sin(lat-lat0) * Math.cos(lat+lat0);
  var Mc = ((15/8)*n2 + (15/8)*n3) * Math.sin(2*(lat-lat0)) * Math.cos(2*(lat+lat0));
  var Md = (35/24)*n3 * Math.sin(3*(lat-lat0)) * Math.cos(3*(lat+lat0));
  var M = b * F0 * (Ma - Mb + Mc - Md);              // meridional arc

  var cos3lat = cosLat*cosLat*cosLat;
  var cos5lat = cos3lat*cosLat*cosLat;
  var tan2lat = Math.tan(lat)*Math.tan(lat);
  var tan4lat = tan2lat*tan2lat;

  var I = M + N0;
  var II = (nu/2)*sinLat*cosLat;
  var III = (nu/24)*sinLat*cos3lat*(5-tan2lat+9*eta2);
  var IIIA = (nu/720)*sinLat*cos5lat*(61-58*tan2lat+tan4lat);
  var IV = nu*cosLat;
  var V = (nu/6)*cos3lat*(nu/rho-tan2lat);
  var VI = (nu/120) * cos5lat * (5 - 18*tan2lat + tan4lat + 14*eta2 - 58*tan2lat*eta2);

  var dLon = lon-lon0;
  var dLon2 = dLon*dLon, dLon3 = dLon2*dLon, dLon4 = dLon3*dLon, dLon5 = dLon4*dLon, dLon6 = dLon5*dLon;

  var N = I + II*dLon2 + III*dLon4 + IIIA*dLon6;
  var E = E0 + IV*dLon + V*dLon3 + VI*dLon5;
	//alert(E);
	//alert(N);
  return gridrefNumToLet(E, N, GridRefFigure);
}


/*
 * convert OS grid reference to geodesic co-ordinates
 */
function OSGridToLatLong(gridRef) {
  var gr = gridrefLetToNum(gridRef);
  var E = gr[0], N = gr[1];

  var a = 6377563.396, b = 6356256.910;              // Airy 1830 major & minor semi-axes
  var F0 = 0.9996012717;                             // NatGrid scale factor on central meridian
  var lat0 = 49*Math.PI/180, lon0 = -2*Math.PI/180;  // NatGrid true origin
  var N0 = -100000, E0 = 400000;                     // northing & easting of true origin, metres
  var e2 = 1 - (b*b)/(a*a);                          // eccentricity squared
  var n = (a-b)/(a+b), n2 = n*n, n3 = n*n*n;

  var lat=lat0, M=0;
  do {
    lat = (N-N0-M)/(a*F0) + lat;

    var Ma = (1 + n + (5/4)*n2 + (5/4)*n3) * (lat-lat0);
    var Mb = (3*n + 3*n*n + (21/8)*n3) * Math.sin(lat-lat0) * Math.cos(lat+lat0);
    var Mc = ((15/8)*n2 + (15/8)*n3) * Math.sin(2*(lat-lat0)) * Math.cos(2*(lat+lat0));
    var Md = (35/24)*n3 * Math.sin(3*(lat-lat0)) * Math.cos(3*(lat+lat0));
    M = b * F0 * (Ma - Mb + Mc - Md);                // meridional arc

  } while (N-N0-M >= 0.00001);  // ie until < 0.01mm

  var cosLat = Math.cos(lat), sinLat = Math.sin(lat);
  var nu = a*F0/Math.sqrt(1-e2*sinLat*sinLat);              // transverse radius of curvature
  var rho = a*F0*(1-e2)/Math.pow(1-e2*sinLat*sinLat, 1.5);  // meridional radius of curvature
  var eta2 = nu/rho-1;

  var tanLat = Math.tan(lat);
  var tan2lat = tanLat*tanLat, tan4lat = tan2lat*tan2lat, tan6lat = tan4lat*tan2lat;
  var secLat = 1/cosLat;
  var nu3 = nu*nu*nu, nu5 = nu3*nu*nu, nu7 = nu5*nu*nu;
  var VII = tanLat/(2*rho*nu);
  var VIII = tanLat/(24*rho*nu3)*(5+3*tan2lat+eta2-9*tan2lat*eta2);
  var IX = tanLat/(720*rho*nu5)*(61+90*tan2lat+45*tan4lat);
  var X = secLat/nu;
  var XI = secLat/(6*nu3)*(nu/rho+2*tan2lat);
  var XII = secLat/(120*nu5)*(5+28*tan2lat+24*tan4lat);
  var XIIA = secLat/(5040*nu7)*(61+662*tan2lat+1320*tan4lat+720*tan6lat);

  var dE = (E-E0), dE2 = dE*dE, dE3 = dE2*dE, dE4 = dE2*dE2, dE5 = dE3*dE2, dE6 = dE4*dE2, dE7 = dE5*dE2;
  lat = lat - VII*dE2 + VIII*dE4 - IX*dE6;
  var lon = lon0 + X*dE - XI*dE3 + XII*dE5 - XIIA*dE7;

  return new LatLon(lat.toDeg(), lon.toDeg());
}


/* 
 * convert standard grid reference ('SU387148') to fully numeric ref ([438700,114800])
 *   returned co-ordinates are in metres, centred on grid square for conversion to lat/long
 *
 *   note that northern-most grid squares will give 7-digit northings
 *   no error-checking is done on gridref (bad input will give bad results or NaN)
 */
function gridrefLetToNum(gridref) {
  // get numeric values of letter references, mapping A->0, B->1, C->2, etc:
  var l1 = gridref.toUpperCase().charCodeAt(0) - 'A'.charCodeAt(0);
  var l2 = gridref.toUpperCase().charCodeAt(1) - 'A'.charCodeAt(0);
  // shuffle down letters after 'I' since 'I' is not used in grid:
  if (l1 > 7) l1--;
  if (l2 > 7) l2--;

  // convert grid letters into 100km-square indexes from false origin (grid square SV):
  var e = ((l1-2)%5)*5 + (l2%5);
  var n = (19-Math.floor(l1/5)*5) - Math.floor(l2/5);

  // skip grid letters to get numeric part of ref, stripping any spaces:
  gridref = gridref.slice(2).replace(/ /g,'');

  // append numeric part of references to grid index:
  e += gridref.slice(0, gridref.length/2);
  n += gridref.slice(gridref.length/2);
  //alert(e +" "+ n +"/"+gridref.length);
  // normalise to 1m grid, rounding up to centre of grid square:
  switch (gridref.length) {
  	case 4: e += '000'; n += '000'; break;
    case 6: e += '00'; n += '00'; break;
    case 8: e += '0'; n += '0'; break;
    // 10-digit refs are already 1m
  }
  //alert(e +" "+ n);
  return [e, n];
}


/*
 * convert numeric grid reference (in metres) to standard-form grid ref
 */
function gridrefNumToLet(e, n, digits) {
  // get the 100km-grid indices
  //n -= n+n; 
  //alert(n);
  var e100k = Math.floor(e/100000), n100k = Math.floor(n/100000);
  //alert(e100k);
  //alert(n100k);
  if (e100k<0 || e100k>6 || n100k<0 || n100k>12) return 'not in uk';

  // translate those into numeric equivalents of the grid letters
  var l1 = (19-n100k) - (19-n100k)%5 + Math.floor((e100k+10)/5);
  var l2 = (19-n100k)*5%25 + e100k%5;

  // compensate for skipped 'I' and build grid letter-pairs
  if (l1 > 7) l1++;
  if (l2 > 7) l2++;
  var letPair = String.fromCharCode(l1+'A'.charCodeAt(0), l2+'A'.charCodeAt(0));
  // strip 100km-grid indices from easting & northing, and reduce precision
  e = Math.floor((e%100000)/Math.pow(10,5-digits/2));
  n = Math.floor((n%100000)/Math.pow(10,5-digits/2));
	
  var gridRef = letPair + e.padLZ(digits/2) + n.padLZ(digits/2);

  return gridRef;
}

// ellipse parameters
var e = { WGS84:    { a: 6378137,     b: 6356752.3142, f: 1/298.257223563 },
          Airy1830: { a: 6377563.396, b: 6356256.910,  f: 1/299.3249646   } };

// helmert transform parameters
var h = { WGS84toOSGB36: { tx: -446.448,  ty:  125.157,   tz: -542.060,   // m
                           rx:   -0.1502, ry:   -0.2470,  rz:   -0.8421,  // sec
                           s:    20.4894 },                               // ppm
          OSGB36toWGS84: { tx:  446.448,  ty: -125.157,   tz:  542.060,
                           rx:    0.1502, ry:    0.2470,  rz:    0.8421,
                           s:   -20.4894 } };


function convertOSGB36toWGS84(p1) {
  var p2 = convert(p1, e.Airy1830, h.OSGB36toWGS84, e.WGS84);
  return p2;
}


function convertWGS84toOSGB36(p1) {
  var p2 = convert(p1, e.WGS84, h.WGS84toOSGB36, e.Airy1830);
  return p2;
}


function convert(p, e1, t, e2) {
  // -- convert polar to cartesian coordinates (using ellipse 1)
  
  p1 = new LatLon(p.lat, p.lon, p.height);  // to avoid modifying passed param
  p1.lat = p.lat.toRad(); p1.lon = p.lon.toRad(); 

  var a = e1.a, b = e1.b;

  var sinPhi = Math.sin(p1.lat), cosPhi = Math.cos(p1.lat);
  var sinLambda = Math.sin(p1.lon), cosLambda = Math.cos(p1.lon);
  var H = p1.height;

  var eSq = (a*a - b*b) / (a*a);
  var nu = a / Math.sqrt(1 - eSq*sinPhi*sinPhi);

  var x1 = (nu+H) * cosPhi * cosLambda;
  var y1 = (nu+H) * cosPhi * sinLambda;
  var z1 = ((1-eSq)*nu + H) * sinPhi;


  // -- apply helmert transform using appropriate params
  
  var tx = t.tx, ty = t.ty, tz = t.tz;
  var rx = t.rx/3600 * Math.PI/180;  // normalise seconds to radians
  var ry = t.ry/3600 * Math.PI/180;
  var rz = t.rz/3600 * Math.PI/180;
  var s1 = t.s/1e6 + 1;              // normalise ppm to (s+1)

  // apply transform
  var x2 = tx + x1*s1 - y1*rz + z1*ry;
  var y2 = ty + x1*rz + y1*s1 - z1*rx;
  var z2 = tz - x1*ry + y1*rx + z1*s1;


  // -- convert cartesian to polar coordinates (using ellipse 2)

  a = e2.a, b = e2.b;
  var precision = 4 / a;  // results accurate to around 4 metres

  eSq = (a*a - b*b) / (a*a);
  var p = Math.sqrt(x2*x2 + y2*y2);
  var phi = Math.atan2(z2, p*(1-eSq)), phiP = 2*Math.PI;
  while (Math.abs(phi-phiP) > precision) {
    nu = a / Math.sqrt(1 - eSq*Math.sin(phi)*Math.sin(phi));
    phiP = phi;
    phi = Math.atan2(z2 + eSq*nu*Math.sin(phi), p);
  }
  var lambda = Math.atan2(y2, x2);
  H = p/Math.cos(phi) - nu;

  return new LatLon(phi.toDeg(), lambda.toDeg(), H);
}


/*
 * pad a number with sufficient leading zeros to make it w chars wide
 */
Number.prototype.padLZ = function(w) {
  var n = this.toString();
  for (var i=0; i<w-n.length; i++) n = '0' + n;
  return n;
}
Number.prototype.toRad = function() {  // convert degrees to radians
  return this * Math.PI / 180;
}
Number.prototype.toDeg = function() {  // convert radians to degrees (signed)
  return this * 180 / Math.PI;
}




/************************************************************************************************/
//Map data {{},{},{}}

/*
	var data = {"MapData":[{species:"Bufo bufo",grid:"SJ540823",date:"10/12/2009",recorder:"Luck",determiner:"Luck"},
						   {species:"Common toad",grid:"SJ540823",date:"10/12/2009",recorder:"Luck",determiner:"Luck"},
				   {species:"Vulpes vulpes",grid:"SJ545828",date:"10/12/2009",recorder:"Luck",determiner:"Luck"}]};
	//PutDataOnMap(data);
*/
function PutDataOnMap(arg){
	$("#GoogleMapControl").slideDown();
	if(IsGMapLoaded == false) LoadGoogleMap(false,false);
	
	
	map.checkResize();
	//console.log(arg);
	//MapData = jQuery.parseJASON(arg);
	MapData= arg;
	//console.log(gmap);
	//console.log(MapData.MapData[1].species);
	
	/*
	var icon = new GIcon();
	icon.image = "http://www.google.com/mapfiles/marker.png";
	//icon.shadow = "http://www.google.com/mapfiles/shadow50.png";
	icon.iconSize = new GSize(20, 34);
	icon.shadowSize = new GSize(37, 34);
	icon.iconAnchor = new GPoint(10, 34);	
	*/
	var markers = new Array();
	var gridList = new Array();
	var point;
	var msg = "";
	var infoData = new Object();
	var mappingInfoData = new Array(); /* sample json / {"SJ8956":[{},{},{}],"SJ4585":[{},{},{}]} */
	infoData.add = function(grid,data){
		//console.log("add");
		//console.log(jQuery.inArray(grid,mappingInfoData));
		if(jQuery.inArray(grid,mappingInfoData) == -1){
			//console.log("push");
			mappingInfoData.push(grid);
			mappingInfoData[grid] = data;
		}else{
			//console.log("append");
			mappingInfoData[grid] += data;
		}
		//console.log(mappingInfoData);
	};
	
	
	for(var i in MapData.MapData){
		//console.log(i);
		var data = MapData.MapData[i];
		var species = data.species;
		
		//console.log(data);
		
		var grid = data.grid;
		//console.log(grid);
		
		//console.log(ll);
		var date = data.date;
		var recorder = data.recorder;
		var determiner = data.determiner;
		
		
		msg = "<p class='InfoWindow'>Species: "+ species +"<br/>Grid Ref.: "+ grid +"<br/>Observer: "+ recorder +"<br/>Determiner: "+ determiner +"</p>";
			
		//Build up data based on the same grid
		infoData.add(grid,msg);	
		
		
	}
	//console.log(mappingInfoData);
	//Loop through date and add marker
	var i = 0;
	for(var a in mappingInfoData){
		
		msg = "<div class='InfoWrap'>"+mappingInfoData[a]+"</div>";
		//console.log(mappingInfoData[a]);
		//console.log("-"+a);
		var icon = new GIcon(G_DEFAULT_ICON);
		
		var ll = convertOSGB36toWGS84(OSGridToLatLong(a));
		
		point = new GLatLng(ll.lat,ll.lon);
		
		markers[i] = new GMarker(point,icon);
		
		markers[i].bindInfoWindowHtml(msg,{maxWidth:500});		
		i++;
	}
		
	var manager = new GMarkerManager(map);
	manager.addMarkers(markers, 1, 17);
	
	//map.setCenter(point, 10);
	manager.refresh();
	map.setZoom(5);
	//map.addOverlay = (new GMarker(point));
		
}
