var key1= 'ABQIAAAA-SSwkDqbK8WrKVKPU7ObohRBfps-PCi3ETYFHtU7Yh69l75yMRST0RWE4r7lsAkfAgd1AmTU3QIO3g';
var guri= 'http://maps.google.com/maps/geo?output=json&callback=gCallback&key='+key1+'&q=';
var appid1 = '26WTvi3V34E2DgU20paS4sfmROlawrpYQ31JRFIbSaFUxiMAQlJjxFbjZYApxx5veR59'; var yuri0 = 'http://api.maps.yahoo.com/ajaxymap?appid=' + appid1;
var yuri= 'http://api.maps.yahoo.com/ajax/geocode?appid='+appid1+'&qt=3&qs=';
var quri='';
var query='';
var gFound = false;
var gCalled = false;
var yCalled = false;
var yFound=false;
var yText = '';
var timer=0;
var gScriptObj = null;
var yScriptObj = null;
var gTagOpen= false;
var yTagOpen=false;
var lats = new Array(10);
var lons = new Array(10);

document.write('<script type="text/javascript" src="'+yuri0+'"><\/'+'script>'+'\n');

function closeGoogleTag() {
if (gTagOpen) {
gTagOpen=false;
gScriptObj.removeScriptTag();
}
}

function closeYahooTag() {
if (yTagOpen) {
yTagOpen=false;
yScriptObj.removeScriptTag();
}
}

	function checkTimer() {
closeGoogleTag();
closeYahooTag();
if (!gCalled && !yCalled) {
alert('El servicio del geocoder no ha respondido. Aseg\u00FArese que est\u00E1 conectado al Internet, que escribi\u00F3 el nombre bien y intente de nuevo.');
return false;
}
if (yFound) {
displayYahooResults();
return false;
}
noResults();
}

function launchGeocode() {
query=trim(document.getElementById('search').value);
var l=query.length;
if (l==0) {
alert("You must enter a city, town or other place to search for");
f1.search.focus();
return false;
}
f1.destination.value= "";
quri=guri+escape(query);
	gScriptObj = new JSONscriptRequest( quri);
	gScriptObj.buildScriptTag();
	gScriptObj.addScriptTag();
gTagOpen=true;
try {
YGeoCode.getPoint=function(d){ yCallback(d) };
}
catch (err) {
var err0 = 0;
}
quri=yuri+escape(query);
	yScriptObj = new JSONscriptRequest( quri);
	yScriptObj.buildScriptTag();
	yScriptObj.addScriptTag();
yTagOpen=true;
gCalled = false;
gFound = false;
yCalled=false;
yFound = false;
timer=window.setTimeout("checkTimer()", 2800);
}

function gCallback(jData) {
gCalled = true;
if (!gTagOpen) {
return false;
}
var r=f1.results;
r.length=0;
if (jData.Status.code == 200) {
gFound = true;
clearTimeout(timer);
closeYahooTag();
var p=jData.Placemark;
var l=p.length;
for(i=0; i<l-1; i++) {
var match=0;
for(j=i+1;j<l; j++) {
if (p[j].address.indexOf('Lng') == -1 && p[i].address == p[j].address && (p[i].Point.coordinates[1]
!= p[j].Point.coordinates[1] || p[i].Point.coordinates[0] != p[j].Point.coordinates[0])) {
p[j].address = p[j].address + " " + (Math.round(p[j].Point.coordinates[1]*100)/100) + " " + (Math.round(p[j].Point.coordinates[0]*100)/100);
match = 1;
}
}
if (match) {
p[i].address = p[i].address + " " + (Math.round(p[i].Point.coordinates[1]*100)/100) + " " + (Math.round(p[i].Point.coordinates[0]*100)/100);
}
}
lats.length=0;
lons.length=0;
for (i=0; i<p.length; i++) {
appendOptionLast("results", p[i].address);
r[r.length-1].value=p[i].Point.coordinates[1] + "|" + p[i].Point.coordinates[0];
lats[i] = p[i].Point.coordinates[1];
lons[i] = p[i].Point.coordinates[0];
}
if (lats.length > 0) {
f1.startlat.value=lats[0];
f1.startlon.value=lons[0];
}
if (r.length == 1) {
document.getElementById("resultslabel").innerHTML = "1 resultado:";
} else {
document.getElementById("resultslabel").innerHTML = r.length + " resultados:";
}
toggle2Rows("resultsrow", "searchrow");
f1.results.focus();
} else {
// no google results
if (yCalled) {
if (yFound) {
displayYahooResults();
} else {
noResults();
}
}
}
closeGoogleTag();
}

