// Define a GSpot

function gSpot(latitude, longitude, contentId) {
	this._lat = latitude;
	this._long = longitude;
	this._contentId = contentId;
	
	this.Latitude = function() {
		return this._lat;
	}
	this.Longitude = function() {
		return this._long;
	}
	this.ContentId = function() {
		return this._contentId;
	}
};


function googleMaps() {
    this.initialize = function(easting, northing, gSpots, showRadius, mapRadius) {

	var rad2deg = 180.0 / Math.PI;

	east = easting * 10;
  	north = northing * 10;
  	geo = NEtoLL(east, north);
  	lat = geo.latitude * rad2deg;
  	lon = geo.longitude * rad2deg;


        if (GBrowserIsCompatible()) {

            // Init GMap
            var map = new GMap2($("map-results"));
            map.setCenter(new GLatLng(lat, lon), 13);
            map.addControl(new GSmallZoomControl3D());
            map.addControl(new GMapTypeControl());
            map.addControl(new GOverviewMapControl());
	    map.addControl(new GScaleControl(256));
            //  Create icons
            var baseIcon = new GIcon(G_DEFAULT_ICON);
            baseIcon.shadow = "http://www.google.com/mapfiles/shadow50.png";
            baseIcon.iconSize = new GSize(20, 34);
            baseIcon.shadowSize = new GSize(37, 34);
            baseIcon.iconAnchor = new GPoint(9, 34);
            baseIcon.infoWindowAnchor = new GPoint(9, 2);

            // Create markers
            function createMarker(point, contentId) {

                var infoWindowContainer = $(contentId);
                var panoramaWindowContainer = $(contentId + "s");

                var marker = new GMarker(point);
                var streetViewClient = new GStreetviewClient();

                streetViewClient.getNearestPanoramaLatLng(point, function(response) {
                    if (response != null) {

                        var infoWindowOptions = { maxContent: panoramaWindowContainer, maxTitle: "Street View" };
                        marker.bindInfoWindow(infoWindowContainer, infoWindowOptions);
                        infoWindowContainer.down(".streetViewBTN").style.visibility = "visible";

                    } else {
                        marker.bindInfoWindow(infoWindowContainer);
                    }

                });

                var panoramaOptions = { latlng: point };
                var panorama = new GStreetviewPanorama(panoramaWindowContainer, panoramaOptions);

                panoramaWindowContainer.style.width = '658px';
                panoramaWindowContainer.style.height = '450px';

                var iw = map.getInfoWindow();

                infoWindowContainer.down(".streetViewBTN").observe("click", function() {
                    iw.maximize();
                });

                GEvent.addListener(marker, "infowindowbeforeclose", function() {
                    panorama.remove();
                });

                return marker;
            }

            // Place a marker on the map for each property
            gSpots.each(function(gSpot) 
            {
                try {
                    map.addOverlay(createMarker(new GLatLng(gSpot.Latitude(), gSpot.Longitude()), gSpot.ContentId()));
                } catch(e) {
                }
            });

            if (showRadius == true) {
                  var bounds = new GLatLngBounds();
                  //Set Up Circle
                  var centre = map.getCenter();
                  //Multiple by 1.609344 for miles. (1.609344 in a km)
                  var givenRad = mapRadius*1.609344;
                  var givenQuality = 40;
                  drawCircle(map, centre, givenRad, givenQuality, bounds, map);
                  fit(map, bounds);
            }
        }
    }
}


function fit(map, bounds){
    map.panTo(bounds.getCenter());
    map.setZoom(map.getBoundsZoomLevel(bounds)+1);
}

function drawCircle(map, center, radius, nodes, bounds, map, liColor, liWidth, liOpa, fillColor, fillOpa)
{
    // Esa 2006
    //calculating km/degree
    var latConv = center.distanceFrom(new GLatLng(center.lat()+0.1, center.lng()))/100;
    var lngConv = center.distanceFrom(new GLatLng(center.lat(), center.lng()+0.1))/100;

    //Loop
    var points = [];
    var step = parseInt(360/nodes)||10;
    for(var i=0; i<=360; i+=step)
    {
    var pint = new GLatLng(center.lat() + (radius/latConv * Math.cos(i * Math.PI/180)), center.lng() +
    (radius/lngConv * Math.sin(i * Math.PI/180)));
    points.push(pint);
    bounds.extend(pint); //this is for fit function
    }
    fillColor = fillColor||liColor||"#0055ff";
    liWidth = liWidth||2;
    var poly = new GPolygon(points,liColor,liWidth,liOpa,fillColor,fillOpa);
    map.addOverlay(poly);
}


