var RomePosition = new google.maps.LatLng(41.54, 12.29); 

function GenericMapHandler(defaultErrorText, canvasId, zoomLevel, largeControl,
    enableMouseWheelZoom) {
    this.canvasId = canvasId;
    if(canvasId != null) {
        this.defaultErrorText = defaultErrorText;
        this.defaultZoomLevel = zoomLevel;
        this.map = new google.maps.Map2($(canvasId));

        if(largeControl)
            this.map.setUI(this.map.getDefaultUI());
        else
            this.map.addControl(new google.maps.SmallMapControl());

        if(!enableMouseWheelZoom)
            this.map.disableScrollWheelZoom();

        this.map.setCenter(RomePosition, zoomLevel);

        this.mgr = new MarkerManager(this.map);
    }

    this.markers = new Array();
}

GenericMapHandler.prototype.reset = function() {
    this.mgr.clearMarkers();
    this.map.setCenter(RomePosition, this.defaultZoomLevel);
}

GenericMapHandler.prototype.resetIcons = function() {
    for(var i = 0, l = this.markers.length; i < l; i++) {
        try {
            this.markers[i].resetIcon();
        } catch(e) {

        }
    }
}

/**
 *  Map handler per gestione mappe dei viaggi
 */
SnpGoogleMapHandler.prototype = new GenericMapHandler();
function SnpGoogleMapHandler(waitingText, defaultErrorText, canvasId, zoomLevel, largeControl) {
    CallParentConstructor(this, GenericMapHandler, defaultErrorText, canvasId, zoomLevel, largeControl);

    this.waitingText = waitingText;

    this.pastMarkers = new Array();
    this.futureMarkers = new Array();
}

SnpGoogleMapHandler.prototype.setPastMarkers = function(markers) {
    this.pastMarkers = markers;
}

SnpGoogleMapHandler.prototype.setFutureMarkers = function(markers) {
    this.futureMarkers = markers;
}

SnpGoogleMapHandler.prototype.showMarkers = function(future) {
    var markers = (future ? this.futureMarkers : this.pastMarkers);
    var markersArray = new Array();
    for(var i = 0; i < markers.length; i++) {
        var markerInfo = markers[i];
        var marker = new TravelMarker(this.waitingText, this.defaultErrorText, markerInfo);
        markersArray.push(marker);
    }
    this.mgr.clearMarkers();
    var ms = new MarkerSpreader(this.map);
    var spreadedMarkers = ms.spreadMarkers(markersArray);
    if(spreadedMarkers.length != 0) {
        this.mgr.addMarkers(spreadedMarkers, 0);
        this.mgr.refresh();
    }
}

/**
 *  Map handler per gestione mappe della galleria
 */
GalleryGoogleMapHandler.prototype = new GenericMapHandler();
function GalleryGoogleMapHandler(defaultErrorText, detailText, pictureByText, canvasId, zoomLevel, largeControl) {
    CallParentConstructor(this, GenericMapHandler, defaultErrorText, canvasId, zoomLevel, largeControl);
    this.detailText = detailText;
    this.pictureByText = pictureByText;
}

GalleryGoogleMapHandler.prototype.setMarkers = function(markers) {
    this.mgr.clearMarkers();
    var markersArray = new Array();
    for(var i = 0; i < markers.length; i++) {
        var markerInfo = markers[i];
        var marker = new GalleryMarker(this.defaultErrorText, this.detailText,
            this.pictureByText, markerInfo);
        markersArray.push(marker);
    }
    var ms = new MarkerSpreader(this.map);
    var spreadedMarkers = ms.spreadMarkers(markersArray);
    if(spreadedMarkers.length != 0) {
        this.mgr.addMarkers(spreadedMarkers, 0);
        this.mgr.refresh();
    }
}

/**
 *  Map handler per gestione top10
 */
Top10MapHandler.prototype = new GenericMapHandler();
function Top10MapHandler(userId, texts, labels, canvasId, baseUrl, zoomLevel,
    largeControl, preferredIconPath, listHandler) {

    CallParentConstructor(this, GenericMapHandler, texts.defaultErrorText, canvasId, zoomLevel, largeControl);

    this.userId = userId;
    this.texts = texts;
    this.labels = labels;
    this.baseUrl = baseUrl;
    this.preferredIconPath = preferredIconPath;
    this.listHandler = listHandler;

    this.markers = new Array();

    $(this.canvasId).mapHandler = this;
}

Top10MapHandler.prototype.deleteItemFailure = function(message) {
    new GeneralScript().showErrorMessage(message);
}

Top10MapHandler.prototype.doDeleteItem = function(transport) {
    var jsonText = transport.responseText;
    eval('jsonResp = ' + jsonText);
    if(jsonResp.code == 200) {
        this.updateMarkers();
        if(this.listHandler) this.listHandler.updateDetails(null);
    }
    else {
        if(jsonResp.msg) {
            this.deleteItemFailure(jsonResp.msg);
        }
        else {
            this.deleteItemFailure(this.texts.removeErrorText);
        }
    }
}

Top10MapHandler.prototype.deleteNode = function(nid) {
    var params = {
        'elementId' : nid
    };
    var me = this;
    AjaxRequest(this.baseUrl + '?page=AjaxDispatcher&class=topten&method=remove',
    {
        parameters : params,
        onSuccess: function(transport){
            me.doDeleteItem(transport);
        },
        onFailure: function(){
            me.deleteItemFailure(this.texts.removeErrorText);
        }
    });
}

Top10MapHandler.prototype.doChangeNodeType = function(transport) {
    var jsonText = transport.responseText;
    eval('jsonResp = ' + jsonText);
    if(jsonResp.code == 200) {
        this.updateMarkers();
    }
    else {
        if(jsonResp.msg) {
            this.deleteItemFailure(jsonResp.msg);
        }
        else {
            this.deleteItemFailure(this.texts.changeTypeErrorText);
        }
    }
}

Top10MapHandler.prototype.changeNodeType = function(nid, favourite) {
    var params = {
        'elementId' : nid,
        'favourite' : favourite
    };
    var me = this;
    AjaxRequest(this.baseUrl + '?page=AjaxDispatcher&class=topten&method=change',
    {
        parameters : params,
        onSuccess: function(transport){
            me.doChangeNodeType(transport);
        },
        onFailure: function(){
            me.deleteItemFailure(this.texts.changeTypeErrorText);
        }
    });
}