function yCallback(jData) {
yCalled = true;
if (gFound || !yTagOpen) {
return false;
}
if (jData.GeoPoint.Lat != "0" || jData.GeoPoint.Lon != "0") {
yFound = true;
yText = jData.GeoAddress;
lats.length=0;
lons.length=0;
lats[0] = jData.GeoPoint.Lat;
lons[0] = jData.GeoPoint.Lon;
f1.startlat.value = lats[0];
f1.startlon.value = lons[0];
}
if (yFound) {
//if (gCalled) {
displayYahooResults();
//}
} else {
//if (gCalled) {
noResults();
//}
}
closeYahooTag();
}

function displayYahooResults() {
clearTimeout(timer);
var r=f1.results;
r.length=0;
toggle2Rows("resultsrow", "searchrow");
document.getElementById("resultslabel").innerHTML = "1 resultado:";
appendOptionLast("results", yText);
f1.results.focus();
}

function noResults() {
clearTimeout(timer);
var r=f1.results;
r.length=0;
toggle2Rows("resultsrow", "searchrow");
document.getElementById("resultslabel").innerHTML = "0 resultados:";
f1.results.focus();
}

function clearGeocode() {
f1.search.value = "";
f1.results.length=0;
document.getElementById("resultslabel").innerHTML = "search results:"; 
f1.startlat.value = "";
f1.startlon.value = "";
toggle2Rows("searchrow", "resultsrow");
f1.destination.value= "";
f1.search.focus()
}

function toggle2Rows(div1, div2) {
document.getElementById(div1).style.display = "block";
document.getElementById(div2).style.display = "none";
}

// JSONscriptRequest -- a simple class for accessing Yahoo! Web Services
// using dynamically generated script tags and JSON
// Author: Jason Levitt
// Date: December 7th, 2005
function JSONscriptRequest(fullUrl) {
    this.fullUrl = fullUrl; 
    this.noCacheIE = '&noCacheIE=' + (new Date()).getTime();
    this.headLoc = document.getElementsByTagName("head").item(0);
    this.scriptId = 'YJscriptId' + JSONscriptRequest.scriptCounter++;
}
JSONscriptRequest.scriptCounter = 1;

JSONscriptRequest.prototype.buildScriptTag = function () {
    this.scriptObj = document.createElement("script");
    this.scriptObj.setAttribute("type", "text/javascript");
    this.scriptObj.setAttribute("src", this.fullUrl + this.noCacheIE);
    this.scriptObj.setAttribute("id", this.scriptId);
}
 
JSONscriptRequest.prototype.removeScriptTag = function () {
    this.headLoc.removeChild(this.scriptObj);  
}

JSONscriptRequest.prototype.addScriptTag = function () {
    this.headLoc.appendChild(this.scriptObj);
}



var f1;
var customIndex=0;
var sigDigits=8;
var mapwin = null;
var gStartlat=0;
var gStartlon=0;
var point = new Object();
point.lat = 0;
point.lon = 0;
point.finalBrg=0;
point.backBrg=0;
var smajor= new Array(6372797.6, 6378137, 6377340.189, 6378160, 6377397.155, 6378206.4, 6378249.145, 6377276.345, 6378137, 6378388, 6378245, 6378160, 6378135, 0);
var flat= new Array(0, 298.257223563, 299.3249646, 298.25, 299.1528128, 294.9786982138, 293.465, 300.8017, 298.257222101, 297, 298.3, 298.25, 298.26, 0);

