/**
 * @author Tomek
 */
  function ecc(major, minor)
  {
	return (major*major - minor*minor) / (major*major);
  }


   function LLtoNE2(lat, lon)
  {

    var deg2rad = Math.PI / 180;
    var rad2deg = 180.0 / Math.PI;
    var phi = lat * deg2rad;      // convert latitude to radians
    var lam = lon * deg2rad;   // convert longitude to radians
    a = 6377563.396;       // OSGB semi-major axis
    b = 6356256.91;        // OSGB semi-minor axis
    e0 = 400000;           // easting of false origin
    n0 = -100000;          // 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
    
	
	
	
    a = 6377340.189;       // OSGBI semi-major
    b = 6356034.447;        // OSGBI semi-minor
    e0 = 200000;           // easting of false origin
    n0 = 250000;          // northing of false origin
    f0 = 1.000035;     // OSGBI scale factor on central meridian
    e2 = 0.00667054015;  // OSGBI eccentricity squared
    lam0 = -0.13962634015954636615389526147909;  // OSGBI false east
    phi0 = 0.93375114981696632365417456114141;    // OSGBI false north	
	
	

	
    var af0 = a * f0;
    var bf0 = b * f0;
    // easting
    var slat2 = Math.sin(phi) * Math.sin(phi);
    var nu = af0 / (Math.sqrt(1 - (e2 * (slat2))));
    var rho = (nu * (1 - e2)) / (1 - (e2 * slat2));
    var eta2 = (nu / rho) - 1;
    var p = lam - lam0;
    var IV = nu * Math.cos(phi);
    var clat3 = Math.pow(Math.cos(phi),3);
    var tlat2 = Math.tan(phi) * Math.tan(phi);
    var V = (nu / 6) * clat3 * ((nu / rho) - tlat2);
    var clat5 = Math.pow(Math.cos(phi), 5);
    var tlat4 = Math.pow(Math.tan(phi), 4);
    var VI = (nu / 120) * clat5 * ((5 - (18 * tlat2)) + tlat4 + (14 * eta2) - (58 * tlat2 * eta2));
    east = e0 + (p * IV) + (Math.pow(p, 3) * V) + (Math.pow(p, 5) * VI);
    // northing
    var n = (af0 - bf0) / (af0 + bf0);
    var M = Marc(bf0, n, phi0, phi);
    var I = M + (n0);
    var II = (nu / 2) * Math.sin(phi) * Math.cos(phi);
    var III = ((nu / 24) * Math.sin(phi) * Math.pow(Math.cos(phi), 3)) * (5 - Math.pow(Math.tan(phi), 2) + (9 * eta2));
    var IIIA = ((nu / 720) * Math.sin(phi) * clat5) * (61 - (58 * tlat2) + tlat4);
    north = I + ((p * p) * II) + (Math.pow(p, 4) * III) + (Math.pow(p, 6) * IIIA);
    east = Math.round(east);       // round to whole number
    north = Math.round(north);     // round to whole number


//    nstr = String(north);      // convert to string
 //   estr = String(east);       // ditto
    nstr = north+'';      // convert to string

    estr = east+'';       // ditto


//			  alert(estr+"|"+nstr);
    
    message1=estr + '$' + nstr;

	return message1;
  }





   function LLtoNE(lat, lon)
  {
    var deg2rad = Math.PI / 180;
    var rad2deg = 180.0 / Math.PI;
    var phi = lat * deg2rad;      // convert latitude to radians
    var lam = lon * deg2rad;   // convert longitude to radians
    a = 6377563.396;       // OSGB semi-major axis
    b = 6356256.91;        // OSGB semi-minor axis
    e0 = 400000;           // easting of false origin
    n0 = -100000;          // 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
    
	
	
	
    a = 6377340.189;       // OSGBI semi-major
    b = 6356034.447;        // OSGBI semi-minor
    e0 = 200000;           // easting of false origin
    n0 = 250000;          // northing of false origin
    f0 = 1.000035;     // OSGBI scale factor on central meridian
    e2 = 0.00667054015;  // OSGBI eccentricity squared
    lam0 = -0.13962634015954636615389526147909;  // OSGBI false east
    phi0 = 0.93375114981696632365417456114141;    // OSGBI false north	
	
	
	
	
    var af0 = a * f0;
    var bf0 = b * f0;
    // easting
    var slat2 = Math.sin(phi) * Math.sin(phi);
    var nu = af0 / (Math.sqrt(1 - (e2 * (slat2))));
    var rho = (nu * (1 - e2)) / (1 - (e2 * slat2));
    var eta2 = (nu / rho) - 1;
    var p = lam - lam0;
    var IV = nu * Math.cos(phi);
    var clat3 = Math.pow(Math.cos(phi),3);
    var tlat2 = Math.tan(phi) * Math.tan(phi);
    var V = (nu / 6) * clat3 * ((nu / rho) - tlat2);
    var clat5 = Math.pow(Math.cos(phi), 5);
    var tlat4 = Math.pow(Math.tan(phi), 4);
    var VI = (nu / 120) * clat5 * ((5 - (18 * tlat2)) + tlat4 + (14 * eta2) - (58 * tlat2 * eta2));
    east = e0 + (p * IV) + (Math.pow(p, 3) * V) + (Math.pow(p, 5) * VI);
    // northing
    var n = (af0 - bf0) / (af0 + bf0);
    var M = Marc(bf0, n, phi0, phi);
    var I = M + (n0);
    var II = (nu / 2) * Math.sin(phi) * Math.cos(phi);
    var III = ((nu / 24) * Math.sin(phi) * Math.pow(Math.cos(phi), 3)) * (5 - Math.pow(Math.tan(phi), 2) + (9 * eta2));
    var IIIA = ((nu / 720) * Math.sin(phi) * clat5) * (61 - (58 * tlat2) + tlat4);
    north = I + ((p * p) * II) + (Math.pow(p, 4) * III) + (Math.pow(p, 6) * IIIA);
    east = Math.round(east);       // round to whole number
    north = Math.round(north);     // round to whole number
    nstr = String(north);      // convert to string
    estr = String(east);       // ditto
    document.out.n.value=nstr;
	document.out.e.value=estr; 
	document.out.ngr.value=NE2NGR(estr, nstr);
  }

  function Marc(bf0, n, phi0, phi)
  {
    var Marc1 = 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(Marc1);
  }
  
  
  function NE2NGR(east, north)
  {
    var eX = east / 500000;
    var nX = north / 500000;
    var tmp = Math.floor(eX)-5.0 * Math.floor(nX)+17.0;
    nX = 5 * (nX - Math.floor(nX));
    eX = 20 - 5.0 * Math.floor(nX) + Math.floor(5.0 * (eX - Math.floor(eX)));
    if (eX > 7.5){
      eX = eX + 1};
    if (tmp > 7.5){
      tmp = tmp + 1};
    var eing = String(east);
    var ning = String(north);
    var lnth = eing.length;
    eing = eing.substring((lnth - 5), lnth);
    lnth = ning.length;
    ning = ning.substring((lnth - 5), lnth);
    ngr = String.fromCharCode(tmp + 65) + String.fromCharCode(eX + 65) + " " + eing + " " + ning;
	ngr = String.fromCharCode(eX + 65) + " " + eing + " " + ning;	
    return ngr;
  }
  
