// This shows a lat/lon graticule on the map. Interval is automatic
// based on Bill Chadwick code. thank you!

//British type=1
//Irish type=2
//Channel Islands type=3

function OGraticule(type) {
  if(type == null || type.length == 0)
   type = 1; //british default
   this.type = type;
}

OGraticule.prototype = new GOverlay();

OGraticule.prototype.initialize = function(map) {

  //save for later
  this.map_ = map;

  //array for lines
  this.lines_ = new Array();

  //array for labels
  this.divs_ = new Array();

}

OGraticule.prototype.remove = function() {

  try{
      var i = 0;
      for(i=0; i< this.lines_.length; i++)
              this.map_.removeOverlay(this.lines_[i]);

      var div = this.map_.getPane(G_MAP_MARKER_SHADOW_PANE);
      for(i=0; i< this.divs_.length; i++)
              div.removeChild(this.divs_[i]);

	}
  catch(e){
  }

}


OGraticule.prototype.copy = function() {
  return this;
}

// Redraw the graticule based on the current projection and zoom level
OGraticule.prototype.redraw = function(force) {
  try {
  //clear old
  this.remove();

  //best color for writing on the map
  this.color_ = this.map_.getCurrentMapType().getTextColor();

  //determine graticule interval
  var bnds = this.map_.getBounds();

  var l = bnds.getSouthWest().lng();
  var b = bnds.getSouthWest().lat();
  var t = bnds.getNorthEast().lat();
  var r = bnds.getNorthEast().lng();


  //sanity - limit to os grid area
  if(this.type == 1){
    if (t < 49.0)
    return;
    if(b > 61.0)
    return;
    if(r < -8.0)
    return;
    if(l > 2.0)
    return;
  }else if( this.type == 2){
    if (t < 51.2)
	return;
    if(b > 55.73)
          return;
    if(r < -12.2)
      return;
    if(l > -4.8)
      return;
  }

  //grid interval in km


  var gr = enclosingOsgbRect(l,b,t,r, this.type);

  var west = gr.bl.east / 1000.0;
  var south = gr.bl.north / 1000.0;
  var east = gr.tr.east / 1000.0;
  var north = gr.tr.north / 1000.0;

  var width = east-west;
  var height = north-south;

  var ww = Math.max(width,height);

  var d;//km initial/min interval
  ww /= 10;//want about 10 grid lines
  if(ww < 2.0)
	d = 1.0;
  else if(ww < 3.0)
    d = 2.0;
  else if(ww < 7.0)
    d = 5.0;
  else if(ww < 13.0)
    d = 10.0;
  else if(ww < 27.0)
    d = 20.0;
  else if(ww < 70.0)
    d = 50.0;
  else
    d = 100.0;

  d = Math.round(d);

  //round iteration limits to the computed grid interval
  east = Math.ceil(east/d)*d;
  west = Math.floor(west/d)*d;
  north = Math.ceil(north/d)*d;
  south = Math.floor(south/d)*d;

  //Sanity / limit
  if(this.type == 1){ //British
    if (west <= 0.0)
    west = 0.0;
    if(east >= 700.0)
    east = 700.0;
    if(south < 0.0)
    south = 0.0;
    if(north > 1300.0)
    north = 1300.0;

  }else if (this.type == 2){ //Irish
    if (west <= 0.0)
          west = 0.0;
    if(east >= 400.0)
          east = 400.0;
    if(south < 0.0)
      south = 0.0;
    if(north > 500.0)
      north = 500.0;
  }

  this.lines_ = new Array();
  this.divs_ = new Array();

  var i=0;//count inserted lines
  var j=0;//count labels

  //pane/layer to write on
  var mapDiv = this.map_.getPane(G_MAP_MARKER_SHADOW_PANE);


  //horizontal lines
  var s = south;
  while(s<=north){

         var pts = new Array();
         //under 10km grid squares draw as straight line top to bottom
         if(d < 10.0){
			pts[0] = this.GLatLngFromEN(east,s);
			pts[1] = this.GLatLngFromEN(west,s);
		 }
         //over 10km grid squares draw as set of segments
		 else{
			var e = west;
			var q = 0;
			while(e<=east){
				pts[q] = this.GLatLngFromEN(e,s);
			    q++;
				e += d;
			}
		 }


		 //line
		 this.lines_[i] = new GPolyline(pts,this.color_,1);
		 this.map_.addOverlay(this.lines_[i]);
		 i++;

                 if(s > 0){
		 //label at height of second horz line
		 try{
		 var p = this.map_.fromLatLngToDivPixel(this.GLatLngFromEN(west+d+d,s));

		 var dv = document.createElement("DIV");
		 //var x = p.x + 3;
		 var x = p.x +1;
		 dv.style.position = "absolute";
                 dv.style.left = x.toString() + "px";
                 dv.style.top = p.y.toString() + "px";
		 dv.style.color = this.color_;
		 dv.style.fontFamily='Arial';
		 dv.style.fontSize='x-small';
		 dv.style.cursor = "help";
		 dv.title = en2ngr((west+d+d+0.4)*1000.0,(s-d+0.4)*1000.0, this.type).substr(0,2) +
                     " (" + Math.floor(s+0.4).toString() + " km North)";
                 var km;
                 if(this.map_.getZoom()<7){
                   km = en2ngr((west+d+d+0.4)*1000.0,(s-d+0.4)*1000.0, this.type).substr(0,2);
                 }else{
                   km = (Math.round(s)%100).toString();
                 }
                 if (km.length < 2)
			km = "0" + km;
                 dv.innerHTML = km;
		 mapDiv.insertBefore(dv,null);
		 this.divs_[j] = dv;
		 j++;
		 }
		 catch(ex){
		 }

                 }
		 s += d;


  }


  //vertical lines
  var hlc = 0;
  var e = west;
  while(e<=east){

         var pts = new Array();

         //under 10km grid squares draw as straight line top to bottom
         if(d < 10.0){
		 pts[0] = this.GLatLngFromEN(e,north);
		 pts[1] = this.GLatLngFromEN(e,south);
		 }
         //over 10km grid squares draw as set of segments
		 else{
			var s = south;
			var q = 0;
			while(s<=north){
				pts[q] = this.GLatLngFromEN(e,s);
			    q++;
				s += d;
			}
		 }


		 //line
		 this.lines_[i] = new GPolyline(pts,this.color_,1);
		 this.map_.addOverlay(this.lines_[i]);
		 i++;

		 //label on second vert line
		 if(hlc != 2)
		 {
		      if(e < east){
                      try{
                      //var p = this.map_.fromLatLngToDivPixel(this.GLatLngFromEN(e,south+d+d));
                      var p = this.map_.fromLatLngToDivPixel(this.GLatLngFromEN(e,south+d));

                      var dv = document.createElement("DIV");
                      //var y = p.y + 3;
                      var y = p.y+1;
                      dv.style.position = "absolute";
                      dv.style.left = p.x.toString() + "px";
                      dv.style.top = y.toString() + "px";
                      dv.style.color = this.color_;
                      dv.style.fontFamily='Arial';
                      dv.style.fontSize='x-small';
                      dv.style.cursor = "help";
                      dv.title = en2ngr((e+0.4)*1000.0,(south+0.4)*1000.0, this.type).substr(0,2) +
                      " (" + Math.floor(e+0.4).toString() + " km East)";
                      var km;
                      if(this.map_.getZoom()<7){
                      km = en2ngr((e+0.4)*1000.0,(south+0.4)*1000.0, this.type).substr(0,2);
                      }else{
                      km = (Math.round(e)%100).toString();
                      }
                      if (km.length < 2)
                      km = "0" + km;
                      dv.innerHTML = km;
                      mapDiv.insertBefore(dv,null);
                      this.divs_[j] = dv;
                      j++;
                      }
                      catch(ex){
                      }
                      }

		 }
		 hlc++;

		 e += d;
     }
  } catch (e) {
  }

}

//from OS east, north in KM to WGS84 Lat/Lon in a GLatLng
OGraticule.prototype.GLatLngFromEN = function(eastKm,northKm) {
           var ogb = ne2ll(eastKm*1000.0,northKm*1000.0, this.type);
	   return new GLatLng(ogb.lat,ogb.lon);
}