document.write('<form NAME="frm" id="frm" method="post" action="viewmap.php" style="width: 100%"><table cellpadding="3"><tr><td id="searchrow" align="left" style="width: 100%"><label for="search" accesskey="S">B&#250;squeda de lugar:</label><input type="text" id="search" value="" size="30" maxlength="52" onfocus="this.select">&nbsp;&nbsp;<input type="button" class="btn" value="Buscar" onClick="launchGeocode()"></td><td id="resultsrow" align="left" style="width: 100%; display: none"><label id="resultslabel" for="results" accesskey="U" style="background-color: #7FFFD4; border: 1px black solid">0 resultados:</label><select id="results" style="width: 14.1em" onchange="writeLatLon()"><option></option></select>&nbsp;&nbsp;<input type="button" class="btn" value="Nueva b&#250;squeda" onclick="clearGeocode()"></td></tr></table><table cellpadding="3"><tr id="startlatrow"><td align="left" colspan="2"><label for="startlat" accesskey="L">Punto de comenzar:</label><br><label for="startlat" accesskey="L">Latitud:</label><input type="text" id="startlat" value="" size="14" maxlength="14" onfocus="this.select()">&nbsp;&nbsp;<label for="startlon" accesskey="N">Longitud:</label><input type="text" id="startlon" value="" size="14" maxlength="14" onfocus="this.select()"></td></tr><tr id="maxdistrow"><td align="left" colspan="2"><label for="bearing" accesskey="B">Direcci&#243;n (0-360):</label><input type="text" id="bearing" value="" size="14" maxlength="14" onfocus="this.select()">&nbsp;&nbsp;&nbsp;<label for="maxdist" accesskey="I">Distancia:</label><input type="text" id="dist" value="" size="14" maxlength="14" onfocus="this.select()">&nbsp;<input type="radio" name="distunits" checked>millas&nbsp;<input type="radio" name="distunits">km</td></tr><tr id="ellipserow" style="display: none"><td align="left" colspan="2"><label for="major">Elipsoide (en metros):</label><br><label for="major">Radio ecuatorial:</label><input type="text" id="major" value="" size="14" maxlength="14" onfocus="this.select()">&nbsp;&nbsp;&nbsp;<select id="param2"><option selected>&nbsp;Radio polar:<option>Achatamiento invertido:</select><input type="text" id="minor" value="" size="14" maxlength="14" onfocus="this.select()"></td></tr><tr><td align="left" colspan="2">&nbsp;&nbsp;<input type="button" class="btn" value="Calcular" accesskey="C" onclick="calculate()">&nbsp;&nbsp;<input type="button" class="btn" value="Borrar" accesskey="0" onclick="resetValues()">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<label for="model" accesskey="M">Modelo de tierra:</label><select id="model" onchange="setEllipse()"><option>Esfera<option selected>Elipsoide WGS84<option>Elipsoide Airy modified<option>Elipsoide Australian<option>Elipsoide Bessel (1841)<option>Elipsoide Clarke (1866)/NAD27<option>Elipsoide Clarke (1880)<option>Elipsoide Everest (1830)<option>Elipsoide GRS80<option>Elipsoide International/Hayford<option>Elipsoide Krasovsky<option>Elipsoide South American (1969<option>Elipsoide WGS72<option>Elipsoide definado</select></td></tr><tr><td align="left"><label for="destination" id="destinationlabel" accesskey="P">Punto de destino:</label><br><textarea class="results" id="destination" cols="56" rows="4" readonly="readonly" onfocus="this.select()" onclick="this.select()"></textarea></td><td align="left" valign="top"><br>&nbsp;<input type="button" class="btn" value="Ver en mapa" Id="map" onClick="viewMap()"><br>&nbsp;<i style="font-size:88%">por Google Maps</i></td></tr></table></form>');

function writeLatLon() {
var i = f1.results.selectedIndex;
f1.startlat.value = lats[i];
f1.startlon.value = lons[i];
}

function setEllipse() {
var i=f1.model.selectedIndex;
if (i==customIndex) {
f1.major.value="";
f1.minor.value="";
f1.destination.value="";
document.getElementById("ellipserow").style.display = "block";
return;
} else {
document.getElementById("ellipserow").style.display = "none";
if (f1.destination.value != "") {
calculate();
}
}
}

function appendOptionLast(combo, item) {
	var elOptNew = document.createElement('option');
	elOptNew.text = item;
	elOptNew.value = item;
	var elSel = document.getElementById(combo);
	try {
		elSel.add(elOptNew, null);
	}
	catch(ex) {
		elSel.add(elOptNew);
	}
}