function conv_gps_igs(lat,lon)  
  {
  aaa=LLtoNE2(lat, lon);
  
  return aaa;  	
  }

function conv_igs_gps(east,north)  
  {
  	var pi=Math.PI;
  rad2deg=180/pi;	
  geo = NEtoLL(east, north);
  lat = geo.latitude * rad2deg;
  lon = geo.longitude * rad2deg;  
  aa=lat+','+lon
  return aa;  	
  }


  
  function f1(lat,lon)
  	{
	LLtoNE(lat, lon);
	};
  function f2(n,e)
  	{
  NE2NGR(e, n);
	};	
  
  
  
  
  
  
  
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 = 6377340.189;       // OSGBI semi-major
    b = 6356034.447;        // OSGBI semi-minor
    e0 = 200000;           // easting of false origin
    n0 = 250000;          // northing of false origin
    f0 = 1.000035;     // OSGBI scale factor on central meridian
    e2 = 0.00667054015;  // OSGBI eccentricity squared
    lam0 = -0.13962634015954636615389526147909;  // OSGBI false east
    phi0 = 0.93375114981696632365417456114141;    // OSGBI false north	





//  a = 6377563.396;       // OSI semi-major
//  b = 6356256.91;        // OSI semi-minor
//  e0 = 400000;           // easting of false origin
//  n0 = -100000;          // northing of false origin
//  f0 = 0.9996012717;     // OSI scale factor on central meridian
//  e2 = 0.0066705397616;  // OSI eccentricity squared
//  lam0 = -0.034906585039886591;  // OSI false east
//  phi0 = 0.85521133347722145;    // OSI 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 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);  
}





function conv_ngr_to_ings(ngr)
{
	ngr="S"+ngr;
	ngr2=ngr.split(" ");
	ngr=ngr2[0]+ngr2[1]+ngr2[2];
	grid='';
//	grid = "Irish";
  var myRegExp = /^[A-Z][A-Z][0-9]/;
  if (myRegExp.test(ngr))
    grid = "British";
    
  myRegExp = /^ [A-Z][0-9]/;
  if (myRegExp.test(ngr))
	grid = "Irish";
	
  myRegExp = /^W[AV][0-9]/;
  if (myRegExp.test(ngr))
    grid = "Channel Islands";

  if (grid == "Channel Islands") 
  {
    var eci = "5" + ngr.substring(2,7);
    if (ngr.charAt(1) == "V")
      var nci = "54" + ngr.substring(7,12);
    else
      var nci = "55" + ngr.substring(7,12);
    east = Number(eci);
    north = Number(nci);
  }
  if ((grid == "British") || (grid == "Irish"))
  {
    north = Number(ngr.substring(7));
    east = Number(ngr.substring(2,7));

    var t1 = ngr.charCodeAt(0) - 65;
    if (t1 < 0)   // probably a space, so Irish
      t1 = 18;    // S assumed for Irish (83-65)
    if (t1 > 8)
      t1 = t1 -1;
    var t2 = Math.floor(t1 / 5);
    north = north + 500000 * (3 - t2);
    east = east + 500000 * (t1 - 5 * t2 - 2);

    t1 = ngr.charCodeAt(1) - 65;
    if (t1 > 8)
      t1 = t1 - 1;
    t2 = Math.floor(t1 / 5);
    north = north + 100000 * ( 4 - t2);
    east = east + 100000 * ( t1 - 5 * t2);
  }
  if (grid=="")
  	{
		alert("bad format NGR datas: "+ngr);
		return;
	};
								document.new_sighting.igs_e.value=east;
								document.new_sighting.igs_n.value=north;		

  	var pi=Math.PI;
  rad2deg=180/pi;	
  geo = NEtoLL(east, north);
//  alert(geo);
  lat = geo.latitude * rad2deg;
  lon = geo.longitude * rad2deg;  

								document.new_sighting.gps_lat.value=lat;
								document.new_sighting.gps_lon.value=lon;																
}