Top10MapHandler.prototype.doUpdateMarkers = function(transport) {
    var jsonText = transport.responseText;
    eval('jsonResp = ' + jsonText);
    if(jsonResp.code == 200) {
        var selNid = null;
        var selMarker = null;
        var markerInfo = null;
        for(var j = 0, ml = this.markers.length; j < ml; j++) {
            if(this.markers[j].isSelected()) {
                markerInfo = this.markers[j].getMarkerInfo();
                selNid = this.markers[j].getMarkerInfo().nid;
                break;
            }
        }
        this.mgr.clearMarkers();
        var topten = jsonResp.topten;
        var markersArray = new Array();
        for(var i = 0, l = topten.length; i < l; i++) {
            var opts = {
                title: topten[i].location
                };
            if(this.preferredIconPath) {
                var customIcon = null;
                var selectedIcon = null;
                if(topten[i].preferred) {
                    customIcon = new google.maps.Icon();
                    customIcon.shadow = this.preferredIconPath + "/images/ombra-preferiti.png";
                    customIcon.image = this.preferredIconPath + "/images/preferred.png";
                    customIcon.iconSize = new GSize(32, 32);
                    customIcon.shadowSize = new GSize(45, 32);
                    customIcon.iconAnchor = new GPoint(7, 30);
                    customIcon.infoWindowAnchor = new GPoint(16, 1);
                    opts = {
                        title : topten[i].location.replace(/(<([^>]+)>)/ig,""),
                        icon : customIcon
                    };
                    selectedIcon = "/images/preferred-over.png";
                }
                else {
                    customIcon = new google.maps.Icon();
                    customIcon.shadow = this.preferredIconPath + "/images/ombra-visitati.png";
                    customIcon.image = this.preferredIconPath + "/images/flagvisitati.png";
                    customIcon.iconSize = new GSize(33, 34);
                    customIcon.shadowSize = new GSize(48, 34);
                    customIcon.iconAnchor = new GPoint(3, 33);
                    customIcon.infoWindowAnchor = new GPoint(31, 4);
                    opts = {
                        title : topten[i].location.replace(/(<([^>]+)>)/ig,""),
                        icon : customIcon
                    };
                    selectedIcon = "/images/flagvisitati-over.png";
                }                
            }
            
            var marker = new UserTopTenMarker(this.preferredIconPath, this,
                this.canvasId, this.texts.defaultErrorText, this.labels, topten[i],
                selectedIcon, opts, this.listHandler);
            if(topten[i].nid == selNid)
                selMarker = marker;
            markersArray.push(marker);
        }
        var ms = new MarkerSpreader(this.map);
        this.markers = ms.spreadMarkers(markersArray);
        if(this.markers.length != 0) {
            this.mgr.addMarkers(this.markers, 0);
            this.mgr.refresh();
            if(selMarker) {
                selMarker.selectMarker(true);
            }
        }

        if(this.listHandler && selMarker) this.listHandler.updateDetailsInfo(selMarker.getMarkerInfo());
    }
    else {
        
}
}

Top10MapHandler.prototype.updateMarkers = function() {
    var me = this;
    var params = {
        'user' : this.userId
        };
    AjaxRequest(me.baseUrl + '?page=AjaxDispatcher&class=topten&method=update',
    {
        parameters: params,
        onSuccess: function(transport){
            me.doUpdateMarkers(transport);
        },
        onFailure: function(){
            
        }
    });
}

/**
 *  Map handler per gestione dettaglio foto
 */
PhotoMapHandler.prototype = new GenericMapHandler();
function PhotoMapHandler(defaultErrorText, locationLabel, canvasId, zoomLevel, largeControl) {
    CallParentConstructor(this, GenericMapHandler, defaultErrorText, canvasId, zoomLevel, largeControl);

    this.locationLabel = locationLabel;
}

PhotoMapHandler.prototype.setMarker = function (markerInfo) {
    this.mgr.clearMarkers();
    var marker = new PhotoMapMarker(this.defaultErrorText,
        this.locationLabel, markerInfo);
    this.mgr.addMarker(marker, 0);
    this.mgr.refresh();
    marker.showPopup();
}

/**
 * Map handler per gestione Destinazioni
 */
PlacesMapHandler.prototype = new GenericMapHandler();
function PlacesMapHandler(defaultErrorText, locationLabel, canvasId, iconsPath,
    mapHandler, zoomLevel, largeControl) {
    CallParentConstructor(this, GenericMapHandler, defaultErrorText, canvasId, zoomLevel, largeControl, false);

    this.locationLabel = locationLabel;
    this.iconsPath = iconsPath;
    this.mapHandler = mapHandler;
    this.visitedMarkers = new Array();
    this.favouritesMarkers = new Array();
    this.suggestedMarkers = new Array();
    
}

PlacesMapHandler.prototype.markerSelected = function(markerInfo) {
    this.mapHandler.markerSelected(markerInfo);
}

PlacesMapHandler.prototype.selectPosition = function(position) {
    this.markers[position].showPopup();
}

PlacesMapHandler.prototype.createMarkers = function(markersInfo, type, shadowIcon) {
    var markers = new Array();
    for(var i = 0; i < markersInfo.length; i++) {
        var markerInfo = markersInfo[i].info;
        markerInfo.lat = markersInfo[i].extinfo.latlng[0];
        markerInfo.lng = markersInfo[i].extinfo.latlng[1];
        markerInfo.south = markersInfo[i].extinfo.bb[0];
        markerInfo.east = markersInfo[i].extinfo.bb[1];
        markerInfo.north = markersInfo[i].extinfo.bb[2];
        markerInfo.west = markersInfo[i].extinfo.bb[3];
        markerInfo.location = markersInfo[i].extinfo.label;
        var opts = null;
        if((i + 1) <= 10) {
            var customIcon = new google.maps.Icon();
            customIcon.shadow = this.iconsPath + shadowIcon;
            
            var selectedIcon = null;
            
            if (type == 'visited') {
                customIcon.image = this.iconsPath + "/images/marker-visitati-" + (i + 1) + ".png";
                customIcon.iconSize = new GSize(33, 34);
                customIcon.shadowSize = new GSize(48, 32);
                customIcon.iconAnchor = new GPoint(3, 33);
                customIcon.infoWindowAnchor = new GPoint(31, 4);
                selectedIcon = "/images/flagvisitati-over.png";            	
            }
            else if (type == 'preferred') {
                customIcon.image = this.iconsPath + "/images/marker-preferiti-" + (i + 1) + ".png";
                customIcon.iconSize = new GSize(32, 32);
                customIcon.shadowSize = new GSize(36, 32);
                customIcon.iconAnchor = new GPoint(7, 30);
                customIcon.infoWindowAnchor = new GPoint(16, 1);
                selectedIcon = "/images/preferred-over.png";            	
            }
            else if (type == 'suggested') {
                customIcon.image = this.iconsPath + "/images/marker-suggeriti.png";
                customIcon.iconSize = new GSize(34, 34);
                customIcon.shadowSize = new GSize(40, 34);
                customIcon.iconAnchor = new GPoint(16, 32);
                customIcon.infoWindowAnchor = new GPoint(24, 2);
                selectedIcon = "/images/suggested-over.png";
            }	

            opts = {
                title : markerInfo.location.replace(/(<([^>]+)>)/ig,""),
                icon : customIcon
            };

            var marker = new PlacesMapMarker(this.iconsPath, this.defaultErrorText,
                this.locationLabel, this, markerInfo, selectedIcon, opts);
            markers.push(marker);
        }
        
    }
    return markers;
}

PlacesMapHandler.prototype.setVisitedMarkers = function(markersInfo) {
    this.visitedMarkers = this.createMarkers(markersInfo, 'visited', "/images/ombra-visitati.png");
}

PlacesMapHandler.prototype.setFavouritesMarkers = function(markersInfo) {
    this.favouritesMarkers = this.createMarkers(markersInfo, 'preferred', "/images/ombra-preferiti.png");
}

PlacesMapHandler.prototype.setSuggestedMarkers = function(markersInfo) {
    this.suggestedMarkers = this.createMarkers(markersInfo, 'suggested', "/images/ombra-suggeriti.png");
}

PlacesMapHandler.prototype.updateMarkers = function(type) {
    if (type == 'visited') {
        this.markers = this.visitedMarkers;
        this.showVisitedMarkers();
    }
    else if (type == 'preferred') {
        this.markers = this.favouritesMarkers;
        this.showFavouritesMarkers();
    }
    else if (type == 'suggested') {
        this.markers = this.suggestedMarkers;
        this.showSuggestedMarkers();
    }
}

