function Geolocation(position){
  this.stopped = false;
  this.position = position;

  this.center = new OpenLayers.LonLat(position.coords.longitude, position.coords.latitude); 
  this.bbox = getAccuracyExtent(this.center,position.coords.accuracy);
  var extent = this.bbox.clone();

  this.accuracy = position.coords.accuracy;
  if (this.accuracy < 1000) {
    this.accuracy = 1000;
    this.bbox = getAccuracyExtent(this.center,this.accuracy);
  }

  extent.transform(map.displayProjection,map.projection);
  map.zoomToExtent(extent);

  var center = this.center;
  var txt = '<div>';
  txt += '<h3>Your probable position</h3>';
  txt += '<p>';
  txt += 'Latitude : '+center.lat+'<br>';
  txt += 'Longitude : '+center.lon+'<br>';
  txt += 'Accuracy : '+position.coords.accuracy+' meters<br>';
  txt += '</p>';
  txt += '<br>';
  txt += '</div>';
  addPoint(userLayer,
           center.lon,
           center.lat,
           txt,
           new OpenLayers.Icon('img/marker.png'));

  center.transform(map.displayProjection,map.projection);
  var feature = new OpenLayers.Feature.Vector(
      new OpenLayers.Geometry.Point(center.lon,center.lat),
            {accuracy:position.coords.accuracy}
      );
  accuracyLayer.addFeatures([feature]);

  this.loadData();
}

Geolocation.prototype = {
  loadData: function() {
    var self = this;
    var bbox = this.bbox;

    $("#message").html("Get spatial information");
    $.get("wikipedia.php",
        {north:bbox.top,
         south:bbox.bottom,
         east:bbox.right,
         west:bbox.left,
         maxRows:50
        },
        function(data) {
          self.addWikipediaData(data);
        });

    var position = this.position;
    var accuracy = this.accuracy;

    $.get("geonames.php",
        {lat:position.coords.latitude,
         lng:position.coords.longitude,
         radius:accuracy/1000,
         featureClass:'P',
         maxRows:50
        },
        function(data) {
          self.addGeonamesData(data);
        });
    $.get("geonames.php",
        {lat:position.coords.latitude,
         lng:position.coords.longitude,
         radius:accuracy/1000,
         featureClass:'H',
         maxRows:50
        },
        function(data) {
          self.addGeonamesData(data);
        });
    $.get("geonames.php",
        {lat:position.coords.latitude,
         lng:position.coords.longitude,
         radius:accuracy/1000,
         featureClass:'L',
         maxRows:50
        },
        function(data) {
          self.addGeonamesData(data);
        });
    $.get("geonames.php",
        {lat:position.coords.latitude,
         lng:position.coords.longitude,
         radius:accuracy/1000,
         featureClass:'T',
         maxRows:50
        },
        function(data) {
          self.addGeonamesData(data);
        });
    $.get("geonames.php",
        {lat:position.coords.latitude,
         lng:position.coords.longitude,
         radius:accuracy/1000,
         featureClass:'S',
         maxRows:50
        },
        function(data) {
          self.addGeonamesData(data);
        });
  },
  addWikipediaData: function(data) {
    if (this.stopped)
      return false;

    var JSON = new OpenLayers.Format.JSON();
    var geonames = JSON.read(data).geonames;

    $("#message").html(geonames.length+" Wikipedia's articles");
    geonames.forEach(function(aGeoName) {
      var txt = '<div>';
      txt += '<h3>'+aGeoName.title+'</h3>';
      txt += '<p>'+aGeoName.summary+'</p>';
      txt += '<p><a href="http://'+aGeoName.wikipediaUrl+'">Article</a></p>';
      txt += '<br>';
      txt += '</div>';
      var icon = new OpenLayers.Icon(
        'img/wikipedia.png',
        new OpenLayers.Size(16,16)
      );
      addPoint(wikipediaLayer,aGeoName.lng,aGeoName.lat,txt,icon);
    });
    wikipediaLayer.isLoaded = true;

    if ((pGeonamesLayer.isLoaded &&
          hGeonamesLayer.isLoaded &&
          lGeonamesLayer.isLoaded &&
          tGeonamesLayer.isLoaded &&
          sGeonamesLayer.isLoaded) ||
        (geonamesLayersLoaded == 5)) {
      $("#message").html("All information around you are loaded");
      $("#throbber").css("display","none");
      $("#warning").css("display", "none");
    }
    return true;
  },

  addGeonamesData: function(data) {
    if (this.stopped)
      return false;

    var JSON = new OpenLayers.Format.JSON();
    var geonames = JSON.read(data).geonames;
    geonamesLayersLoaded++;
    if (geonames.length > 0) {
      var layer = pGeonamesLayer;
      var icon = new OpenLayers.Icon('img/marker-gold.png');
      switch (geonames[0].fcl) {
        case 'P':
          $("#message").html(
              geonames.length+" Geonames : city, village, ...");
          break;
        case 'H':
          $("#message").html(
              geonames.length+" Geonames : stream, lake, ...");
          layer = hGeonamesLayer;
          icon = new OpenLayers.Icon('img/marker-blue.png');
          break;
        case 'L':
          $("#message").html(
              geonames.length+" Geonames : parks, area, ...");
          layer = lGeonamesLayer;
          icon = new OpenLayers.Icon('img/marker-green.png');
          break;
        case 'T':
          $("#message").html(
              geonames.length+" Geonames : mountain, hill, rock, ...");
          layer = tGeonamesLayer;
          icon = new OpenLayers.Icon('img/marker-brawn.png');
          break;
        case 'S':
          $("#message").html(
              geonames.length+" Geonames : spot, building, farm, ...");
          layer = sGeonamesLayer;
          icon = new OpenLayers.Icon('img/marker-violet.png');
          break;
      }
      geonames.forEach(function(aGeoName) {
        var txt = '<div>';
        txt += '<h3>'+aGeoName.name+'</h3>';
        txt += '<p>';
        if (aGeoName.fcl == 'P') {
          txt += 'Population : '+aGeoName.population+'<br>';
        }
        txt += aGeoName.fcodeName+"<br>";
        txt += aGeoName.adminName1+", "+aGeoName.countryName+"<br>";
        txt += '</p>';
        txt += '<br>';
        txt += '</div>';
        addPoint(layer,aGeoName.lng,aGeoName.lat,txt,icon.clone());
      });
      layer.isLoaded = true;
    }

    if ((wikipediaLayer.isLoaded &&
          pGeonamesLayer.isLoaded &&
          hGeonamesLayer.isLoaded &&
          lGeonamesLayer.isLoaded &&
          tGeonamesLayer.isLoaded &&
          sGeonamesLayer.isLoaded) ||
        (geonamesLayersLoaded == 5)) {
      $("#message").html("All information around you are loaded");
      $("#throbber").css("display","none");
      $("#warning").css("display", "none");
    }
    return true;
  }
};