function initializeLoad() {
f1=document.frm;
customIndex=f1.model.length-1;
f1.results.value = "";
}

function resetValues() {
f1.startlat.value="";
f1.startlon.value="";
f1.bearing.value = "";
f1.dist.value="";
f1.search.value = "";
f1.results.length = 0;
f1.destination.value= "";
f1.major.value="";
f1.minor.value="";
document.getElementById("searchrow").style.display = "block";
document.getElementById("resultsrow").style.display = "none";
}

function rad(dg) {
	return (dg* Math.PI / 180);
}

function deg(rd) {
	return (rd* 180 / Math.PI);
}

function trim(s) {
while(s.charCodeAt(0)<33 || s.charCodeAt(0)==160)
s=s.substring(1,s.length);
while(s.charCodeAt(s.length-1)<33 || s.charCodeAt(s.length-1)==160)
s=s.substring(0,s.length-1);
return s;
}

function normalizeLongitude(lon) {
var n=Math.PI;
if (lon > n) {
lon = lon - 2*n
} else if (lon < -n) {
lon = lon + 2*n
}
return lon;
}

function normalizeBearing(brg) {
var n=2*Math.PI;
if (brg < 0) {
brg = brg + n
} else if (brg >= n) {
brg = brg - n
}
return brg;
}

function isValidFP(n, name, allowNull) {
	if (n == "" && !allowNull) {
alert("La " + name + " es requerida");
return false;
}
if (parseFloat(n, 10) != n) {
alert("La " + name + " es inv\u00E1lida");
return false;
}
return true;
}

function checkMinMax(n, mn, mx, name, units) {
if (n<mn || n>mx) {
alert("La " + name + " debe ser entre " + mn + " y " + mx + " " + units);
return false
}
return true;
}

function calculate() {
var mx, units, radiusEarth, smaj;
var brg = new Array(0, 180, 0);
with (Math) {
var startlat=latLonToDecimal(f1.startlat.value, -90, 90, "latitud");
if (startlat == -999) {
f1.startlat.focus();
return;
}
gStartlat=startlat;
var j=0;
if (startlat == 90) {
startlat = 89.999999999;
j=1
}
if (startlat == -90) {
startlat = -89.999999999;
j=2;
}
startlat=rad(startlat);
var startlon=latLonToDecimal(f1.startlon.value, -180, 180, "longitud");
if (startlon == -999) {
f1.startlon.focus();
return;
}
gStartlon=startlon;
startlon=rad(startlon);
brg[0] = latLonToDecimal(f1.bearing.value, 0, 360, "direcci\u00F3n");
if (brg[0] == -999) {
f1.bearing.focus();
return;
}
brg[j] = rad(brg[j]);
var dist=f1.dist.value;
if (!isValidFP(dist, "distancia", false)) {
		f1.dist.focus();
return false;
}
if (f1.distunits[1].checked) {
mx=41000;
radiusEarth=6372.7976;
units="km";
} else {
mx=25000;
radiusEarth=3959.8728;
units="millas";
}
var i=f1.model.selectedIndex;
if (i<customIndex) {
// models 0 to 12
smaj=smajor[i]*1;
if (!checkMinMax(dist, 0, mx, "distancia", units)) {
		f1.dist.focus();
return false;
	}
var sminor=getSemiMinor(smaj, flat[i]);
} else {
// user defined ellipse
smajor[i]= trim(f1.major.value);
smaj= f1.major.value*1;
if (!isValidFP(smaj, "radio ecuatorial", false) || !checkMinMax(smaj, 1, 1000000000, "radio ecuatorial", "metros")) {
f1.major.focus();
return false;
}
var sminor= trim(f1.minor.value)*1;
if (f1.param2.selectedIndex == 1) {
if (!isValidFP(sminor, "Achatamiento invertido", false)) {
f1.minor.focus();
return false;
} 
flat[i]=sminor;
sminor=getSemiMinor(smaj, flat[i]);
if (flat[i]<2) {
alert("El achatamiento invertido debe ser mayor que 2");
f1.minor.focus();
return false;
}
} else {
if (!isValidFP(sminor, "radio polar", false)) {
f1.minor.focus();
return false;
} 
flat[i]=smaj/(smaj-sminor);
if (sminor < smaj/2) {
alert("El radio polar no debe ser menos que la mitad del radio ecuatorial");
f1.minor.focus();
return false;
}
if (sminor >= smaj) {
alert("El radio polar debe ser menor que el radio ecuatorial");
f1.minor.focus();
return false;
}
}
var c= smaj*PI/500;
if (f1.distunits[0].checked) {
c=c/1.609344;
}
var l=floor(log(c)/log(10)) - 1;
mx=ceil(c/pow(10, l))*pow(10, l);
if (!checkMinMax(dist, 0, mx, "distancia", units)) {
f1.dist.focus();
return false;
}
}

if (i != 0) {
destEllipse(startlat, startlon, brg[j], dist, smaj, sminor)
} else {
destSphere(startlat, startlon, brg[j], dist/radiusEarth);
}
if  (isNaN(point.finalBrg) || isNaN(point.lat) || isNaN(point.lon)) {
alert("La calculadora no pudo encontrar el punto de destino");
return false;
}

point.lat = padZeroRight(deg(point.lat));
point.lon = padZeroRight(deg(normalizeLongitude(point.lon)));
point.finalBrg = deg(normalizeBearing(point.finalBrg));
point.backBrg=deg(normalizeBearing(point.backBrg));
f1.destination.value = "Latitud: " + decimalToDMS(point.lat, 1) + "   "+point.lat + "\n";
f1.destination.value += "Longitud: " + decimalToDMS(point.lon, 0) + "   " + point.lon + "\n";
f1.destination.value += "Direcci\u00F3n final: " + decimalToDMS(point.finalBrg, 2) + "   " + padZeroRight(point.finalBrg) + "\n";
f1.destination.value += "Direcci\u00F3n regreso: " + decimalToDMS(point.backBrg, 2) + "   " + padZeroRight(point.backBrg);

}
}