PlacesMapHandler.prototype.showVisitedMarkers = function() {
    this.mgr.clearMarkers();
    this.mgr.addMarkers(this.visitedMarkers, 0);
    this.mgr.refresh();
}

PlacesMapHandler.prototype.showFavouritesMarkers = function() {
    this.mgr.clearMarkers();
    this.mgr.addMarkers(this.favouritesMarkers, 0);
    this.mgr.refresh();
}

PlacesMapHandler.prototype.showSuggestedMarkers = function() {
    this.mgr.clearMarkers();
    this.mgr.addMarkers(this.suggestedMarkers, 0);
    this.mgr.refresh();
}


/**
 * MapHandler per gestire il picker di indirizzi
 */
AddressMapHandler.prototype = new GenericMapHandler();
function AddressMapHandler(
    defaultErrorText, addressNotFoundErrorText, outOfCountryErrorText,
    canvasId, baseUrl, zoomLevel, largeControl,
    iconType, iconPreferredPath, input,
    selectedNationField, selectedDistrictField, selectedProvinceField, selectedCityField,
    selectedLatitudeField, selectedLongitudeField,
    selectedSouthField, selectedEastField, selectedNorthField, selectedWestField,
    waitingPanelId) {
    CallParentConstructor(this, GenericMapHandler, defaultErrorText, canvasId, zoomLevel, largeControl, true);
    
    this.addressNotFoundErrorText = addressNotFoundErrorText;
    this.outOfCountryErrorText = outOfCountryErrorText;
    
    this.clickHandler =  null;
    
    this.baseUrl = baseUrl;
    this.geocoder = new google.maps.ClientGeocoder();
    this.iconType = iconType;        	
    this.iconPreferredPath = iconPreferredPath;
    this.input_field = $(input);
    this.nation_field = $(selectedNationField);
    this.district_field = $(selectedDistrictField);
    this.province_field = $(selectedProvinceField);
    this.city_field = $(selectedCityField);
    this.latitude_field = $(selectedLatitudeField);
    this.longitude_field = $(selectedLongitudeField);
    this.south_field = $(selectedSouthField);
    this.east_field = $(selectedEastField);
    this.north_field = $(selectedNorthField);
    this.west_field = $(selectedWestField);
    this.waitingPanel = $(waitingPanelId);
    
    this.resetFields(true);
}

/** getIcon() returns the GoogleMaps icon
 *  answer. 
 */ 
AddressMapHandler.prototype.getIcon = function() {
    var customIcon = null;

    switch (this.iconType) {
        case 'visitati':
            customIcon = new google.maps.Icon();
            customIcon.shadow = this.iconPreferredPath + '/images/ombra-visitati.png';
            customIcon.image = this.iconPreferredPath + "/images/flagvisitati.png";
            customIcon.iconSize = new GSize(33, 34);
            customIcon.shadowSize = new GSize(48, 34);
            customIcon.iconAnchor = new GPoint(3, 33);
            customIcon.infoWindowAnchor = new GPoint(31, 4);
        default:
            break;
    }
    
    return customIcon;
}

AddressMapHandler.prototype.showError = function(errorMessage) {
    var gs = new GeneralScript();
    if(this.waitingPanel) gs.hideComponent(this.waitingPanel);
    gs.showErrorMessage(errorMessage);
}

/** AddressToMap() is called when the geocoder returns an
 *  answer. 
 */ 
AddressMapHandler.prototype.AddressToMap = function(response) {
    this.resetFields(false);
	
    if (!response || response.Status.code != 200) {
        this.showError(this.addressNotFoundErrorText);		
    } else {
        try {
            var place = null;
            var point =  null;
            var countryCode = null;

            for(var i = 0; i < response.Placemark.length; i++) {
                if("IT" == countryCode) {
                    break;
                }
                place = null;
                point =  null;
                countryCode = null;
                try {
                    place = response.Placemark[i];
                    point = new GLatLng(place.Point.coordinates[1], place.Point.coordinates[0]);
                    countryCode = place.AddressDetails.Country.CountryNameCode;
                } catch(e) { }
            }
            if(countryCode == null) {
                throw "No country code";
            }

            if (countryCode!="IT") {
                this.showError(this.outOfCountryErrorText);
            } else {
//                var postalCode = "";
//                try {
//                    postalCode = place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.PostalCode.PostalCodeNumber;
//                } catch (e) { }

                try {
                    var south = place.ExtendedData.LatLonBox.south;
                    var east = place.ExtendedData.LatLonBox.east;
                    var north = place.ExtendedData.LatLonBox.north;
                    var west = place.ExtendedData.LatLonBox.west;
                    var bounds = new GLatLngBounds(new GLatLng(south, west), new GLatLng(north, east));
                    this.map.setCenter(bounds.getCenter(), this.map.getBoundsZoomLevel(bounds));

                    this.south_field.setValue(south);
                    this.east_field.setValue(east);
                    this.north_field.setValue(north);
                    this.west_field.setValue(west);
                } catch (e) {
                    this.map.setCenter(point);
                }

                var location = place.address;
                var country = '';
                try {
                    country = place.AddressDetails.Country.CountryNameCode;
                } catch(e){}
                var region = '';
                try {
                    region = place.AddressDetails.Country.AdministrativeArea.AdministrativeAreaName;
                } catch(e){}
                var prov = '';
                try {
                    prov = place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.SubAdministrativeAreaName;
                } catch(e){}
                var locality = '';
                try {
                    locality = place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.LocalityName;
                } catch(e){}
//                var address = place.address;

                var params = {
                    'country':country,
                    'region':region,
                    'prov':prov,
                    'locality':locality
                };
                var me = this;
                AjaxRequest(this.baseUrl + '?page=AjaxDispatcher&class=map&method=placesToIds',
                {
                    parameters : params,
                    onSuccess: function(transport){
                        me.updatePlaceFields(transport);
                    },
                    onFailure: function(){
                        me.showError(me.defaultErrorText);
                    }
                });
                this.input_field.setValue(location);
                this.latitude_field.setValue(place.Point.coordinates[1]);
                this.longitude_field.setValue(place.Point.coordinates[0]);
                var opts = {
                    title : location.replace(/(<([^>]+)>)/ig,""),
                    icon : this.getIcon()
                    };
                var marker = new PhotoMapMarker(this.defaultErrorText, '',
                {
                    'location':location,
                    'lat':place.Point.coordinates[1],
                    'lng':place.Point.coordinates[0]
                    },
                opts);
                this.mgr.addMarker(marker, 0);
                this.mgr.refresh();
                setTimeout(function() {
                    marker.showPopup();
                }, 10);
            }
        } catch (e) {
            this.showError(this.addressNotFoundErrorText);
        }
    }
}

/** ClickToMap() is called when the user clicks on the map
 */ 
