// sjcUtility.js
// conversion routines, etc
// Copyright (C) 2005 San Joaquin County Community Development Geographic Information Systems, ALL RIGHTS RESERVED
// initial creation: 01/14/2004 David Bollinger
//



//==mouse-to-map==

function getMapXY(xIn,yIn) {
	mouse.x = xIn;
	var muppx = extent.width / iWidth;
	mapX = muppx * mouse.x + extent.minx;
	mouse.y = iHeight - yIn;
	var muppy = extent.height / iHeight;
	mapY = muppy * mouse.y + extent.miny;
}

function getImageXY(e) {
  if (!e) var e = window.event;
  if (e.pageX || e.pageY) {
		mouse.x = e.pageX;
		mouse.y = e.pageY;
	}
  else
  if (e.clientX || e.clientY) {
		mouse.x = e.clientX + document.body.scrollLeft;
		mouse.y = e.clientY + document.body.scrollTop;
	}
}

function getOVImageXY(e) {
  if (!e) var e = window.event;
  if (e.pageX || e.pageY) {
		mouse.x = e.pageX;
		mouse.y = e.pageY;
	}
  else
  if (e.clientX || e.clientY) {
		mouse.x = e.clientX + document.body.scrollLeft;
		mouse.y = e.clientY + document.body.scrollTop;
	}
}

//==num-to-str==

var bUserLocaleUsesComma = String(1/10).indexOf(',') >= 0;

// number to string
function n2s(n) {
	var s = new String(n);
	s = s.replace(/,/g, '.');
	return s;
}

// string to number
function s2n(s) {
	if (bUserLocaleUsesComma)
		s = s.replace(/./g, ',');
	var n = parseFloat(s);
	return n;
}


//== generate links to other mapping sites


function asklink() {
  // defunct -- ask has outsourced to ms/live/bing
  return binglink();
}

function binglink() {
  var link = 'http://maps.live.com/default.aspx?';
  // calc the center of the map
  var cx = (extent.minx+extent.maxx)/2.0;
  var cy = (extent.miny+extent.maxy)/2.0;
  var cc = sp2ll(cx,cy);
  // calc the span of the map
  var ul = sp2ll(extent.minx,extent.maxy);
  var br = sp2ll(extent.maxx,extent.miny);
  var spanx = br[2] - ul[2];
  var spany = ul[3] - br[3];
  link += 'cp='+cc[3]+'~'+cc[2];
  var sty = 'h';
  var lvl = 9;
  var spn = (spanx > spany) ? spanx : spany;
  if (spn < 1.6000) lvl=10;
  if (spn < 0.8000) lvl=11;
  if (spn < 0.4000) lvl=12;
  if (spn < 0.2000) lvl=13;
  if (spn < 0.1000) lvl=14;
  if (spn < 0.0500) lvl=15;
  if (spn < 0.0250) lvl=16;
  if (spn < 0.0125) lvl=17;
  if (spn < 0.00625) lvl=18;
  if (spn < 0.003125) lvl=19;
  if (spn < 0.0015625) { sty='b'; lvl=1; }
  link += '&style='+sty;
  link += '&dir=0';
  link += '&lvl='+lvl;
  return link;
}

function googlelink() {
  var link = 'http://maps.google.com/';
  // calc the center of the map
  var cx = (extent.minx+extent.maxx)/2.0;
  var cy = (extent.miny+extent.maxy)/2.0;
  var cc = sp2ll(cx,cy);
  // calc the span of the map
  var ul = sp2ll(extent.minx,extent.maxy);
  var br = sp2ll(extent.maxx,extent.miny);
  var spanx = br[2] - ul[2];
  var spany = ul[3] - br[3];
  link += '?cbll='+cc[3]+','+cc[2];
  link += '&ie=UTF8';
  link += '&layer=c';
  link += '&ll='+cc[3]+','+cc[2];
  link += '&t=h';
  var sv = false;
  if (spanx < 0.02) { spanx = 0.02; sv = true; }
  if (spany < 0.02) { spany = 0.02; sv = true; }
  link += '&spn='+(spanx/2)+','+(spany/2);
  return link;
}

function mapquestlink() {
  var link = 'http://www.mapquest.com/maps/map.adp';
  // calc the center of the map
  var cx = (extent.minx+extent.maxx)/2.0;
  var cy = (extent.miny+extent.maxy)/2.0;
  var cc = sp2ll(cx,cy);
  // calc the span of the map
  var ul = sp2ll(extent.minx,extent.maxy);
  var br = sp2ll(extent.maxx,extent.miny);
  var spanx = br[2] - ul[2];
  var spany = ul[3] - br[3];
  if (spanx < 0.001) spanx = 0.001;
  if (spany < 0.001) spany = 0.001;
  link += '?latlongtype=decimal';
  link += '&latitude='+cc[3];
  link += '&longitude='+cc[2];
  var lvl = 6;
  var spn = (spanx > spany) ? spanx : spany;
  if (spn < 1.0000) lvl=7;
  if (spn < 0.5000) lvl=8;
  if (spn < 0.2500) lvl=9;
  if (spn < 0.1250) lvl=10;
  if (spn < 0.0625) lvl=11;
  if (spn < 0.03125) lvl=12;
  if (spn < 0.015625) lvl=13;
  link += '&zoom='+lvl;
  return link;
}

