//if (!TEF) TEF={};

function removeUnit(value)
{
    if (value.substring(value.length-2) == "px") {
        return value.substring(0, value.length-2);
    }
    return value;
}

// Constructor
TEF.Map = function(mapDivId)
{
    this.divId = mapDivId;
    
    mapDiv = document.getElementById(mapDivId);
    this.width = removeUnit(mapDiv.style.width);
    this.height = removeUnit(mapDiv.style.height);
    switch (mapVendor) {
        case 0: // ootoogo
            break;
        case 1: // google
            this.gmap = new GMap2(mapDiv);
            // FIXME Should be set using a method
            G_NORMAL_MAP.getMinimumResolution = function(){return 2};
            G_NORMAL_MAP.getMaximumResolution = function(){return 12}; 
            //this.gmap.setCenter(new GLatLng(37.4419, -122.1419), 13);
            break;
        default:
            alert("Unknown map vendor ["+mapVendor+"]");
    }
    
    this.listeners = new Array();
};
TEF.Map.prototype = {
    width:null,
    height:null,
    
    setWidth:function(width)
    {
        this.width = width;
    },
    
    getWidth:function()
    {
        return this.width;
    },

    setHeight:function(height)
    {
        this.height = height;
    },
    
    getHeight:function()
    {
        return this.height;
    },
    
    addListener:function(listener)
    {
        switch (mapVendor) {
            case 0: // ootoogo
                this.listeners.push(listener);
                break;
            case 1: // google
                // Should not be called
                // Cf. GEvent.addListener
            default:
                alert("Unknown map vendor ["+mapVendor+"]");
        }
    },
    
    trigger:function(source, eventId)
    {
        for (i=0; i<this.listeners.length; i++) {
            if (this.listeners[i].getEventId() == eventId) {
                this.listeners[i].getCallback().call(source); 
            }
        }
    },
    
    getGoogleMap:function()
    {
         return this.gmap;
    },
    
    setBoundingBox:function(longMin, latMin, longMax, latMax)
    {
        switch (mapVendor) {
            case 0: // ootoogo
                alert("setBoundingBox: Not yet implemented");
                break;
            case 1:
                bounds = new GLatLngBounds(new GLatLng(latMin, longMin), new GLatLng(latMax, longMax));
                zoomLevel = this.gmap.getBoundsZoomLevel(bounds);
                center = new GLatLng((latMax+latMin)/2, (longMax+longMin)/2);
                this.gmap.setCenter(center, zoomLevel);
                break;
            default:
                alert("setBoundingBox: Unknown map vendor ["+mapVendor+"]");
        }
    },
    
    getBoundingBox: function()
    {
        switch (mapVendor) {
            case 0: // ootoogo
                alert("getBoundingBox: Not yet implemented");
                break;
            case 1:
                bounds = this.gmap.getBounds();
                return new TEF.BoundingBox(bounds.getSouthWest().lng(),
                                           bounds.getSouthWest().lat(),
                                           bounds.getNorthEast().lng(),
                                           bounds.getNorthEast().lat());
                break;
            default:
                alert("getBoundingBox: Unknown map vendor ["+mapVendor+"]");
        }
    },
    
    setCenter:function(long, lat, zoomLevel)
    {
        switch (mapVendor) {
            case 0: // ootoogo
                alert("setCenter: Not yet implemented");
                break;
            case 1:
                this.gmap.setCenter(new GLatLng(lat, long), zoomLevel);
                break;
            default:
                alert("setCenter: Unknown map vendor ["+mapVendor+"]");
        }
    },
    
    addPanZoomControl:function(small)
    {
        switch (mapVendor) {
            case 0: // ootoogo
                alert("addPanZoomControl: Not yet implemented");
                break;
            case 1:
                // TODO Take into account "small" input parameter
                this.gmap.addControl(new GSmallMapControl());
                break;
            default:
                alert("addPanZoomControl: Unknown map vendor ["+mapVendor+"]");
        }
    },
    
    zoomIn:function()
    {
        switch (mapVendor) {
            case 0: // ootoogo
                // No display update (update is based on new URL call)
                // But not to update map bounds
                this.trigger(null, "moveend")
                break;
            case 1: // google
                // Should not be called
            default:
                alert("zoomIn: Unknown map vendor ["+mapVendor+"]");
        }
    },
    
    /** FIXME Here overlay is assumed to be a marker */
    addOverlay:function(overlay)
    {
        switch (mapVendor) {
            case 0: // ootoogo
                alert('not yet implemented');
                break;
            case 1: // google
                marker = overlay;
                gmarker = new GMarker(marker.getPoint().getGLatLng());
                this.gmap.addOverlay(gmarker);
                break;
            default:
                alert("addOverlay: Unknown map vendor ["+mapVendor+"]");
        }
    },
    
    clearOverlays:function()
    {
        switch (mapVendor) {
            case 0: // ootoogo
                alert('not yet implemented');
                break;
            case 1: // google
                this.gmap.clearOverlays();
                break;
            default:
                alert("addOverlay: Unknown map vendor ["+mapVendor+"]");
        }
    },
    
    clearMarkers:function()
    {
        this.clearOverlays();
    },
    
    unload:function()
    {
        switch (mapVendor) {
            case 0: // ootoogo
                // Nothing to do ?
                break;
            case 1: // google
                GUnload();
                break;
            default:
                alert("unload: Unknown map vendor ["+mapVendor+"]");
        }
    }
};

TEF.Point = function(longitude, latitude) {
    this.longitude = longitude;
    this.latitude = latitude;
}; // Constructor
TEF.Point.prototype = {
    longitude:null,
    latitude:null,
    
    setLongitude:function(longitude)
    {
        this.longitude = longitude;
    },

    getLongitude:function()
    {
        return this.longitude;
    },
    
    setLatitude:function(latitude)
    {
        this.latitude = latitude;
    },

    getLatitude:function()
    {
        return this.latitude;
    },
    
    getGLatLng:function()
    {
        return new GLatLng(this.latitude, this.longitude);
    }
};

// Constructor
TEF.BoundingBox = function(longMin, latMin, longMax, latMax) {
    this.longMin = longMin;
    this.latMin = latMin;
    this.longMax = longMax;
    this.latMax = latMax;
};
TEF.BoundingBox.prototype = {
    getLongitudeMin:function()
    {
        return this.longMin;
    },
    getLongitudeMax:function()
    {
        return this.longMax;
    },
    getLatitudeMin:function()
    {
        return this.latMin;
    },
    getLatitudeMax:function()
    {
        return this.latMax;
    }
};

// Constructor
TEF.Listener = function(eventId, callback) {
    this.eventId = eventId;
    this.callback = callback;
}

TEF.Listener.prototype = {
    setEventId:function(eventId)
    {
        this.eventId = eventId;
    },
    getEventId:function()
    {
        return this.eventId;
    },
    
    setCallback:function(callbakc)
    {
        this.callback = callback;
    },
    getCallback:function()
    {
        return this.callback;
    }
}

// For method static calls
TEF.Event = {
    addListener:function(map, eventId, callback)
    {
        switch (mapVendor) {
            case 0: // ootoogo
                map.addListener(new TEF.Listener(eventId, callback));
                break;
            case 1: // google
                 gmap = map.getGoogleMap();
                 GEvent.addListener(gmap, eventId, callback);
                 break;
            default:
                alert("Unknown map vendor ["+mapVendor+"]");
        }
    }
}

//Constructor
TEF.Marker = function(point) {
    this.point = point;
}
TEF.Marker.prototype = {
        
        getPoint:function()
        {
            return this.point;
        }
}