AddressMapHandler.prototype.ClickToMap = function(response) {
    this.resetFields(false);
    if (!response || response.Status.code != 200) {
        this.showError(this.addressNotFoundErrorText);
    } else {
        var place = response.Placemark[0];
        var point = new GLatLng(place.Point.coordinates[1],
            place.Point.coordinates[0]);
        var countryCode = place.AddressDetails.Country.CountryNameCode;
		
        if (countryCode!="IT") {
            this.showError(this.outOfCountryErrorText);
        } else {
            //			var postalCode = "";
            //         try {
            //				postalCode = place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.PostalCode.PostalCodeNumber;
            //			} catch (e) { }
			
            try {
                var south = place.ExtendedData.LatLonBox.south;
                var east = place.ExtendedData.LatLonBox.east;
                var north = place.ExtendedData.LatLonBox.north;
                var west = place.ExtendedData.LatLonBox.west;
                //var bounds = new GLatLngBounds(new GLatLng(south, west), new GLatLng(north, east));
				
                this.south_field.setValue(south);
                this.east_field.setValue(east);
                this.north_field.setValue(north);
                this.west_field.setValue(west);
            } catch (e) {
            //this.map.setCenter(point);
            }
			
            var location = place.address;
            var country = -1;
            try {
                country = place.AddressDetails.Country.CountryNameCode;
            } catch(e){ }
            var region = -1;
            try{
                region = place.AddressDetails.Country.AdministrativeArea.AdministrativeAreaName;
            } catch(e){ }
            var prov = -1;
            try {
                prov = place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.SubAdministrativeAreaName;
            } catch(e){ }
            var locality = -1;
            try {
                locality = place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.LocalityName;
            } catch(e){ }
            //			var address = "";
            //            try {
            //                address = place.address;
            //            } catch(e){ }

            var params = {
                'country':country,
                'region':region,
                'prov':prov,
                'locality':locality
            };
            var me = this;
            AjaxRequest(this.baseUrl + '?page=AjaxDispatcher&class=map&method=placesToIds',
            {
                parameters : params,
                onSuccess: function(transport){
                    me.updatePlaceFields(transport);
                },
                onFailure: function(){
                    me.showError(me.defaultErrorText);
                }
            });
						
            this.input_field.setValue(location);
            this.latitude_field.setValue(place.Point.coordinates[1]);
            this.longitude_field.setValue(place.Point.coordinates[0]);
			
            var opts = {
                title : location.replace(/(<([^>]+)>)/ig, ""),
                icon : this.getIcon()
                };
			
            var marker = new PhotoMapMarker(
                this.defaultErrorText, '',
                {
                    'location':location,
                    'lat':place.Point.coordinates[1],
                    'lng':place.Point.coordinates[0]
                    },
                opts);
            this.mgr.addMarker(marker, 0);
            this.mgr.refresh();
            setTimeout(function() {
                marker.showPopup();
            }, 10);
        }
    }
}

/** showLocation() is called when you click on the Search button
 *  in the form.  It geocodes the address entered into the form
 *  and adds a marker to the map at that location.
 */  
AddressMapHandler.prototype.showLocation = function() {
    var address = this.input_field.getValue() + ", Italia";
    if (address) {
        var me = this;
        if(this.waitingPanel) new GeneralScript().showComponent(this.waitingPanel);
        this.geocoder.getLocations(address, function(response) { 
            me.AddressToMap(response);
        });
    }
}

/** findLocation() is used to enter the sample addresses into the form.
 * 
 * @param address
 * @return
 */
AddressMapHandler.prototype.findLocation = function(address) {
    this.input_field.setValue(address);
    this.showLocation();
}


/** redraw() is used when the map is translated over the page.
 * 
 * @return
 */
AddressMapHandler.prototype.redraw = function(address) {
    this.resetFields(true);
}

/** resetFields() is used when the map is translated over the page.
 * 
 * @return
 */
AddressMapHandler.prototype.resetFields = function(recenter) {
    if(this.waitingPanel) new GeneralScript().hideComponent(this.waitingPanel);
    // Elimino i markers
    this.mgr.clearMarkers();
	
    this.input_field.disabled = false;
	
    // Resetto i campi
    this.resetValues(true);
	
    // Centro la mappa su Roma e setto lo zoomLevel di default
    if (recenter) {
        this.map.checkResize();
        this.map.setCenter(RomePosition, this.defaultZoomLevel);
    }

    try {
        this.input_field.focus();
    } catch(e){}
	
    var me = this;
    if(this.clickHandler == null) {
        this.clickHandler = GEvent.addListener(this.map, "click", function(overlay,latlng) {
            if (latlng) {
                new GeneralScript().showComponent(me.waitingPanel);
                me.geocoder.getLocations(latlng, function(response) {
                    me.ClickToMap(response);
                });
            }
        });
    }
}

AddressMapHandler.prototype.restoreFields = function() {
    // recupero valori
    try {
        this.nation_field.value = this.nation_field.old_value;
        this.district_field.value = this.district_field.old_value;
        this.province_field.value = this.province_field.old_value;
        this.city_field.value = this.city_field.old_value;
        this.latitude_field.value = this.latitude_field.old_value;
        this.longitude_field.value = this.longitude_field.old_value;
        this.south_field.value = this.south_field.old_value;
        this.east_field.value = this.east_field.old_value;
        this.north_field.value = this.north_field.old_value;
        this.west_field.value = this.west_field.old_value;
        this.input_field.value = this.input_field.old_value;
    } catch(e){}
}

AddressMapHandler.prototype.resetValues = function(resetText) {
    // backup dei valori
    this.nation_field.old_value = this.nation_field.value;
    this.district_field.old_value = this.district_field.value;
    this.province_field.old_value = this.province_field.value;
    this.city_field.old_value = this.city_field.value;
    this.latitude_field.old_value = this.latitude_field.value;
    this.longitude_field.old_value = this.longitude_field.value;
    this.south_field.old_value = this.south_field.value;
    this.east_field.old_value = this.east_field.value;
    this.north_field.old_value = this.north_field.value;
    this.west_field.old_value = this.west_field.value;
    this.input_field.old_value = this.input_field.value;

    // Resetto i campi
    this.nation_field.setValue('-1');
    this.district_field.setValue('-1');
    this.province_field.setValue('-1');
    this.city_field.setValue('-1');
    this.latitude_field.setValue('-1');
    this.longitude_field.setValue('-1');
    this.south_field.setValue('-1');
    this.east_field.setValue('-1');
    this.north_field.setValue('-1');
    this.west_field.setValue('-1');

//    if(resetText) {
//        this.input_field.setValue('');
//    }
}

/** updatePlaceFields() is used to replace locality fields in to the form
 * 
 * @param transport
 * @return
 */
AddressMapHandler.prototype.updatePlaceFields = function(transport) {
    if(this.waitingPanel) new GeneralScript().hideComponent(this.waitingPanel);
    var jsonText = transport.responseText;
    eval('jsonResp = ' + jsonText);
    if(jsonResp.code == 200) {        
        this.nation_field.setValue(jsonResp.country);
        this.district_field.setValue(jsonResp.region);
        this.province_field.setValue(jsonResp.prov);
        this.city_field.setValue(jsonResp.locality);         
    }
    else {
        this.nation_field.setValue(-1);
        this.district_field.setValue(-1);
        this.province_field.setValue(-1);
        this.city_field.setValue(-1);

        if(jsonResp.msg) {
            this.showError(jsonResp.msg);
        }
        else {
            this.showError(this.defaultErrorText);
        }
    }
}

/**
 * Sets the info for the picker.
 *
 * @param details The details object containing the predefined info to
 * be set on the picker.
 * @param showPopup An optional boolean switch to show a popup on the marker.
 * @return
 */
