/*
 * Javascript code for geo:truc (http://www.geotruc.net/) 
 * 
 * Copyright (C) 2007-2010 Mickaël Graf <korbinus at gmail.com>
 */
var map = null;
var geocoder = null;
var gtURL = "http://www.geotruc.net/gt.php?sid="
var title = null;
var place = null;
var precision = 6;
var gtXmlHttp;
var displayLinks = 0;
function opt(v,txt) {
  return "<option value='" +v +"'>" +txt +"</option>"
}
var options = opt(-1,"----------------------") +opt(6, "Geo (microformat)") +opt(8, "GeoJSON") +opt(2, "GeoRSS (GML)")
 +opt(3, "GeoRSS (simple)") +opt(11, "Google Maps (static)") +opt(9, "GPX") +opt(4, "HTML")
 +opt(5, "KML") +opt(1, "Machine tags") +opt(10, "Nanoformat") +opt(7, "W3C geo")

var decimalCoordinates = /^([-]?[0-9]{1,2}[\.]?[0-9]*)[,; ]*([-]?[0-1]?[0-9]{1,2}[\.]?[0-9]*)$/;
var coord1 = /^([N|S])[ ]?(\d{1,2})[\°][ ]?(\d{1,2})[\'][ ]?(\d{1,2})[\"\']{1,2}[,; ]*([E|W])[ ]?(\d{1,3})[\°][ ]?(\d{1,2})[\'][ ]?(\d{1,2})[\"\']{1,2}$/;
var coord2 = /^(\d{1,2})[\°][ ]?(\d{1,2})[\'][ ]?(\d{1,2})[\"\']{1,2}[ ]?([N|S])[,; ]*(\d{1,3})[\°][ ]?(\d{1,2})[\'][ ]?(\d{1,2})[\"\']{1,2}[ ]?([E|W])$/;
var coord3 = /^([N|S])[ ]?(\d{1,2})[\°][ ]?(\d{1,2})[\'][,; ]*([E|W])[ ]?(\d{1,3})[\°][ ]?(\d{1,2})[\']$/;
var coord4 = /^(\d{1,2})[\°][ ]?(\d{1,2})[\'][ ]?([N|S])[,; ]*(\d{1,3})[\°][ ]?(\d{1,2})[\'][ ]?([E|W])$/;

/* Preload images */
var imgPth = "http://www.geotruc.net/images/";

var prog =new Image(107, 13)
prog.src =imgPth +"loading.gif"
var loading ="<img src='" + prog.src +"' border='0' alt='' />"

function GetXmlHttpObject() { 
 if(window.XMLHttpRequest) return new XMLHttpRequest()
 else if(window.ActiveXObject) return new ActiveXObject("Microsoft.XMLHTTP")
} 
function codeMapType (mt) {
 if(mt ==G_NORMAL_MAP) return 0
 if(mt ==G_SATELLITE_MAP) return 1
 if(mt ==G_HYBRID_MAP) return 2
 if(mt ==G_PHYSICAL_MAP) return 3
}
function wsURL(t,hl,x,y,z,mt){
 //base URL
 return gtURL +Math.random() +"&t=" +t +"&hl=" +hl +"&y=" +y +"&x=" +x +"&z=" +z +"&mt=" +mt
}
function gtXmlHttpCall(t, y, x, ttl) {
 if (t ==-1) return

 gtXmlHttp =GetXmlHttpObject()
 if(gtXmlHttp == null) {
  alert("Your browser doesn't support HTTP request.")
  return
 }
 var url =wsURL(t, t==0?"en_US":"0", x, y, map.getZoom(), codeMapType(map.getCurrentMapType()))
 if(t ==0){
     if(title !=null) url =url +"&title=" +encodeURI(title)
     gtXmlHttp.onreadystatechange =gtXmlHttpLinks
 } else{
  if(place){ 
    url =url +"&ad=" +encodeURI(place.address)
    try{
     with(place.AddressDetails.Country) {
      url =url +"&reg=" +encodeURI(CountryNameCode)
      with(AdministrativeArea) {
       if(AdministrativeAreaName) url =url +"&ar=" +encodeURI(aa.AdministrativeAreaName)
      }
     }
    } catch(err) { }
  }
  gtXmlHttp.onreadystatechange = gtXmlHttpCode
 }
 gtXmlHttp.open ("GET",url,true)
 gtXmlHttp.send (null)
}
function gtXmlHttpLinks() {
 var d =document.getElementById("display")
 if (gtXmlHttp.readyState ==4 || gtXmlHttp.readyState =="complete") {
  d.innerHTML =gtXmlHttp.responseText
  displayLinks =1
 } else d.innerHTML =loading
}
function gtXmlHttpCode () {
 var d =document.getElementById("display");
 displayLinks =0;
 if (gtXmlHttp.readyState ==4 || gtXmlHttp.readyState =="complete") {
  d.innerHTML ="<textarea id='geotag' class='code' cols='50' rows='5' readonly='readonly' title='Click to select' onclick='this.select();'>"
  +gtXmlHttp.responseText
  +"</textarea>"
 } else d.innerHTML =loading
}
function toDecDegrees (dir, d, m, s) {
 if (m>59) m = 59
 if (s>59) s = 59

 return (dir=="E" || dir=="N"? 1: -1)*(d*3600 + m*60 + s)/3600
}

function toDMS (val) {
 var p =val.toString().split(".") //parts
 var d =p[0] //degrees
 if(!p[1]) return d +"&#176 0' 0'' "

 p =(Number("0." +p[1])*60).toString().split(".")
 var m =p[0]
 if(!p[1]) return d +"&#176 " +m +"' 0'' "

 var s =roundDecimals(Math.round(Number("0." +p[1]) * 60)).toString();
 return d +"&#176 " +m +"' " +s +"'' ";
}
function convertLatToDMS(v) {
 return toDMS(Math.abs(v)) +(v <0? "S" :"N")
}
function convertLngToDMS(v) {
 return toDMS(Math.abs(v)) +(v <0? "W" :"E")
}
function roundDecimals(v) { 
 var a =Math.pow(10, precision)
 return Math.round(v*a)/a
}
function buildHTMLResult (pt, adrs) {
 title =adrs?adrs:roundDecimals(pt.y) +", " +roundDecimals(pt.x)
 var hint = "Click to select"
 var html = ""

 document.title = title +" - geo:truc"
 html ="<span id='resaddress' style='font-weight: bold'>" +title +"</span>"

 return html +"<div><table><tr><td id='coordinates'><b>Coordinates</b> : </td><td><input class='coords' size='23' readonly='readonly' title='" + hint + "'onclick='this.select();' value=\""+convertLatToDMS(pt.y)+", "+convertLngToDMS(pt.x) +"\" /></td></tr>"
  +"<tr><td>&nbsp;</td><td><input id='resdeccoord' class='coords' size='23' readonly='readonly' title='" + hint + "' onclick='this.select();' value='"+roundDecimals(pt.y)+", "+roundDecimals(pt.x)+"' /></td></tr></table></div>"
  +"Click <a href='#' class='mylk' onclick='gtXmlHttpCall(0,"+pt.y+", "+pt.x+",\"" +title +"\"); return false;'>here</a> for a link to this location<br />"
  +"or grab a snippet of code : "
  +"<select id='menu' onchange='gtXmlHttpCall(this.options[this.selectedIndex].value,"+pt.y+","+pt.x+");return false;'>" +options +"</select>"
  +"<div id='display'></div>"
}

/* DEPRECATED */  
function retrieveLocation() {
 var titi =decodeURI(window.location).split("x=")
 if(titi[1] !=undefined) {
  var toto =titi[1].split("-y=")
  var adrs =document.getElementById("address")
  adrs.value ==toto[1] +" "+ toto[0]
  showAddress(adrs.value)
 }
}

function newDraggableMarker(pt, adrs) {
 var marker = new GMarker (pt, {draggable: true});

 map.clearOverlays() //clean the map
 document.getElementById("res").innerHTML = buildHTMLResult(pt,adrs) //build coordinates
 gtXmlHttpCall(0,pt.y, pt.x, title)
 map.addOverlay(marker) //show the marker 
 map.panTo(pt) //pan

 GEvent.addListener(marker, "dragend", function() {
  var pt = marker.getLatLng()
  document.getElementById("res").innerHTML = buildHTMLResult(pt,'')
  gtXmlHttpCall(0,pt.y, pt.x, title)
  map.panTo(pt)
 })
 return marker;
}
function checkBoundaries(l, b) {
 var c=-1*b
 /* if the l is out of this world, return a corrected value */
 if(l >= c && l <= b) return l
 else if(l < c) return c
 else if(l > b) return b 
}
function latBound(l) {
 return checkBoundaries(l, 90)
}
function longBound(l) {
 return checkBoundaries(l, 180)
}
function makeMarker(lt,lg,z,adrs) {
 var pt = new GLatLng(lt,lg)
 map.setCenter(pt, z)
 var mrk = newDraggableMarker(pt,adrs)
}
function showAddress (adrs, zoom) {
 /* Check if the adrs is coordinates before asking geocoder for avoiding to get results screwed by reversed geocoding.*/
 var pt, marker, decLat, decLong

 var prsDecCoords=adrs.match(decimalCoordinates)
 var parse1=adrs.match(coord1)
 var parse2=adrs.match(coord2)
 var parse3=adrs.match(coord3)
 var parse4=adrs.match(coord4)

 if(!zoom) zoom=13
 /* Check that address is in fact coordinates */
 if(prsDecCoords) {
  makeMarker(prsDecCoords[1], prsDecCoords[2])
 } 
 else if(parse1) {
  place=null
  decLat = toDecDegrees(parse1[1], latBound(Number(parse1[2])), Number(parse1[3]), Number(parse1[4]))
  decLong = toDecDegrees (parse1[5], longBound(Number(parse1[6])), Number(parse1[7]), Number(parse1[8]))
  makeMarker(decLat, decLong, zoom)
 }
 else if(parse2) {
  place=null
  decLat = toDecDegrees(parse2[4], latBound(Number(parse2[1])), Number(parse2[2]), Number(parse2[3]))
  decLong = toDecDegrees(parse2[8], longBound(Number(parse2[5])), Number(parse2[6]), Number(parse2[7]))
  makeMarker(decLat, decLong, zoom)
 }
 else if(parse3) {
  place=null
  decLat = toDecDegrees(parse3[1], latBound(Number(parse3[2])), Number(parse3[3]), 0)
  decLong = toDecDegrees(parse3[4], longBound(Number(parse3[5])), Number(parse3[6]), 0)
  makeMarker(decLat, decLong, zoom)
 }
 else if(parse4) {
  place=null
  decLat = toDecDegrees(parse4[3], latBound(Number(parse4[1])), Number(parse4[2]), 0)
  decLong = toDecDegrees(parse4[6], longBound(Number(parse4[4])), Number(parse4[5]), 0)
  makeMarker(decLat, decLong, zoom)
 }
 else if(geocoder) {
  geocoder.getLocations ( adrs,
   function (response) {
    if (!response || response.Status.code != 200) alert(adrs +" not geocoded.")
    else { 
     place = response.Placemark[0]
     makeMarker(place.Point.coordinates[1], place.Point.coordinates[0],zoom,place.address)
    }
   }
  );
 }
}
function getElementValue(id) {
  return document.getElementById(id).value
}
function FBPublish() {
  FB.ui({
    method: "stream.publish",
    attachment: {
      name: 'geo:truc',
      caption: document.getElementById('resaddress').innerHTML,
      href: document.getElementById('url').value,
      media: [
        {
          type: "image",
	  src: document.getElementById('minimapurl').value,
          href: document.getElementById('url').value
        }
      ]
    }
  },
  function(r){  loginsUpdate(); }
 );
}
function loginsUpdate() {
  var l=document.getElementById('logins');
  FB.getLoginStatus(function(r){if(r.session) 
    {l.innerHTML='Welcome <fb:name uid="loggedinuser" firstnameonly="true" useyou="false"></fb:name> <fb:login-button size="small" autologoutlink="true" onlogin="loginsUpdate()"></fb:login-button>' }
    else {l.innerHTML='<fb:login-button size="small" autologoutlink="true" onlogin="loginsUpdate()"></fb:login-button>'}
  });
  FB.XFBML.parse(l);
}

function load(){
 if(GBrowserIsCompatible()){
   loginsUpdate();
  var mapType;
  switch(Number(getElementValue("map_type"))) {
   case 1: mapType =G_SATELLITE_MAP
   break
   case 2: mapType =G_HYBRID_MAP
   break
   case 3: mapType =G_PHYSICAL_MAP
   break
   default: mapType =G_NORMAL_MAP
  }
  var startZoom =Number(getElementValue("start_zoom"))
  var latitude =Number(getElementValue("latitude"))
  var longitude =Number(getElementValue("longitude")) 

  geocoder = new GClientGeocoder()
  map = new GMap2(document.getElementById("map"))
  map.setCenter(new GLatLng(latitude, longitude), startZoom, mapType)
  map.setUIToDefault()
  map.addControl(new GOverviewMapControl())

  GEvent.addListener(map, "click", function(overlay, point) {
   if (overlay) map.removeOverlay (overlay)
   else { 
    place =null
    marker =newDraggableMarker(point) 
   }
  });

  GEvent.addListener(map, "zoomend", function(old, nw) {
   if (displayLinks ==1) {
    var loc =getElementValue("resdeccoord")
    var coords =loc.split(', ')
    gtXmlHttpCall(0,Number(coords[0]), Number(coords[1]), document.title) 
   }
  });

  GEvent.addListener(map, "maptypechanged", function() {
   if (displayLinks ==1) {
    var loc =getElementValue("resdeccoord")
    var coords =loc.split(', ')
    gtXmlHttpCall(0,Number(coords[0]), Number(coords[1]), document.title)
   }
  });

  if (getElementValue("address")) showAddress (getElementValue("address"))
  else if(latitude != 20 && longitude != 0) {
  // Are the coordinates different from the standard center? If yes, create the menu and a marker
   marker = newDraggableMarker(new GLatLng(latitude, longitude))
  }
 }
}