function getSemiMinor(smajor, flat) {
return smajor-(smajor/flat);
}

function latLonToDecimal(ll, mn, mx, f) {
	var fail;
ll = trim(ll);
var 	msg= "inv\u00E1lida";
if (ll == "") {
msg= "requerida";
fail=true;
}
	if (parseFloat(ll, 10) != ll) {
var ch=ll.substring(ll.length-1);
ch=ch.toLowerCase();
if (f != "bearing") {
if (!/^\d{1,3}(\W{1,2}\d{1,2}){0,2}\W{0,2}(e|n|s|w)$/i.test(ll) || f=="latitude" && ch!="n"&&ch!="s" || f=="longitude"&&ch!="e"&&ch!="w") {
fail = true;
}
} else {
if (!/^\d{1,3}(\W{1,2}\d{1,2}){0,2}\W{0,3}$/i.test(ll)) {
fail = true;
}
}
if (!fail) {
var dms = ll.split(/\D/gi);
ll = dms[0];
for (i=1; i<dms.length; i++) {
if (dms[i] > 59) {
fail = true;
}
ll=ll*1+dms[i]/Math.pow(60, i);
}
if (ch == "s" || ch == "w") {
ll=-ll;
}
}
}
if (!fail) {
if (ll<mn || ll>mx) {
msg="inv\u00E1lida. Debe ser un n\u00FAmero entre " + mn + " y " + mx + ".";
fail=true;
}
}
	if (fail) {
			alert ('La ' + f + ' es ' + msg);
		return -999;
		} else {
return ll;
	}
}

function padWithZero(s) {
	if (s<10) {
		s= "0" + s;
	}
	return s;
}

function padZeroRight(s) {
if (sigDigits>8) {
sigDigits=8;
} else if (sigDigits < 5) {
sigDigits=5;
}
	s="" + Math.round(s*Math.pow(10, sigDigits))/Math.pow(10, sigDigits);
	var i = s.indexOf('.');
var d=(s.length-i-1);
	if (i == -1) {
		return (s + ".00");
		} else if (d == 1) {
		return (s + "0");
	} else {
return s;
}
}