AddressMapHandler.prototype.setInfo = function(details, showPopup) {
    this.resetFields(false);
	
    if (!details.editable) {
        this.input_field.onblur = null;
        this.input_field.disabled = true;
        if(this.clickHandler) GEvent.removeListener(this.clickHandler);
        this.clickHandler = null;
    }
		
    this.input_field.setValue(details.label);
    this.district_field.setValue(details.location[0]);
    this.province_field.setValue(details.location[1]);
    this.city_field.setValue(details.location[2]);    
    this.latitude_field.setValue(details.latlng[0]);
    this.longitude_field.setValue(details.latlng[1]);
    this.south_field.setValue(details.bb[0]);
    this.east_field.setValue(details.bb[1]);
    this.north_field.setValue(details.bb[2]);
    this.west_field.setValue(details.bb[3]);
    
    var bounds = new GLatLngBounds(
        new GLatLng(details.bb[0], details.bb[3]),
        new GLatLng(details.bb[2], details.bb[1]));
    
    opts = {
        'title' : details.label.replace(/(<([^>]+)>)/ig,""),
        'icon' : this.getIcon()
        };

    var marker = new PhotoMapMarker(
        this.defaultErrorText, '',
        {
            'location':details.label,
            'lat':details.latlng[0],
            'lng':details.latlng[1]
            },
        opts);
    this.mgr.addMarker(marker, 0);
    this.mgr.refresh();
    if(showPopup) setTimeout(function() {
        marker.showPopup();
    }, 100);
    this.map.setCenter(marker.getLatLng(), this.map.getBoundsZoomLevel(bounds));

}

/*
 * Address Map Handler for Destinations
 **/

AddressMapDestination.prototype = new GenericMapHandler();
function AddressMapDestination(
    defaultErrorText, addressNotFoundErrorText, outOfCountryErrorText,
    canvasId, baseUrl, zoomLevel, largeControl,
    iconType, iconPreferredPath, input, galleryPanelID, recipesPanelID, advicesPanelID,
    selectedNationField, selectedDistrictField, selectedProvinceField, selectedCityField,
    selectedLatitudeField, selectedLongitudeField,
    selectedSouthField, selectedEastField, selectedNorthField, selectedWestField,
    waitingPanelId) {
    CallParentConstructor(this, GenericMapHandler, defaultErrorText, canvasId, zoomLevel, largeControl, true);

    this.addressNotFoundErrorText = addressNotFoundErrorText;
    this.outOfCountryErrorText = outOfCountryErrorText;

    this.clickHandler =  null;

    this.baseUrl = baseUrl;
    this.geocoder = new google.maps.ClientGeocoder();
    this.iconType = iconType;
    this.iconPreferredPath = iconPreferredPath;
    this.input_field = $(input);
    this.nation_field = $(selectedNationField);
    this.district_field = $(selectedDistrictField);
    this.province_field = $(selectedProvinceField);
    this.city_field = $(selectedCityField);
    this.latitude_field = $(selectedLatitudeField);
    this.longitude_field = $(selectedLongitudeField);
    this.south_field = $(selectedSouthField);
    this.east_field = $(selectedEastField);
    this.north_field = $(selectedNorthField);
    this.west_field = $(selectedWestField);
    this.waitingPanel = $(waitingPanelId);

    this.photoPanel = $(galleryPanelID);
    this.recipesPanel = $(recipesPanelID);
    this.advicesPanel = $(advicesPanelID);
    
    this.resetFields(true);
}

/** getIcon() returns the GoogleMaps icon
 *  answer.
 */
AddressMapDestination.prototype.getIcon = function() {
    var customIcon = null;

    switch (this.iconType) {
        case 'visitati':
            customIcon = new google.maps.Icon();
            customIcon.shadow = this.iconPreferredPath + '/images/ombra-visitati.png';
            customIcon.image = this.iconPreferredPath + "/images/flagvisitati.png";
            customIcon.iconSize = new GSize(33, 34);
            customIcon.shadowSize = new GSize(48, 34);
            customIcon.iconAnchor = new GPoint(3, 33);
            customIcon.infoWindowAnchor = new GPoint(31, 4);
        default:
            break;
    }

    return customIcon;
}

AddressMapDestination.prototype.showError = function(errorMessage) {
    var gs = new GeneralScript();
    if(this.waitingPanel) gs.hideComponent(this.waitingPanel);
    gs.showErrorMessage(errorMessage);
}

/** AddressToMap() is called when the geocoder returns an
 *  answer.
 */
AddressMapDestination.prototype.AddressToMap = function(response) {
    this.resetFields(false);

    if (!response || response.Status.code != 200) {
        this.showError(this.addressNotFoundErrorText);
    } else {
        try {
            var place = null;
            var point =  null;
            var countryCode = null;

            for(var i = 0; i < response.Placemark.length; i++) {
                if("IT" == countryCode) {
                    break;
                }
                place = null;
                point =  null;
                countryCode = null;
                try {
                    place = response.Placemark[i];
                    point = new GLatLng(place.Point.coordinates[1], place.Point.coordinates[0]);
                    countryCode = place.AddressDetails.Country.CountryNameCode;
                } catch(e) { }
            }
            if(countryCode == null) {
                throw "No country code";
            }

            if (countryCode!="IT") {
                this.showError(this.outOfCountryErrorText);
            } else {
//                var postalCode = "";
//                try {
//                    postalCode = place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.PostalCode.PostalCodeNumber;
//                } catch (e) { }

                try {
                    var south = place.ExtendedData.LatLonBox.south;
                    var east = place.ExtendedData.LatLonBox.east;
                    var north = place.ExtendedData.LatLonBox.north;
                    var west = place.ExtendedData.LatLonBox.west;
                    var bounds = new GLatLngBounds(new GLatLng(south, west), new GLatLng(north, east));
                    this.map.setCenter(bounds.getCenter(), this.map.getBoundsZoomLevel(bounds));

                    this.south_field.setValue(south);
                    this.east_field.setValue(east);
                    this.north_field.setValue(north);
                    this.west_field.setValue(west);
                } catch (e) {
                    this.map.setCenter(point);
                }

                var location = place.address;
                var country = '';
                try {
                    country = place.AddressDetails.Country.CountryNameCode;
                } catch(e){}
                var region = '';
                try {
                    region = place.AddressDetails.Country.AdministrativeArea.AdministrativeAreaName;
                } catch(e){}
                var prov = '';
                try {
                    prov = place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.SubAdministrativeAreaName;
                } catch(e){}
                var locality = '';
                try {
                    locality = place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.LocalityName;
                } catch(e){}
//                var address = place.address;

                var params = {
                    'country':country,
                    'region':region,
                    'prov':prov,
                    'locality':locality
                };
                
                var me = this;
                AjaxRequest(this.baseUrl + '?page=AjaxDispatcher&class=map&method=placesToIds',
                {
                    parameters : params,
                    onSuccess: function(transport){
                        me.updatePlaceFields(transport);
                        me.updateGalleryPhoto();
                        me.updateRecipes();
                        me.updateAdvices();
                    },
                    onFailure: function(){
                        me.showError(me.defaultErrorText);
                    }
                });
                this.input_field.setValue(location);
                this.latitude_field.setValue(place.Point.coordinates[1]);
                this.longitude_field.setValue(place.Point.coordinates[0]);
                var opts = {
                    title : location.replace(/(<([^>]+)>)/ig,""),
                    icon : this.getIcon()
                    };
                var marker = new PhotoMapMarker(this.defaultErrorText, '',
                {
                    'location':location,
                    'lat':place.Point.coordinates[1],
                    'lng':place.Point.coordinates[0]
                    },
                opts);
                this.mgr.addMarker(marker, 0);
                this.mgr.refresh();
                setTimeout(function() {
                    marker.showPopup();
                }, 10);
            }
        } catch (e) {
            this.showError(this.addressNotFoundErrorText);
        }
    }
}

/** ClickToMap() is called when the user clicks on the map
 */
