
    var MARKERS_PATH                  = "/portal/templates/default/img/markers/";
    var GROUND_OVERLAY_URL            = "http://www.mallorcaweb.com/portal/templates/default/img/mar.png";

    var GPOLYGON_STROKE_COLOR         = "#ffffff";
    var GPOLYGON_STROKE_OPACITY       = 1;
    var GPOLYGON_COLOR                = "#404040";
    var GPOLYGON_OPACITY              = 0.3;

    var GPOLYGON_HOVER_STROKE_COLOR   = "#ffffff";
    var GPOLYGON_HOVER_STROKE_OPACITY = 1;
    var GPOLYGON_HOVER_COLOR          = "#E4A600";
    var GPOLYGON_HOVER_OPACITY        = 0.3;

    var GPOLYGON_LIGHT_STROKE_COLOR   = "#000000";
    var GPOLYGON_LIGHT_STROKE_OPACITY = 0;
    var GPOLYGON_LIGHT_COLOR          = "#ffffff";
    var GPOLYGON_LIGHT_OPACITY        = 0;
    
    // GMapUtilities
    //////////////////////////////////////////////////////

    function GMapUtilities()
    {
        // Empty constructor due to is a static class
    }
    
    GMapUtilities.decodePolyline = function(encoded)
    {
        encoded    = encoded.replace(/\\\\/g, "\\");
        
        var len    = encoded.length;
        var index  = 0;
        var points = [];
        var lat    = 0;
        var lng    = 0;
    
        while (index < len)
        {
            var b;
            var shift  = 0;
            var result = 0;
            
            do
            {
                b       = encoded.charCodeAt(index++) - 63;
                result |= (b & 0x1f) << shift;
                shift  += 5;
            }
            while (b >= 0x20);
            
            var dlat = ((result & 1) ? ~(result >> 1) : (result >> 1));
            lat     += dlat;
    
            shift  = 0;
            result = 0;
            
            do
            {
                b       = encoded.charCodeAt(index++) - 63;
                result |= (b & 0x1f) << shift;
                shift  += 5;
            }
            while (b >= 0x20);
            
            var dlng = ((result & 1) ? ~(result >> 1) : (result >> 1));
            lng     += dlng;

            points.push(new GLatLng( lat * 1e-5, lng * 1e-5));
        }

        return points;
    }

    // GMap2 extensions
    //////////////////////////////////////////////////////

    GMap2.prototype.init = function(point, zoom, mapControl, overview)
    {
        this.setCenter(point, zoom);
        
        this.addControl(new GMapTypeControl());
        this.addMapType(G_PHYSICAL_MAP);
        
        this.cur        = null
        this.curLighted = null;

        if (mapControl == true)
        {
            this.addControl(new GLargeMapControl());
        }
        else
        {
            this.removeControl(new GLargeMapControl());
        }
        
        if (overview == true)
        {
            this.addControl(new GOverviewMapControl());
        }
    }

    GMap2.prototype.initMini = function(point, zoom, maptype)
    {
        this.setCenter(point, zoom);        
        this.addControl(new GSmallMapControl());

        if (maptype == true)
        {
            this.addControl(new GMapTypeControl());
            this.addMapType(G_PHYSICAL_MAP);
        }
    }

    GMap2.prototype.addGroundOverlay = function()
    {
        var sw   = new GLatLng(38.272689, 1.032715);
        var ne   = new GLatLng(40.279526, 5.383301);
        var over = new GGroundOverlay(GROUND_OVERLAY_URL, new GLatLngBounds(sw, ne));

        this.addOverlay(over);
    }
    
    GMap2.prototype.showHideMarkers = function(cid, showHide)
    {
        for (i = 0; i < this.markers[cid].length; i++)
        {
            if (showHide)
            {
                icon = this.markers[cid][i].getIcon();
                icon.image = MARKERS_PATH + "mfc-" + cid + ".png";
                
                this.addOverlay(this.markers[cid][i]);
            }
            else
            {
                this.removeOverlay(this.markers[cid][i]);
            }
        }
    }
    
    // GMyMarker
    //////////////////////////////////////////////////////
    
    function GMyMarker(ind, point, url, img1, img2, title)
    {
        icon                  = new GIcon();
        icon.image            = MARKERS_PATH + img1;
        icon.iconSize         = new GSize(32, 32);
        icon.iconAnchor       = new GPoint(16, 32);
        icon.infoWindowAnchor = new GPoint(16, 0);
        
        GMarker.call(this, point, {icon: icon, title: title});

        this.showClose = "show";
        this.html      = "This content must be set by child GMyMarker's classes";

        this.ind       = ind;
        this.point     = point;
        this.url       = url;
        this.img1      = img1;
        this.img2      = img2;

        if (this.img1 != this.img2 && this.img2 != null)
        {
            GEvent.addListener(this, "mouseover", this.highlight);
            GEvent.addListener(this, "mouseout", this.unHighlight);

            GEvent.addListener(this, "infowindowopen", this.handleWindowOpen);
            GEvent.addListener(this, "infowindowclose", this.handleWindowClose);
        }
    }

    GMyMarker.prototype = new GMarker(new GLatLng(0, 0));

    GMyMarker.prototype.showHideInfoWindowHtml = function()
    {
        if (this.showClose == "show")
        {
            this.showClose = "close";
            this.openInfoWindowHtml(this.html);
        }
        else
        {
            this.showClose = "show";
            this.closeInfoWindow();
        }
    }

    GMyMarker.prototype.handleWindowOpen = function()
    {
        if (this.img1 != this.img2 && this.img2 != null)
        {
            GEvent.clearListeners(this, "mouseover");
            GEvent.clearListeners(this, "mouseout");
            this.setImage(MARKERS_PATH + this.img2);
        }
    }

    GMyMarker.prototype.handleWindowClose = function()
    {
        if (this.img1 != this.img2 && this.img2 != null)
        {
            GEvent.addListener(this, "mouseover", this.highlight);
            GEvent.addListener(this, "mouseout", this.unHighlight);
            this.setImage(MARKERS_PATH + this.img1);
        }
    }
    
    GMyMarker.prototype.highlight = function()
    {
        this.setImage(MARKERS_PATH + this.img2);
        e = document.getElementById("li" + this.ind) || false;

        if (e)
        {
            e.className = "light";
        }
    }

    GMyMarker.prototype.unHighlight = function()
    {
        this.setImage(MARKERS_PATH + this.img1);
        e = document.getElementById("li" + this.ind) || false;

        if (e)
        {
            e.className = "";
        }
    }

    GMyMarker.prototype.handleClick = function()
    {
        location.href = this.url;
    }
    
    // GPoblacioMarker
    //////////////////////////////////////////////////////

    function GPoblacioMarker(ind, point, url, num)
    {
        GMyMarker.call(this, ind, point, url, "marker.png", "marker-highlight.png", num);
        GEvent.addListener(this, "click", this.handleClick);
    }

    GPoblacioMarker.prototype = new GMyMarker(0, new GLatLng(0, 0), "/");

    // GLlocMarker
    //////////////////////////////////////////////////////

    function GLlocMarker(ind, point, url, img1, img2, nom, thumb, width, height, showMsg)
    {
        nom = nom.replace("&#039;", "'");
        
        GMyMarker.call(this, ind, point, url, img1, img2, nom);

        this.nom     = nom;
        this.thumb   = thumb;
        this.width   = width || 70;
        this.height  = height || 50;
        this.showMsg = showMsg

        this.html  = "\
            <div class='markerInfo'>\
                \
                <div class='picture'>\
                    <img width='" + width + "' height='" + this.height + "' src='" + this.thumb + "' alt='" + this.nom + "' title='" + this.nom + "' />\
                </div>\
                \
                <div class='dades'>\
                    <p class='nom'>\
                        " + this.nom + "\
                    </p>\
                    \
                    <div>\
                        <a href='" + this.url + "'>" + showMsg + "</a>&nbsp;&gt;&gt;\
                    </div>\
                </div>\
                \
            </div>\
            ";

        if (url != false && url != null)
        {
            GEvent.addListener(this, "click", this.showHideInfoWindowHtml);
        }
    }

    GLlocMarker.prototype = new GMyMarker(0, new GLatLng(0, 0), "/");

    // GMyPolygon
    //////////////////////////////////////////////////////

    /*
    **    This code only when we use mouse over/out events with polygons
    **    Put this snippet in template
    **
    ****************************************************************************

        points{$id} = GMapUtilities.decodePolyline("{$encPoints}");
        poly{$id}   = new GMyPolygon(points{$id}, "{$nom}");

        a = poly{$id}.getArea();
        document.write("UPDATE poblacions SET superficie = '" + a + "' WHERE id = '{$id}' LIMIT 1 ;\r\n");
    
    ****************************************************************************/
    
    var _mSvgForced  = true;
    var _mSvgEnabled = true;

    function GMyPolygon(id, points, url, tooltip, lighted, withEvents)
    {
        if (lighted == true)
        {
            strokeColor   = GPOLYGON_LIGHT_STROKE_COLOR;
            strokeOpacity = GPOLYGON_LIGHT_STROKE_OPACITY;
            color         = GPOLYGON_LIGHT_COLOR;
            opacity       = GPOLYGON_LIGHT_OPACITY;
        }
        else
        {
            strokeColor   = GPOLYGON_STROKE_COLOR;
            strokeOpacity = GPOLYGON_STROKE_OPACITY;;
            color         = GPOLYGON_COLOR;
            opacity       = GPOLYGON_OPACITY;
        }
        
        BDCCPolygon.call(this, points, strokeColor, 1, strokeOpacity, color, opacity, tooltip, "solid");

        this.id         = id;
        this.url        = url;
        this.lighted    = lighted;
        this.withEvents = withEvents;

        if (withEvents == true)
        {
            GEvent.addListener(this, "mouseover", this.handleMouseOver);
            GEvent.addListener(this, "mouseout", this.handleMouseOut);
            GEvent.addListener(this, "click", this.handleClick);
        }
        else
        {
            this.customCursor = "normal";
        }
    }

    GMyPolygon.prototype = new BDCCPolygon([new GLatLng(0, 0)], "#ffffff", 1, 1, GPOLYGON_COLOR, GPOLYGON_OPACITY, "tooltip");

    GMyPolygon.prototype.handleMouseOver = function()
    {
        this.setStrokeColor(GPOLYGON_HOVER_STROKE_COLOR);
        this.setStrokeOpacity(GPOLYGON_HOVER_STROKE_OPACITY);
        this.setFillColor(GPOLYGON_HOVER_COLOR);
        this.setFillOpacity(GPOLYGON_HOVER_OPACITY);
        
        e = document.getElementById("li" + this.id);

        if (e)
        {
            e.className = "light";
        }
    }

    GMyPolygon.prototype.handleMouseOut = function()
    {
        this.setStrokeColor(GPOLYGON_STROKE_COLOR);
        this.setStrokeOpacity(GPOLYGON_STROKE_OPACITY);
        this.setFillColor(GPOLYGON_COLOR);
        this.setFillOpacity(GPOLYGON_OPACITY);
        
        e = document.getElementById("li" + this.id);

        if (e)
        {
            e.className = "";
        }
    }

    GMyPolygon.prototype.handleClick = function()
    {
        this.handleMouseOver();

        GEvent.clearListeners(this, "mouseover");
        GEvent.clearListeners(this, "mouseout");
        
        location.href = this.url;
    }