function decimalToDMS(l, type) {
// type lat=0 lon=1 brg=2
	var dir1="";
if (type==1) {
	if (l<0) {
		dir1= "S";
		} else {
		dir1 = "N";
	}
} else if (type==0) {
	if (l<0) {
		dir1= "W";
		} else {
		dir1= "E";
	}
}
	l=Math.abs(Math.round(l*3600)/3600);
	var deg1= Math.floor(l);
	var temp=(l-deg1)*60;
	var min1=padWithZero(Math.floor(temp));
	temp=(temp-min1);
	var sec1=padWithZero(Math.round(temp*60));
if (sec1 == 60) {
sec1 = 59;
}
return Math.abs(deg1) + '\u00B0' + min1 + '\u2032' + sec1 + '\u2033' + dir1;
}

function viewMap() {
	if (f1.destination.value != "") {
var url = "viewmap.html?" + point.lat + "&" + point.lon + "&" + gStartlat + "&" + gStartlon;
f1.target = "mapwin";
if (screen.height <= 600) {
mapwin=window.open(url,"mapwin","menubar=1,toolbar=0,directories=0,location=0,status=1,resizable=1,scrollbars=1");
} else {
mapwin=window.open(url,"mapwin","menubar=1,toolbar=1,directories=1,location=1,status=1,resizable=1,scrollbars=1");
}
		} else {
alert ('Hay que calcular el punto de destino antes de ver el mapa');
	}
}

	function destEllipse(lat1, lon1, brg, s, a, b) {
with (Math) {
if (f1.distunits[1].checked) {
s *= 1000;
} else {
s *= 1609.344;
}
 var ind = max(f1.model.selectedIndex, 1);
var cs1, ds1, ss1, cs1m;
var f = 1/flat[ind];  
//alert('f='+f);
//alert('b='+b);
var sb=sin(brg);
var cb=cos(brg);
var tu1=(1-f)*tan(lat1);
var cu1=1/sqrt((1+tu1*tu1));
var su1=tu1*cu1;
var s2=atan2(tu1, cb);
var sa = cu1*sb;
var csa=1-sa*sa;
var us=csa*(a*a - b*b)/(b*b);
var A=1+us/16384*(4096+us*(-768+us*(320-175*us)));
var B = us/1024*(256+us*(-128+us*(74-47*us)));
var s1=s/(b*A);
var s1p = 2*PI;
while (abs(s1-s1p) > 1e-12) {
 cs1m=cos(2*s2+s1);
 ss1=sin(s1);
 cs1=cos(s1);
 ds1=B*ss1*(cs1m+B/4*(cs1*(-1+2*cs1m*cs1m)- B/6*cs1m*(-3+4*ss1*ss1)*(-3+4*cs1m*cs1m)));
 s1p=s1;
 s1=s/(b*A)+ds1;
}
var t=su1*ss1-cu1*cs1*cb;
var lat2=atan2(su1*cs1+cu1*ss1*cb, (1-f)*sqrt(sa*sa + t*t));
var l2=atan2(ss1*sb, cu1*cs1-su1*ss1*cb);
var c=f/16*csa*(4+f*(4-3*csa));
var l=l2-(1-c)*f*sa* (s1+c*ss1*(cs1m+c*cs1*(-1+2*cs1m*cs1m)));
var d=atan2(sa, -t);
point.finalBrg=d+2*PI;
point.backBrg=d+PI;
point.lat = lat2;
point.lon = lon1+l;
}
}

function destSphere(lat1, lon1, brg, dist) {
with (Math) {
point.lat = asin(sin(lat1)*cos(dist) + cos(lat1)*sin(dist)*cos(brg));
point.lon = lon1 + atan2(sin(brg)*sin(dist)*cos(lat1), cos(dist)-sin(lat1)*sin(point.lat));
var dLon = lon1-point.lon;
var y = sin(dLon) * cos(lat1);
var x = cos(point.lat)*sin(lat1) - sin(point.lat)*cos(lat1)*cos(dLon);
var d=atan2(y, x);
point.finalBrg = d+PI;
point.backBrg=d+2*PI;
}
}


var recipient="C" + "o" + "n" + "t" + "a" + "c" + "t" + "o"
var eml = "mailto:" + "&#100;&#101;" + "a" + "&#110;&#64;&#103;&#101;&#111;&#109;&#105;&#100;&#112;&#111;&#105;&#110;&#116;&#46;&#99;&#111;&#109;";

function e() {
document.write('<a href=' + eml + '>' + recipient + '</a>');
}