AddressMapDestination.prototype.ClickToMap = function(response) {
    this.resetFields(false);
    if (!response || response.Status.code != 200) {
        this.showError(this.addressNotFoundErrorText);
    } else {
        var place = response.Placemark[0];
        var point = new GLatLng(place.Point.coordinates[1],
            place.Point.coordinates[0]);
        var countryCode = place.AddressDetails.Country.CountryNameCode;

        if (countryCode!="IT") {
            this.showError(this.outOfCountryErrorText);
        } else {
            //			var postalCode = "";
            //         try {
            //				postalCode = place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.PostalCode.PostalCodeNumber;
            //			} catch (e) { }

            try {
                var south = place.ExtendedData.LatLonBox.south;
                var east = place.ExtendedData.LatLonBox.east;
                var north = place.ExtendedData.LatLonBox.north;
                var west = place.ExtendedData.LatLonBox.west;
                //var bounds = new GLatLngBounds(new GLatLng(south, west), new GLatLng(north, east));

                this.south_field.setValue(south);
                this.east_field.setValue(east);
                this.north_field.setValue(north);
                this.west_field.setValue(west);
            } catch (e) {
            //this.map.setCenter(point);
            }

            var location = place.address;
            var country = -1;
            try {
                country = place.AddressDetails.Country.CountryNameCode;
            } catch(e){ }
            var region = -1;
            try{
                region = place.AddressDetails.Country.AdministrativeArea.AdministrativeAreaName;
            } catch(e){ }
            var prov = -1;
            try {
                prov = place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.SubAdministrativeAreaName;
            } catch(e){ }
            var locality = -1;
            try {
                locality = place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.LocalityName;
            } catch(e){ }
            //			var address = "";
            //            try {
            //                address = place.address;
            //            } catch(e){ }

            var params = {
                'country':country,
                'region':region,
                'prov':prov,
                'locality':locality
            };
            
            var me = this;
            AjaxRequest(this.baseUrl + '?page=AjaxDispatcher&class=map&method=placesToIds',
            {
                parameters : params,
                onSuccess: function(transport){
                    me.updatePlaceFields(transport);
                    me.updateGalleryPhoto();
                    me.updateRecipes()
                    me.updateAdvices();
                },
                onFailure: function(){
                    me.showError(me.defaultErrorText);
                }
            });

            this.input_field.setValue(location);
            this.latitude_field.setValue(place.Point.coordinates[1]);
            this.longitude_field.setValue(place.Point.coordinates[0]);

            var opts = {
                title : location.replace(/(<([^>]+)>)/ig, ""),
                icon : this.getIcon()
                };

            var marker = new PhotoMapMarker(
                this.defaultErrorText, '',
                {
                    'location':location,
                    'lat':place.Point.coordinates[1],
                    'lng':place.Point.coordinates[0]
                    },
                opts);
            this.mgr.addMarker(marker, 0);
            this.mgr.refresh();
            setTimeout(function() {
                marker.showPopup();
            }, 10);
        }
    }
}

/** showLocation() is called when you click on the Search button
 *  in the form.  It geocodes the address entered into the form
 *  and adds a marker to the map at that location.
 */
AddressMapDestination.prototype.showLocation = function() {
    var address = this.input_field.getValue();
    if (address) {
        var me = this;
        if(this.waitingPanel) new GeneralScript().showComponent(this.waitingPanel);
        this.geocoder.getLocations(address, function(response) {
            me.AddressToMap(response);
        });
    }
}

/** findLocation() is used to enter the sample addresses into the form.
 *
 * @param address
 * @return
 */
AddressMapDestination.prototype.findLocation = function(address) {
    this.input_field.setValue(address);
    this.showLocation();
}


/** redraw() is used when the map is translated over the page.
 *
 * @return
 */
AddressMapDestination.prototype.redraw = function(address) {
    this.resetFields(true);
}

/** resetFields() is used when the map is translated over the page.
 *
 * @return
 */
AddressMapDestination.prototype.resetFields = function(recenter) {
    if(this.waitingPanel) new GeneralScript().hideComponent(this.waitingPanel);
    // Elimino i markers
    this.mgr.clearMarkers();

    this.input_field.disabled = false;

    // Resetto i campi
    this.resetValues(true);

    // Centro la mappa su Roma e setto lo zoomLevel di default
    if (recenter) {
        this.map.checkResize();
        this.map.setCenter(RomePosition, this.defaultZoomLevel);
    }

//    try {
//        this.input_field.focus();
//    } catch(e){}

    var me = this;
    if(this.clickHandler == null) {
        this.clickHandler = GEvent.addListener(this.map, "click", function(overlay,latlng) {
            if (latlng) {
                new GeneralScript().showComponent(me.waitingPanel);
                me.geocoder.getLocations(latlng, function(response) {
                    me.ClickToMap(response);
                });
            }
        });
    }
}

AddressMapDestination.prototype.restoreFields = function() {
    // recupero valori
    try {
        this.nation_field.value = this.nation_field.old_value;
        this.district_field.value = this.district_field.old_value;
        this.province_field.value = this.province_field.old_value;
        this.city_field.value = this.city_field.old_value;
        this.latitude_field.value = this.latitude_field.old_value;
        this.longitude_field.value = this.longitude_field.old_value;
        this.south_field.value = this.south_field.old_value;
        this.east_field.value = this.east_field.old_value;
        this.north_field.value = this.north_field.old_value;
        this.west_field.value = this.west_field.old_value;
        this.input_field.value = this.input_field.old_value;
    } catch(e){}
}

AddressMapDestination.prototype.resetValues = function(resetText) {
    // backup dei valori
    this.nation_field.old_value = this.nation_field.value;
    this.district_field.old_value = this.district_field.value;
    this.province_field.old_value = this.province_field.value;
    this.city_field.old_value = this.city_field.value;
    this.latitude_field.old_value = this.latitude_field.value;
    this.longitude_field.old_value = this.longitude_field.value;
    this.south_field.old_value = this.south_field.value;
    this.east_field.old_value = this.east_field.value;
    this.north_field.old_value = this.north_field.value;
    this.west_field.old_value = this.west_field.value;
    this.input_field.old_value = this.input_field.value;

    // Resetto i campi
    this.nation_field.setValue('-1');
    this.district_field.setValue('-1');
    this.province_field.setValue('-1');
    this.city_field.setValue('-1');
    this.latitude_field.setValue('-1');
    this.longitude_field.setValue('-1');
    this.south_field.setValue('-1');
    this.east_field.setValue('-1');
    this.north_field.setValue('-1');
    this.west_field.setValue('-1');

//    if(resetText) {
//        this.input_field.setValue('');
//    }
}

/** updatePlaceFields() is used to replace locality fields in to the form
 *
 * @param transport
 * @return
 */
AddressMapDestination.prototype.updatePlaceFields = function(transport) {
    if(this.waitingPanel) new GeneralScript().hideComponent(this.waitingPanel);
    var jsonText = transport.responseText;
    eval('jsonResp = ' + jsonText);
    if(jsonResp.code == 200) {
        this.nation_field.setValue(jsonResp.country);
        this.district_field.setValue(jsonResp.region);
        this.province_field.setValue(jsonResp.prov);
        this.city_field.setValue(jsonResp.locality);



        
    }
    else {
        this.nation_field.setValue(-1);
        this.district_field.setValue(-1);
        this.province_field.setValue(-1);
        this.city_field.setValue(-1);

        if(jsonResp.msg) {
            this.showError(jsonResp.msg);
            
        }
        else {
            this.showError(this.defaultErrorText);
        }
    }
}



