/* global Bdf,Geo,L */

Geo.Position = function (map, checkCallback) {
    this.map = map;
    this.checkCallback = checkCallback;
    this.stateObject = {
        
    };
};

/* Constantes */
Geo.Position.CURRENT_POSITION_KEY = "currentposition";
Geo.Position.NEW_POSITION_KEY = "newposition";

Geo.Position.initMap = function (mapId, start, checkCallback) {
    var centerLat, centerLon, zoom, withCurrent;
    if (start) {
        centerLat = start.latitude;
        centerLon = start.longitude;
        zoom = 12;
        if (start.zoom) {
            zoom = start.zoom;
        }
        withCurrent = true;
        if (start.noCurrent) {
            withCurrent = false;
        }
    } else {
        centerLat = -1;
        centerLon = 0;
        zoom = 1;
        withCurrent = false;
    }
    var map = Geo.init(mapId, centerLat, centerLon, zoom);
    var geoPosition =  new Geo.Position(map, checkCallback);
    if (withCurrent) {
        geoPosition.addMarker(Geo.Position.CURRENT_POSITION_KEY, new L.LatLng(centerLat, centerLon), {
                title: Bdf.Loc.get("_ label.pioche.position_current"),
                clickable: false
        });
        checkCallback(geoPosition);
    }
    map.on('click', function(e) {
        geoPosition.setNewPosition(e.latlng);
    });
    return geoPosition;
};

Geo.Position.prototype.centerOn = function (key) {
    var marker = this.getMarker(key);
    if (marker) {
        this.map.panTo(marker.getLatLng());
    }
};

Geo.Position.prototype.getMarker = function (key) {
    if (this.hasMarker(key)) {
        return this.stateObject[key];
    }
    return null;
};

Geo.Position.prototype.hasMarker = function (key) {
    return this.stateObject.hasOwnProperty(key);
};

Geo.Position.prototype.addMarker = function (key, latlng, options) {
    var imageName;
    if (key === Geo.Position.CURRENT_POSITION_KEY) {
        imageName = "marker-blue.png";
    } else {
        imageName = "marker-red.png";
    }
    options.icon =  L.icon({
        iconSize: [25, 41],
        iconAnchor: [12, 41],
        popupAnchor: [1, -34],
        shadowSize: [41, 41],
        shadowUrl: 'theme/icons/marker-shadow.png',
        iconUrl: 'theme/icons/' + imageName
    });
    var marker = new L.Marker(latlng, options);
    marker.addTo(this.map);
    this.stateObject[key] = marker;
    return marker;
};

Geo.Position.prototype.setNewPosition = function (latlng) {
    var marker = this.getMarker(Geo.Position.NEW_POSITION_KEY);
    if (marker) {
        marker.setLatLng(latlng);
    }
    else {
        this.addMarker(Geo.Position.NEW_POSITION_KEY, latlng, {
                title: Bdf.Loc.get("_ label.pioche.position_new"),
                draggable: true,
                zIndexOffset: 1000
        });
    }
    this.checkCallback(this);
};

Geo.Position.prototype.centerBoth = function () {
    var currentMarker = this.getMarker(Geo.Position.CURRENT_POSITION_KEY);
    var newMarker = this.getMarker(Geo.Position.NEW_POSITION_KEY);
    if ((!currentMarker) || (!newMarker)) return;
    var array = new Array();
    array[0] = currentMarker.getLatLng();
    array[1] = newMarker.getLatLng();
    var bounds = new L.LatLngBounds(array);
    this.map.fitBounds(bounds, {padding: [30,30]});
};

/*
Voir http://wiki.openstreetmap.org/wiki/Nominatim
*/
Geo.Position.prototype.geocodage = function (address, callback) {
    var geoposition = this;
    if (!address) {
        callback(false);
        return;
    }
    var cleanedAddress = Geo.cleanString(address);
    if (cleanedAddress.length === 0) {
        callback(false);
        return;
    }
    $.ajax({
        url: "https://nominatim.openstreetmap.org/search",
        dataType: "jsonp",
        jsonp: "json_callback",
        data: {
            format: "json",
            q: cleanedAddress,
            limit: 1
        },
        success: function (data, textStatus) {
            if (data.length === 0) {
                callback(false);
            } else {
                let first = data[0];
                let latlng = new L.LatLng(first.lat, first.lon);
                geoposition.setNewPosition(latlng);
                geoposition.map.panTo(latlng);
                callback(true);
            }
        },
        error: function (XMLHttpRequest, textStatus, errorThrown)  {
            Bdf.log(textStatus);
        }
    });
};
