﻿// ==UserScript==
// @name           KOUtil
// @namespace      http://rflexor.cachezentrale.de
// @description    Fügt Links hinter Koordinaten ein
// @include        http://*
// ==/UserScript==


//TODO: Darf nicht �ber den Bildschirmrand gehen
//TODO: Andere Koordinatenformate
//TODO: Umrechnungen: Bei Eingabe: Formatcheck
//TODO: Peilen etc. anbieten
//TODO: Sekunden unterscheiden sich manchmal im 100stel Sekundenbereich. Auch ber�cksichtigen?

function getXEle(path) {
  var result=document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null ).singleNodeValue;
  return result;
}

function getXEles(path) {
  var result=document.evaluate(path, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null );
  return result;
}


var reArray = new Array();
// GC-Form
reArray[0]=/([NS]\s*\d\d*°*\s*\d\d*[.,]\d\d\d'*\s[EOW]\s*\d\d*°*\s*\d\d*[.,]\d\d\d'*)/g;
// Garmin-Form
reArray[1]=/([NS]\s*\d\d*°*\s*\d\d*'\s*\d\d*"\s[EOW]\s*\d\d*°*\s*\d\d*'\s*\d\d*")/g;

	
var foundKO=false;

//Some Pages dont want KOUtil ...
if (document.body.innerHTML.indexOf("NOKOUTIL")==-1) {
  for (i=0;i<reArray.length;i++) {
    if (document.body.innerHTML.search(reArray[i])!=-1) {
      foundKO=true;
      break;
    }
  }
}
if (foundKO) {

var textsnap = getXEles('//text()');
for (var i = 0; i < textsnap.snapshotLength; i++)  {
 
  var curNode=textsnap.snapshotItem(i);
  var idx1=0;

  while (-1 != idx1) {  
 
    var curText=curNode.nodeValue;
    var koType=-1;

    for (j=0;j<reArray.length;j++) {
      if (curText.search(reArray[j])!=-1) {
        koType=j;
        break;
      }
    }

    var idx1=curText.search(reArray[koType]); 
    if (-1 != idx1) {

      var len=curText.match(reArray[koType])[0].length;
      var before=document.createTextNode(curText.substr(0,idx1));
      var ko=document.createTextNode(curText.substr(idx1, len));
      var after=document.createTextNode(curText.substr(idx1+len));
      var parentNd = curNode.parentNode;
      
      var span=document.createElement("span");
      span.setAttribute("style", "color:red;cursor:pointer;font-size:20px");
      span.setAttribute("title", "Koordinaten im KOUtil �ffnen");
      span.setAttribute("onClick", "javascript:KOUtil(event, this.previousSibling,"+koType+");");
      span.appendChild(document.createTextNode("\u21d7"));
      //span.appendChild(ko);
 
      parentNd.replaceChild(after,curNode);
      parentNd.insertBefore(span,after);
      parentNd.insertBefore(ko,span);
      parentNd.insertBefore(before,ko);
    }
    curNode=after;
  }

}

var scrNode = document.createElement("script");
var head=getXEle('//head');
if (!head) {

  head = document.createElement("head");
  html = document.getXEle('//html');
  html.insertBefore(head,html.firstChild);
}
head.appendChild(scrNode);

var divLay = document.createElement("div");

divLay.setAttribute("style","  \
   width:300px; height:200px; visibility:hidden; background:#F5F5F5; color:black; \
   position:absolute; top:100px; left:100px; outline-width:1px; outline-color:#000000; \
   outline-style:solid;font-family:sans-serif; font-size:8pt");

divLay.divMoveFlag=false;
divLay.setAttribute("id","KOUtilPopup");



var tab = document.createElement("table");
tab.setAttribute("border","0");
tab.setAttribute("cellpadding","2");
tab.setAttribute("height","10");
tab.setAttribute("width","100%");
var row1 = document.createElement("tr");
var row2 = document.createElement("tr");
var titlebar = document.createElement("td");
var windowclose = document.createElement("td");

titlebar.setAttribute("width","100%");
titlebar.setAttribute("bgcolor","#CCCCCC");
titlebar.setAttribute("style","font-family:sans-serif; text-align:center;font-size:8pt;cursor:default;");

windowclose.setAttribute("width","10");
windowclose.setAttribute("bgcolor","#CCCCCC");
windowclose.setAttribute("style","font-family:sans-serif; font-size:8pt;text-align:center;cursor:default;");
windowclose.innerHTML="[X]";

var contentCell = document.createElement("td");
contentCell.setAttribute("id","KOUtilContent");
contentCell.setAttribute("colspan","2");
contentCell.setAttribute("style","text-align:left;background:#F5F5F5; padding:5px; color:black;font-family:sans-serif; font-size:8pt");

contentCell.innerHTML=' \
   <p>Found coordinates: <span id="KOUtilOrigKO"></span></p> \
   <p>In other words:</p><form> \
   <div align="center"><table border="0"> \
     <tr><td style="font-size:8pt">Deg:</td><td> \
        <input type="text" size="30" onChange="recalc(0);" \
           style="font-size:8pt;border-width:0;outline-color:#000000;outline-width:1px;outline-style:solid;" id="KOUtilDegKO"> \
     </td></tr> \
     <tr><td style="font-size:8pt">Min:</td><td> \
        <input type="text" size="30" onChange="recalc(1);" \
           style="font-size:8pt;border-width:0;outline-color:#000000;outline-width:1px;outline-style:solid;" id="KOUtilMinKO"> \
     </td></tr> \
     <tr><td style="font-size:8pt">Sec:</td><td> \
        <input type="text" size="30" onChange="recalc(2);" \
           style="font-size:8pt;border-width:0;outline-color:#000000;outline-width:1px;outline-style:solid;" id="KOUtilSecKO"> \
     </td></tr> \
   </table></div></form> \
   <p>What do you want to do?</p> \
   <ul><li><a id="KOUtilLinkGM" href="" target="_blank">Show in Google Maps</a></li> \
       <li><a id="KOUtilLinkGC" href="" target="_blank">Show in GC.com</a></li></ul></p> \
';



divLay.appendChild(tab);
tab.appendChild(row1);
row1.appendChild(titlebar);
row1.appendChild(windowclose);
tab.appendChild(row2);
row2.appendChild(contentCell);
titlebar.innerHTML="KO-Util V0.7";

titlebar.setAttribute("onMouseDown",'                   \
  var popup=document.getElementById("KOUtilPopup");     \
  popup.divMoveFlag=true;                              \
  var obj=popup;     \
  var oX = obj.offsetLeft;var oY = obj.offsetTop;     \
  while(obj.parentNode) {                             \
      oX=oX+obj.parentNode.offsetLeft;                \
      oY=oY+obj.parentNode.offsetTop;                 \
      if (obj==document.getElementsByTagName("body")[0]) {break;} \
      else{obj=obj.parentNode;}                       \
    }                                                 \
    popup.rX=event.pageX-oX;                           \
    popup.rY=event.pageY-oY;                           \
  return false;');

titlebar.setAttribute("onMouseUp",'                     \
  var popup=document.getElementById("KOUtilPopup");     \
  popup.divMoveFlag=false;                             \
  ');

titlebar.setAttribute("onMouseMove",' \
  var popup=document.getElementById("KOUtilPopup");     \
  if(popup.divMoveFlag) { \
    popup.style.left=(event.pageX-popup.rX)+"px";           \
    popup.style.top=(event.pageY-popup.rY)+"px";            \
  }');

titlebar.setAttribute("onMouseOut",' \
  var popup=document.getElementById("KOUtilPopup");     \
  if(popup.divMoveFlag) { \
    popup.style.left=(event.pageX-popup.rX)+"px";           \
    popup.style.top=(event.pageY-popup.rY)+"px";            \
  }');


windowclose.setAttribute("onMouseDown",'divHide();');


document.body.appendChild(divLay);

scrNode.innerHTML='                                                   \
function divVisible() { \
  document.getElementById("KOUtilPopup").style.visibility="visible";     \
} \
function divHide() { \
  document.getElementById("KOUtilPopup").style.visibility="hidden";     \
} \
function KOClass () { \
  this.lat=0; \
  this.lon=0; \
} \
KOClass.prototype.fromSec = function(strKoMin) { \
   var i=strKoMin.replace(/[°\'"]/g," "); \
   i=i.replace(/,/g,".");  \
   i=i.replace(/O/g,"E");                                          \
   i=i.replace(/^.*([NS])\\s*(\\d\\d*)\\s*(\\d\\d*)\\s*(\\d\\d*)\\s*([EW])\\s*(\\d\\d*)\\s*(\\d\\d*)\\s*(\\d\\d*).*$/,"$1 $2 $3 $4 $5 $6 $7 $8");  \
   var parts=i.split(" ");                                           \
   koLaNS=parts[0];                                                  \
   koLaDeg=parts[1];                                                 \
   koLaMin=parts[2];                                                 \
   koLaSec=parts[3];                                                 \
   koLoNS=parts[4];                                                  \
   koLoDeg=parts[5];                                                 \
   koLoMin=parts[6];                                                 \
   koLoSec=parts[7];                                                 \
   this.lat=((koLaNS == "N"?1:-1)*((1*koLaDeg)+(koLaMin/60)+(koLaSec/3600)));      \
   this.lon=((koLoNS == "E"?1:-1)*((1*koLoDeg)+(koLoMin/60)+(koLoSec/3600)));      \
}; \
KOClass.prototype.fromMin = function(strKoMin) { \
   var i=strKoMin.replace(/[°\'"]/g," "); \
   i=i.replace(/,/g,"."); \
   i=i.replace(/O/g,"E"); \
   i=i.replace(/^.*([NS])\\s*(\\d\\d*)\\s*(\\d\\d*\\.\\d\\d\\d)\\s*([EW])\\s*(\\d\\d*)\\s*(\\d\\d*\\.\\d\\d\\d).*$/,"$1 $2 $3 $4 $5 $6"); \
   var parts=i.split(" "); \
   koLaNS=parts[0]; \
   koLaDeg=parts[1]; \
   koLaMin=parts[2]; \
   koLoNS=parts[3]; \
   koLoDeg=parts[4]; \
   koLoMin=parts[5]; \
   this.lat=((koLaNS == "N"?1:-1)*((1*koLaDeg)+(koLaMin/60))); \
   this.lon=((koLoNS == "E"?1:-1)*((1*koLoDeg)+(koLoMin/60))); \
}; \
KOClass.prototype.fromDeg = function(strKoDeg) { \
   var i=strKoDeg.replace(/[°\'"]/g," "); \
   i=i.replace(/,/g,"."); \
   i=i.replace(/O/g,"E"); \
   i=i.replace(/^.*([NS])\\s*(\\d\\d*\\.\\d*)\\s*([EW])\\s*(\\d\\d*\\.\\d*).*$/,"$1 $2 $3 $4"); \
   var parts=i.split(" "); \
   koLaNS=parts[0]; \
   koLaDeg=parts[1]; \
   koLoNS=parts[2]; \
   koLoDeg=parts[3]; \
   this.lat=((koLaNS == "N"?1:-1)*koLaDeg); \
   this.lon=((koLoNS == "E"?1:-1)*koLoDeg); \
}; \
KOClass.prototype.getDeg = function() { \
 var iLat=this.lat; \
 var iLon=this.lon; \
 var latNS=iLat>0?"N":"S"; \
 var lonEW=iLon>0?"E":"W"; \
 iLat=iLat*(iLat>0?1:-1); \
 iLon=iLon*(iLon>0?1:-1); \
 var latdeg=Math.round(iLat*1000000)/1000000; \
 var londeg=Math.round(iLon*1000000)/1000000; \
 return latNS+" "+latdeg+" "+lonEW+" "+londeg; \
}; \
KOClass.prototype.getMin = function() { \
 var iLat=this.lat; \
 var iLon=this.lon; \
 var latNS=iLat>0?"N":"S"; \
 var lonEW=iLon>0?"E":"W"; \
 iLat=iLat*(iLat>0?1:-1); \
 iLon=iLon*(iLon>0?1:-1); \
 var latdeg=Math.floor(iLat); \
 var londeg=Math.floor(iLon); \
 var latmin=Math.round((iLat-latdeg)*60000)/1000; \
 var lonmin=Math.round((iLon-londeg)*60000)/1000; \
 return latNS+" "+latdeg+" "+latmin+" "+lonEW+" "+londeg+" "+lonmin; \
}; \
KOClass.prototype.getSec = function() { \
 var iLat=this.lat; \
 var iLon=this.lon; \
 var latNS=iLat>0?"N":"S"; \
 var lonEW=iLon>0?"E":"W"; \
 iLat=iLat*(iLat>0?1:-1); \
 iLon=iLon*(iLon>0?1:-1); \
 var latdeg=Math.floor(iLat); \
 var londeg=Math.floor(iLon); \
 var latsec=(iLat-latdeg)*60; /*ugly*/ \
 var lonsec=(iLon-londeg)*60; /*ugly*/ \
 var latmin=Math.floor((iLat-latdeg)*60); \
 var lonmin=Math.floor((iLon-londeg)*60); \
 latsec=Math.round((latsec-latmin)*60); \
 lonsec=Math.round((lonsec-lonmin)*60); \
 return latNS+" "+latdeg+" "+latmin+" "+latsec+" "+lonEW+" "+londeg+" "+lonmin+" "+lonsec; \
}; \
KOClass.prototype.getGM = function() { \
   gKoLaDeg=Math.round(this.lat*10000000)/10000000; \
   gKoLoDeg=Math.round(this.lon*10000000)/10000000; \
   var url="http://maps.google.de/maps?f=q&hl=de&geocode=&time=&date=&ttype=&q=";                               \
   /*url=url+koLaNS+"+"+koLaDeg+"%C2%B0+"+koLaMin+"+"+koLoNS+"+"+koLoDeg+"%C2%B0+"+koLoMin+"&ie=UTF8&ll="; */       \
   url=url+this.getMin().replace(/ /g,"+")+"&ie=UTF8&ll=";        \
   url=url+gKoLaDeg+","+gKoLoDeg;                                                                               \
   url=url+"&spn=0.004512,0.010042&t=h&z=17&om=1";  \
   return url;                                                            \
}; \
KOClass.prototype.getGC = function() { \
   return "http://www.geocaching.com/seek/gmnearest.aspx?lat="+this.lat+"&lng="+this.lon+"&zm=16&mt=h";      \
}; \
  function KOUtil(event, domele, typ) {                               \
   var contentCell = document.getElementById("KOUtilContent");                    \
   var popup = document.getElementById("KOUtilPopup");                    \
   divVisible();                     \
   popup.style.left=event.pageX+"px";                               \
   popup.style.top=event.pageY+"px";                                \
   var KOs=domele.nodeValue.replace(/  */g," ");                      \
   var origKO=KOs;                                                    \
   var KOObj=new KOClass();                                            \
   if (typ===0) { \
     KOObj.fromMin(KOs); \
   } else { \
     KOObj.fromSec(KOs); \
   } \
   document.getElementById("KOUtilOrigKO").innerHTML=origKO; \
   updatePanel(KOObj); \
} \
  function recalc(typ) { \
    var KOObj = new KOClass(); \
    if (0==typ) { \
       KOObj.fromDeg(document.getElementById("KOUtilDegKO").value); \
    } else if (1==typ) { \
       KOObj.fromMin(document.getElementById("KOUtilMinKO").value); \
    } else if (2==typ){ \
       KOObj.fromSec(document.getElementById("KOUtilSecKO").value); \
    } \
    updatePanel(KOObj); \
  } \
  function updatePanel(kos) { \
    document.getElementById("KOUtilDegKO").setAttribute("value",kos.getDeg()); \
    document.getElementById("KOUtilMinKO").setAttribute("value",kos.getMin()); \
    document.getElementById("KOUtilSecKO").setAttribute("value",kos.getSec()); \
    document.getElementById("KOUtilLinkGM").setAttribute("href",kos.getGM()); \
    document.getElementById("KOUtilLinkGC").setAttribute("href",kos.getGC()); \
  } \
';

}



