var Location = (function() {

    var map,geoCoder;


    var initMap = function (options) {

        map = new google.maps.Map(document.getElementById("location_map"), {
            zoom: options.zoom,
            center: new google.maps.LatLng(options.lat, options.lng),
            mapTypeId: google.maps.MapTypeId.ROADMAP
        });

        google.maps.event.addListener(map, "zoom_changed", function(){
            var zoom =  map.getZoom();
            if (zoom) {
                $('[id$="zoom"]').val(zoom);
            }
        });

        var marker = setMarker(map, options);


        geoCoder = new google.maps.Geocoder(map);

        $('[id$="address"]').on("change", function(){
            var address = $.trim($(this).val());

            if (address !== "") {
                var request = { address : $(this).val() };

                geoCoder.geocode(request, function( result, status ) {
                    if( status === google.maps.GeocoderStatus.OK ) {
                        result = result[0];
                        map.setCenter(result.geometry.location);
                        setMarkerPosition(marker, {
                            lat: result.geometry.location.lat,
                            lng: result.geometry.location.lng
                        });
                        updateEntity(result);
                    }
                });
            }
        });
    };

    var setMarker = function(map, options) {
        var marker = new google.maps.Marker({
            map: map,
            position: new google.maps.LatLng(options.lat, options.lng),
            draggable:true,
            animation: google.maps.Animation.DROP
        });

        marker.addListener('dragend', function(event){
            geoCoder.geocode({"location": event.latLng }, function( result, status ) {
                if( status === google.maps.GeocoderStatus.OK ) {
                    updateEntity(result[0]);
                }
            });
        });

        return marker;
    };

    var updateEntity = function(result) {
        var data = parseAddressComponents(result.address_components);

        $('[id$="address"]').val(result.formatted_address);
        $('[id$="data"]').val('{"lat":'+result.geometry.location.lat()+',"lng":'+result.geometry.location.lng()+'}');

        $.ajax({
            url: Routing.generate("cs_admin_location_fetch_location_entity"),
            data: {gmData:data},
            method: "post",
            dataType: "json",
            async: false,
            success: function(response) {
                $('[id$="location"]').val(response.location);
            }
        });
    };

    var parseAddressComponents = function(addressComponents) {

        var data = {};

        for( var i = 0; i < addressComponents.length; i++ ) {
            for(var j = 0; j < addressComponents[i].types.length; j++ ){
                switch(addressComponents[i].types[j]) {
                    case 'street_number':
                        data.street_number = addressComponents[i].long_name;
                        break;
                    case 'postal_code':
                        data.postal_code =  addressComponents[i].long_name;
                        break;
                    case 'route':
                    case 'street_address':
                    case 'intersection':
                        data.address =  addressComponents[i].long_name;
                        break;
                    case 'locality':
                        data.locality =  addressComponents[i].long_name;
                        break;
                    case 'administrative_area_level_2':
                        data.province =  addressComponents[i].long_name;
                        break;
                    case 'administrative_area_level_1':
                        data.comunitat_autonoma =  addressComponents[i].short_name;
                        break;
                    case 'country':
                        data.country =  addressComponents[i].short_name;
                        break;
                    default:
                        break;
                }
            }
        }

        return data;
    };

    var setMarkerPosition = function(marker, options) {
        var latLng = new google.maps.LatLng(options.lat(), options.lng());

        marker.setPosition(latLng);

        return marker;
    };

    return {
        init: function(options) {
            initMap(options);
        }
    };
})();