function ShowElementIfStreetviewAvailable(latitude, longitude, element) {
    
    var streetViewClient = new GStreetviewClient();
    var point = new GLatLng(latitude, longitude);

    streetViewClient.getNearestPanoramaLatLng(point, function(response) {
        if (response && element) {
            element.style.display = "block";
        }
    });
}


		

function NEtoLL(east, north) 
{
  // converts NGR easting and nothing to lat, lon.
  // input metres, output radians
  var nX = Number(north);
  var eX = Number(east);
  a = 6377563.396;       // OSGB semi-major
  b = 6356256.91;        // OSGB semi-minor
  e0 = 400000;           // OSGB easting of false origin
  n0 = -100000;          // OSGB northing of false origin
  f0 = 0.9996012717;     // OSGB scale factor on central meridian
  e2 = 0.0066705397616;  // OSGB eccentricity squared
  lam0 = -0.034906585039886591;  // OSGB false east
  phi0 = 0.85521133347722145;    // OSGB false north
  var af0 = a * f0;
  var bf0 = b * f0;
  var n = (af0 - bf0) / (af0 + bf0);
  var Et = east - e0;
  var phid = InitialLat(north, n0, af0, phi0, n, bf0);
  var nu = af0 / (Math.sqrt(1 - (e2 * (Math.sin(phid) * Math.sin(phid)))));
  var rho = (nu * (1 - e2)) / (1 - (e2 * (Math.sin(phid)) * (Math.sin(phid))));
  var eta2 = (nu / rho) - 1;
  var tlat2 = Math.tan(phid) * Math.tan(phid);
  var tlat4 = Math.pow(Math.tan(phid), 4);
  var tlat6 = Math.pow(Math.tan(phid), 6);
  var clatm1 = Math.pow(Math.cos(phid), -1);
  var VII = Math.tan(phid) / (2 * rho * nu);
  var VIII = (Math.tan(phid) / (24 * rho * (nu * nu * nu))) * (5 + (3 * tlat2) + eta2 - (9 * eta2 * tlat2));
  var IX = ((Math.tan(phid)) / (720 * rho * Math.pow(nu, 5))) * (61 + (90 * tlat2) + (45 * Math.pow(Math.tan(phid), 4) ));
  var phip = (phid - ((Et * Et) * VII) + (Math.pow(Et, 4) * VIII) - (Math.pow(Et, 6) * IX)); 
  var X = Math.pow(Math.cos(phid), -1) / nu;
  var XI = (clatm1 / (6 * (nu * nu * nu))) * ((nu / rho) + (2 * (tlat2)));
  var XII = (clatm1 / (120 * Math.pow(nu, 5))) * (5 + (28 * tlat2) + (24 * tlat4));
  var XIIA = clatm1 / (5040 * Math.pow(nu, 7)) * (61 + (662 * tlat2) + (1320 * tlat4) + (720 * tlat6));
  var lambdap = (lam0 + (Et * X) - ((Et * Et * Et) * XI) + (Math.pow(Et, 5) * XII) - (Math.pow(Et, 7) * XIIA));
  var geo = { latitude: phip, longitude: lambdap };
  return(geo);
} 

function Marc(bf0, n, phi0, phi)
{
  var Marc = bf0 * (((1 + n + ((5 / 4) * (n * n)) + ((5 / 4) * (n * n * n))) * (phi - phi0))
    - (((3 * n) + (3 * (n * n)) + ((21 / 8) * (n * n * n))) * (Math.sin(phi - phi0)) * (Math.cos(phi + phi0)))
    + ((((15 / 8) * (n * n)) + ((15 / 8) * (n * n * n))) * (Math.sin(2 * (phi - phi0))) * (Math.cos(2 * (phi + phi0))))
    - (((35 / 24) * (n * n * n)) * (Math.sin(3 * (phi - phi0))) * (Math.cos(3 * (phi + phi0)))));
  return(Marc);
}

function InitialLat(north, n0, af0, phi0, n, bf0)
{
  var phi1 = ((north - n0) / af0) + phi0;
  var M = Marc(bf0, n, phi0, phi1);
  var phi2 = ((north - n0 - M) / af0) + phi1;
  var ind = 0;
  while ((Math.abs(north - n0 - M) > 0.00001) && (ind < 20))  // max 20 iterations in case of error
  {  
	ind = ind + 1;
	phi2 = ((north - n0 - M) / af0) + phi1;
    M = Marc(bf0, n, phi0, phi2);
    phi1 = phi2;
  }
  return(phi2);  
}