function yahoolink() {
  var link = 'http://maps.yahoo.com/map';
  // calc the center of the map
  var cx = (extent.minx+extent.maxx)/2.0;
  var cy = (extent.miny+extent.maxy)/2.0;
  var cc = sp2ll(cx,cy);
  // calc the span of the map
  var ul = sp2ll(extent.minx,extent.maxy);
  var br = sp2ll(extent.maxx,extent.miny);
  var spanx = br[2] - ul[2];
  var spany = ul[3] - br[3];
  if (spanx < 0.001) spanx = 0.001;
  if (spany < 0.001) spany = 0.001;
  link += '?ard=1';
  link += '&mvt=h';
  link += '&lat='+cc[3];
  link += '&lon='+cc[2];
  var lvl = 11;
  var spn = (spanx > spany) ? spanx : spany;
  if (spn < 1.0000) lvl=12;
  if (spn < 0.5000) lvl=13;
  if (spn < 0.2500) lvl=14;
  if (spn < 0.1250) lvl=15;
  if (spn < 0.0625) lvl=16;
  if (spn < 0.03125) lvl=17;
  if (spn < 0.015625) lvl=18;
  //if (spn < 0.0078125) lvl=19;
  link += '&zoom='+lvl;
  return link;
}


function zillowlink() {
  var link = 'http://www.zillow.com/homes/#/homes/for_sale/map/';
  // calc the center of the map
  var cx = (extent.minx+extent.maxx)/2.0;
  var cy = (extent.miny+extent.maxy)/2.0;
  var cc = sp2ll(cx,cy);
  // calc the span of the map
  var ul = sp2ll(extent.minx,extent.maxy);
  var br = sp2ll(extent.maxx,extent.miny);
  var spanx = br[2] - ul[2];
  var spany = ul[3] - br[3];
  if (spanx < 0.001) spanx = 0.001;
  if (spany < 0.001) spany = 0.001;
  link += (cc[3]+spany/2) + ',' + (cc[2]+spanx/2) + ',' + (cc[3]-spany/2) + ',' + (cc[2]-spanx/2) + '_rect/';
  var lvl = 11;
  var spn = (spanx > spany) ? spanx : spany;
  if (spn < 1.0000) lvl=12;
  if (spn < 0.5000) lvl=13;
  if (spn < 0.2500) lvl=14;
  if (spn < 0.1250) lvl=15;
  if (spn < 0.0625) lvl=16;
  if (spn < 0.03125) lvl=17;
  if (spn < 0.015625) lvl=18;
  //if (spn < 0.0078125) lvl=19;
  link += 'lvl' + '_zm/';
  link += '1_rs';
  return link;
}


//==sp-to-ll==

// NAD83 SPCS CA 3 (numbers) to NAD83 Geo (array of string)
function sp2ll(x,y) {
	function dd2str(dd) {
		var d = parseInt(dd);
		var ms = Math.abs(dd - d);
		var m = parseInt(ms*60);
		var s = Math.round((ms*3600 - m*60) * 100.0) / 100.0;
		return (d + '° ' + m + '\' ' + s + '\"');
	}

	function epfn(e,p) {
		var esinp = e * Math.sin(p);
		return Math.pow( (1-esinp) / (1+esinp), e/2 );
	}

	with (Math) {
		var a = 20925604.474167; // 6378137m * (3937/1200) = us survey feet
		var e = 0.0818191910434954;
		var esq = e*e;
		var phi0 = 0.6370451769779303;
		var phi1 = 0.6469353760725648;
		var phi2 = 0.6707882091831538;
		var lambda0 = -2.1031217486531672;
		var x0 = 6561666.666666672; // 2000000m * (3937/1200)
		var y0 = 1640416.666666668; // 500000m * (3937/1200)

		var m1 = cos(phi1) / sqrt(1 - esq * pow(sin(phi1),2));  
		var m2 = cos(phi2) / sqrt(1 - esq * pow(sin(phi2),2));

		var pi4 = PI / 4.0;
		var t0 = tan(pi4 - (phi0 / 2)) / epfn(e,phi0);
		var t1 = tan(pi4 - (phi1 / 2)) / epfn(e,phi1);
		var t2 = tan(pi4 - (phi2 / 2)) / epfn(e,phi2);

		var n = log(m1 / m2) / log(t1 / t2);
		var f = m1 / (n * pow(t1, n)); 
		var rho0 = a * f * pow(t0, n);

		x -= x0;
		y -= y0;

		var rho = sqrt(pow(x,2) + pow((rho0 - y),2));
		var theta = atan(x / (rho0 - y));
		var t = pow((rho / (a * f)),(1 / n));
		var lambda = (theta / n) + lambda0;

		var epsilon = 0.000000002;
		var pi2 = PI / 2.0;
		var phix, phi = pi2 - (2 * atan(t));
		do {
			phix = phi;
			var esinp = e * sin(phi);
			phi = pi2 - 2 * atan(t * epfn(e,phi));
		} while ((abs(phi - phix)) > epsilon);

		var rad2deg = 180.0 / PI;
		return new Array( dd2str(lambda*rad2deg), dd2str(phi*rad2deg), lambda*rad2deg, phi*rad2deg );
	}
}

