/**
 * Google map fonctions.
 *
 * @copyright Travelsoft
 * @author antoine.ndione
 */
(function($){

    var messages = [];
    messages[G_GEO_MISSING_ADDRESS]    = "Aucune adresse spécifiée";
    messages[G_GEO_UNKNOWN_ADDRESS]    = "La localisation a échoué, cette adresse est inconue";
    messages[G_GEO_UNAVAILABLE_ADDRESS]= "La localisation de cette adresse est indisponible";
    messages[G_GEO_BAD_KEY]            = "Votre cléf est incorect (Cléf de l'Api google)";
    messages[G_GEO_TOO_MANY_QUERIES]   = "Vous faites trop de requêtes, veuillez contacter les responsable de google api";
    messages[G_GEO_SERVER_ERROR]       = "Le server de localisation de google a rencontré une erreur interne";


    /** Search for a map. */
    $.fn.google = function (){
        var query = $(this).attr("href") ||$(this).attr("href");
        var inZoom = $(this).attr("rel");
        var mapInfo = getMapInfo(query, $(this).parent("div"));
        if (inZoom && inZoom !== "" && inZoom != "null") {
            mapInfo.zoom = parseInt(inZoom);
        }
        getMap(mapInfo);
    };

    /** get's the map or notify the error. */
    function getMap(mapInfo) {
        if (mapInfo === undefined || mapInfo === null) {mapInfo = {};}
        if (mapInfo.container !== null) {
            if (GBrowserIsCompatible()) {
                var bounds = new GLatLngBounds();
                if (mapInfo.latitude !== null && mapInfo.longitude !== null) {
                    var map = initMap(mapInfo);
                    var point = new GLatLng(mapInfo.latitude, mapInfo.longitude);
                    var marker = createMarker(point, mapInfo);
                    map.addOverlay(marker);
                    bounds.extend(point);
                    map.setZoom(map.getBoundsZoomLevel(bounds));
                    map.setCenter(bounds.getCenter());
                    if (mapInfo.openInfoWin) {
                        GEvent.trigger(marker,'click');
                    }
                } else if (mapInfo.address !== null) {
                    var geocoder= new GClientGeocoder();
                    geocoder.getLocations(mapInfo.address, function(result){
                        if (result.Status.code === G_GEO_SUCCESS) {
                            if (result.Placemark.length > 0) {
                                var map = initMap(mapInfo);
                                var p = result.Placemark[0].Point.coordinates;
                                var point = new GLatLng(p[1],p[0]);
                                var marker = createMarker(point, mapInfo);
                                map.addOverlay(marker);
                                bounds.extend(point);
                                map.setZoom(getMyZoom(mapInfo, map, bounds));
                                map.setCenter(bounds.getCenter());
                                if (mapInfo.openInfoWin) {
                                    GEvent.trigger(marker,'click');
                                }
                            }
                        } else {
                            var reason = "Une erreur est survenue lors de la localisation code = " + result.Status.code;
                            if (messages[result.Status.code]) {
                                reason = messages[result.Status.code];
                            }
                            mapInfo.container.html('<p class="gMapError">' + reason +'</p>');
                        }
                    });
                }
            } else {
                container.html = "Problême de compatibilité aec google map";
            }
        } else {
            alert("Aucun container défini");
        }
    }

    /** Initialize the map */
    function initMap(mapInfo) {
        var map = new GMap2(mapInfo.container.get(0));
        map.setCenter(new GLatLng(0,0),0);
        map.addControl(new GLargeMapControl());
        map.addControl(new GMapTypeControl());
        return map;
    }

    /** Get's the specified zoom or the default one. */
    function getMyZoom(mapInfo, map, bounds) {
        var myZoom = mapInfo.zoom;
        var defaultZoom = map.getBoundsZoomLevel(bounds);
        if (myZoom && myZoom < defaultZoom) {
            return myZoom;
        } else {
            return defaultZoom;
        }
    }

    /** Get's the search informations .*/
    function getMapInfo(query, container) {
        var info = $.extend({}, $.fn.google.defaults);
        if (query !== null) {
            info.query = query;
            info.container = container;
            var splited = /(.*)\((.*)\)@([-|+]{0,1}[0-9]+.*[0-9]+),([-|+]{0,1}[0-9]+.*[0-9]+)/i.exec(query);
            if (splited !== null && splited.length > 0) {
                info.address = splited[1].replace(/^,s/g, "");
                info.markerName = splited[2];
                info.latitude = splited[3];
                info.longitude = splited[4];
            } else if (query.indexOf("@") >= 0) {
                splited = /(.*)@([-|+]{0,1}[0-9]+.*[0-9]+),([-|+]{0,1}[0-9]+.*[0-9]+)/i.exec(query);
                if (splited !== null && splited.length > 0) {
                    info.address = splited[1].replace(/^,\s/g, "");
                    info.latitude = splited[2];
                    info.longitude = splited[3];
                }
            } else {
                splited = /(.*)\((.*)\)/i.exec(query);
                if (splited !== null && splited.length > 0) {
                    info.address = splited[1].replace(/^,\s/g, "");
                    info.markerName = splited[2];
                } else {
                    info.address = query.replace(/^,\s/g, "");
                }
            }
        }
        return info;
    }

    /** Creates a marker and sets the click event*/
    function createMarker(point, mapInfo) {
        var marker = new GMarker(point);
        var html = mapInfo.infoWinHtml;
        if (mapInfo.markerName) {
            html = html.replace("[name]", mapInfo.markerName);
        } else {
            html = html.replace("<strong>[name]</strong><br/>", mapInfo.markerName);
        }
        if (mapInfo.address !== null) {
            html = html.replace("[address]", mapInfo.address);
        } else {
            html = html.replace("[address]", "");
        }
        if (html !== null && html.length > 0) {
            GEvent.addListener(marker, "click", function() {
              marker.openInfoWindowHtml(html);
            });
        }
        return marker;
    }

    /** Default configuration .*/
    $.fn.google.defaults = {
        container : null,
        markerName : "",
        infoWinHtml : '<div style="font-family: Arial;height: 100px;width: 230px;"><strong>[name]</strong><br/>[address]</div>',
        openInfoWin : true,
        latitude : null,
        longitude : null,
        address : null,
        query : null,
        zoom : null
    };

})(jQuery);