AddressMapDestination.prototype.updateGalleryPhoto = function() {
    if(this.photoPanel) {

            var parametri = {
                'country':this.nation_field.value,
                'region':this.district_field.value,
                'prov':this.province_field.value,
                'locality':this.city_field.value
            };
            var panel = this.photoPanel ;
            var loader = this.photoPanel;
            if(loader && $(loader)!=null) new Effect.Opacity($(loader), { 
                from: 1.0, to: 0.1, duration: 0.1 
               });
               
            AjaxRequest(this.baseUrl + '?page=AjaxHtmlDispatcher&class=gallery&method=updatePosition' ,
            {
                parameters : parametri,
                onSuccess: function(transport){
                    if(loader && $(loader)!=null) new Effect.Opacity($(loader), { 
                        from: 0.5, to: 1.0, duration: 0.2 
                    });
                    if(panel) $(panel).innerHTML = transport.responseText;
                    

                },
                onFailure: function(){
               
                }
            });

    }

AddressMapDestination.prototype.updateRecipes = function() {
    if(this.recipesPanel) {

            var parametri = {
                'country':this.nation_field.value,
                'region':this.district_field.value,
                'prov':this.province_field.value,
                'locality':this.city_field.value
            };
            var panel = this.recipesPanel ;
            var loader = this.recipesPanel;
            if(loader && $(loader)!=null) new Effect.Opacity($(loader), {
                from: 1.0, to: 0.1, duration: 0.1
               });
            AjaxRequest(this.baseUrl + '?page=AjaxHtmlDispatcher&class=recipe&method=updatePosition' ,
            {
                parameters : parametri,
                onSuccess: function(transport){
                    if(loader && $(loader)!=null) new Effect.Opacity($(loader), {
                        from: 0.5, to: 1.0, duration: 0.2
                    });
                    if(panel) $(panel).innerHTML = transport.responseText;

                },
                onFailure: function(){

                }
            });

    }


    
AddressMapDestination.prototype.updateAdvices = function() {
    if(this.advicesPanel) {

            var parametri = {
                'country':this.nation_field.value,
                'region':this.district_field.value,
                'prov':this.province_field.value,
                'locality':this.city_field.value
            };
            var panel = this.advicesPanel ;
            var loader = this.advicesPanel;
            if(loader && $(loader)!=null) new Effect.Opacity($(loader), {
                from: 1.0, to: 0.1, duration: 0.1
               });
            AjaxRequest(this.baseUrl + '?page=AjaxHtmlDispatcher&class=advice&method=updatePosition' ,
            {
                parameters : parametri,
                onSuccess: function(transport){
                    if(loader && $(loader)!=null) new Effect.Opacity($(loader), {
                        from: 0.5, to: 1.0, duration: 0.2
                    });
                    if(panel) $(panel).innerHTML = transport.responseText;

                },
                onFailure: function(){

                }
            });

    }

}

/**
 * Sets the info for the picker.
 *
 * @param details The details object containing the predefined info to
 * be set on the picker.
 * @param showPopup An optional boolean switch to show a popup on the marker.
 * @return
 */
AddressMapDestination.prototype.setInfo = function(details, showPopup) {
    this.resetFields(false);

    if (!details.editable) {
        this.input_field.onblur = null;
        this.input_field.disabled = true;
        if(this.clickHandler) GEvent.removeListener(this.clickHandler);
        this.clickHandler = null;
    }

    this.input_field.setValue(details.label);
    this.district_field.setValue(details.location[0]);
    this.province_field.setValue(details.location[1]);
    this.city_field.setValue(details.location[2]);
    this.latitude_field.setValue(details.latlng[0]);
    this.longitude_field.setValue(details.latlng[1]);
    this.south_field.setValue(details.bb[0]);
    this.east_field.setValue(details.bb[1]);
    this.north_field.setValue(details.bb[2]);
    this.west_field.setValue(details.bb[3]);

    var bounds = new GLatLngBounds(
        new GLatLng(details.bb[0], details.bb[3]),
        new GLatLng(details.bb[2], details.bb[1]));

    opts = {
        'title' : details.label.replace(/(<([^>]+)>)/ig,""),
        'icon' : this.getIcon()
        };

    var marker = new PhotoMapMarker(
        this.defaultErrorText, '',
        {
            'location':details.label,
            'lat':details.latlng[0],
            'lng':details.latlng[1]
            },
        opts);
    this.mgr.addMarker(marker, 0);
    this.mgr.refresh();
    if(showPopup) setTimeout(function() {
        marker.showPopup();
    }, 100);
    this.map.setCenter(marker.getLatLng(), this.map.getBoundsZoomLevel(bounds));

}



/**
 *  Map handler per gestione travelblog
 */
TravelBlogMapHandler.prototype = new GenericMapHandler();
function TravelBlogMapHandler(texts, labels, canvasId, zoomLevel,
    largeControl, preferredIconPath, url) {

    CallParentConstructor(this, GenericMapHandler, texts.defaultErrorText, canvasId, zoomLevel, largeControl);

    this.texts = texts;
    this.labels = labels;
    this.preferredIconPath = preferredIconPath;
    this.markers = new Array();
    this.backupMarkers = new Array();
    this.baseUrl = url;

    $(this.canvasId).mapHandler = this;
}

TravelBlogMapHandler.prototype.setMarkers = function(markers) {
    var markersArray = new Array();
    this.orderedMarkers = new Array();
    this.backupMarkers = markers;
    var current = null;
    for(var i = 0, l = markers.length; i < l; i++) {
        var opts = {
            title: markers[i].location
            };
        if(this.preferredIconPath) {
            var customIcon = null;
            var selectedIcon = null;
            if(markers[i].current) {
                customIcon = new google.maps.Icon();
                customIcon.shadow = this.preferredIconPath + "/images/ombra-preferiti.png";
                customIcon.image = this.preferredIconPath + "/images/preferred.png";
                customIcon.iconSize = new GSize(32, 32);
                customIcon.shadowSize = new GSize(36, 32);
                customIcon.iconAnchor = new GPoint(3, 33);
                customIcon.infoWindowAnchor = new GPoint(31, 4);
                opts = {
                    'title' : markers[i].location.replace(/(<([^>]+)>)/ig,""),
                    'icon' : customIcon
                };
                selectedIcon = "/images/preferred-over.png";
            }
            else {
                customIcon = new google.maps.Icon();
                customIcon.shadow = this.preferredIconPath + "/images/ombra-visitati.png";
                customIcon.image = this.preferredIconPath + "/images/flagvisitati.png";
                customIcon.iconSize = new GSize(33, 34);
                customIcon.shadowSize = new GSize(48, 34);
                customIcon.iconAnchor = new GPoint(3, 33);
                customIcon.infoWindowAnchor = new GPoint(31, 4);
                opts = {
                    'title' : markers[i].location.replace(/(<([^>]+)>)/ig,""),
                    'icon' : customIcon
                };
                selectedIcon = "/images/flagvisitati-over.png";
            }
        }

        var marker = new TravelBlogMarker(this.preferredIconPath, this,
            this.canvasId, this.texts.defaultErrorText, this.labels, markers[i],
            selectedIcon, opts);
        this.orderedMarkers.push(marker);
        markersArray.push(marker);
        if(markers[i].current) {
            current = marker;
        }
    }
    this.markers = markersArray;
    this.mgr.clearMarkers();
    this.map.clearOverlays();
    this.createPolyline();
    var ms = new MarkerSpreader(this.map);
    this.markers = ms.spreadMarkers(markersArray);
    if(this.markers.length != 0) {
        this.mgr.addMarkers(this.markers, 0);
        var bb = this.getBB();
        this.map.setCenter(bb.getCenter(), Math.max(this.map.getBoundsZoomLevel(bb), 5));
        this.mgr.refresh();
    }
    if(current) setTimeout(function(){
        current.showPopup();
    }, 10);
}


TravelBlogMapHandler.prototype.createPolyline = function() {
    var points = new Array();
    for(var i = 0; i < this.markers.length; i++) {
        points.push(this.markers[i].getLatLng());
    }
    var polyline = new google.maps.Polyline(points, "#cc0000", 4);
    this.map.addOverlay(polyline);
}

TravelBlogMapHandler.prototype.getBB = function() {
    var o = this.markers[0].getLatLng().lng();
    var e = this.markers[0].getLatLng().lng();
    var n = this.markers[0].getLatLng().lat();
    var s = this.markers[0].getLatLng().lat();
    for(var i = 1; i < this.markers.length; i++) {
        if(this.markers[i].getLatLng().lat() < s) s = this.markers[i].getLatLng().lat();
        if(this.markers[i].getLatLng().lat() > n) n = this.markers[i].getLatLng().lat();
        if(this.markers[i].getLatLng().lng() < o) o = this.markers[i].getLatLng().lng();
        if(this.markers[i].getLatLng().lng() > e) e = this.markers[i].getLatLng().lng();
    }
    return new google.maps.LatLngBounds(new google.maps.LatLng(s, o), new google.maps.LatLng(n, e));
}

TravelBlogMapHandler.prototype.updateMap = function(nid, index) {
    var params = {
        'nid' : nid,
        'index' : index
    };
    var me = this;
    AjaxRequest( this.baseUrl + "?page=AjaxDispatcher&class=travelblog&method=reloadmap" , {
        parameters : params,
        onSuccess: function(transport){
            var jsonText = transport.responseText;
            eval('jsonResp = ' + jsonText);
            if(jsonResp.code == 200) {
                me.setMarkers(jsonResp.data);
            }
            else {
                me.showError(this.defaultErrorText);
            }
        },
        onFailure: function(){
            me.showError(this.defaultErrorText);
        }
    });
}

TravelBlogMapHandler.prototype.showError = function(errorMessage) {
    var gs = new GeneralScript();
    if(this.waitingPanel) gs.hideComponent(this.waitingPanel);
    gs.showErrorMessage(errorMessage);
}

TravelBlogMapHandler.prototype.showStop = function(index) {
    var bm = this.backupMarkers;
    for(var i = 0; i < bm.length; i++) {
        bm[i].current = false;
    }
    if(index < bm.length) {
        bm[index].current = true;
        this.setMarkers(bm);
    } else {
        this.setMarkers(bm);
        var bb = this.getBB();
        this.map.setZoom(Math.max(this.map.getBoundsZoomLevel(bb)-1,5));
        this.map.panTo(bb.getCenter());
    }
}


/**
 * Map handler per gestione Destinazioni
 */
RankingMap.prototype = new GenericMapHandler();
function RankingMap(defaultErrorText, locationLabel, canvasId, iconsPath,
    mapHandler, zoomLevel, largeControl) {
    CallParentConstructor(this, GenericMapHandler, defaultErrorText, canvasId, zoomLevel, largeControl, false);

    this.locationLabel = locationLabel;
    this.iconsPath = iconsPath;
    this.mapHandler = mapHandler;
    this.visitedMarkers = new Array();
    this.favouritesMarkers = new Array();
    this.suggestedMarkers = new Array();

}

RankingMap.prototype.markerSelected = function(markerInfo) {
    this.mapHandler.markerSelected(markerInfo);
}

RankingMap.prototype.selectPosition = function(position) {
    this.markers[position].showPopup();
}

RankingMap.prototype.createMarkers = function(markersInfo, type, shadowIcon) {
    var markers = new Array();
    for(var i = 0; i < markersInfo.length; i++) {
        var markerInfo = markersInfo[i].info;
        markerInfo.lat = markersInfo[i].extinfo.latlng[0];
        markerInfo.lng = markersInfo[i].extinfo.latlng[1];
        markerInfo.south = markersInfo[i].extinfo.bb[0];
        markerInfo.east = markersInfo[i].extinfo.bb[1];
        markerInfo.north = markersInfo[i].extinfo.bb[2];
        markerInfo.west = markersInfo[i].extinfo.bb[3];
        markerInfo.location = markersInfo[i].extinfo.label;
        var opts = null;
        if((i + 1) <= 10) {
            var customIcon = new google.maps.Icon();
            customIcon.shadow = this.iconsPath + shadowIcon;

            var selectedIcon = null;

            if (type == 'image') {
                customIcon.image = this.iconsPath + "/images/icone/.png";
                customIcon.iconSize = new GSize(33, 34);
                customIcon.shadowSize = new GSize(48, 32);
                customIcon.iconAnchor = new GPoint(3, 33);
                customIcon.infoWindowAnchor = new GPoint(31, 4);
                selectedIcon = "/images/flagvisitati-over.png";
            }
            else if (type == 'recipe') {
                customIcon.image = this.iconsPath + "/images/icone/icon-ricetta-map.png";
                customIcon.iconSize = new GSize(39, 38);
                //customIcon.shadowSize = new GSize(36, 32);
                customIcon.iconAnchor = new GPoint(7, 30);
                customIcon.infoWindowAnchor = new GPoint(16, 1);
                //selectedIcon = "/images/preferred-over.png";
            }
            else if (type == 'advice') {
                customIcon.image = this.iconsPath + "/images/marker-suggeriti.png";
                customIcon.iconSize = new GSize(34, 34);
                customIcon.shadowSize = new GSize(40, 34);
                customIcon.iconAnchor = new GPoint(16, 32);
                customIcon.infoWindowAnchor = new GPoint(24, 2);
                selectedIcon = "/images/suggested-over.png";
            }

            opts = {
                title : markerInfo.location.replace(/(<([^>]+)>)/ig,""),
                icon : customIcon
            };

            var marker = new PlacesMapMarker(this.iconsPath, this.defaultErrorText,
                this.locationLabel, this, markerInfo, selectedIcon, opts);
            markers.push(marker);
        }

    }
    return markers;
}

RankingMap.prototype.setImageMarkers = function(markersInfo) {
    this.imageMarkers = this.createMarkers(markersInfo, 'image', "");
}

RankingMap.prototype.setRecipeMarkers = function(markersInfo) {
    this.recipeMarkers = this.createMarkers(markersInfo, 'recipe', "");
}

RankingMap.prototype.setAdviceMarkers = function(markersInfo) {
    this.adviceMarkers = this.createMarkers(markersInfo, 'advice', "");
}

RankingMap.prototype.updateMarkers = function(type) {
    if (type == 'image') {
        this.markers = this.visitedMarkers;
        this.showImageMarkers();
    }
    else if (type == 'recipe') {
        this.markers = this.favouritesMarkers;
        this.showRecipeMarkers();
    }
    else if (type == 'advice') {
        this.markers = this.suggestedMarkers;
        this.showAdviceMarkers();
    }
}

RankingMap.prototype.showImageMarkers = function() {
    this.mgr.clearMarkers();
    this.mgr.addMarkers(this.imageMarkers, 0);
    this.mgr.refresh();
}

RankingMap.prototype.showRecipeMarkers = function() {
    this.mgr.clearMarkers();
    this.mgr.addMarkers(this.recipeMarkers, 0);
    this.mgr.refresh();
}

RankingMap.prototype.showAdviceMarkers = function() {
    this.mgr.clearMarkers();
    this.mgr.addMarkers(this.adviceMarkers, 0);
    this.mgr.refresh();
}
}
}
