function MapViewer(map, marker_types, lat, lng, zoom) 
{
    this.map = map;
    this.origin = null
    this.marker_types = marker_types;

    this.markers = [];
    this.manager = new GMarkerManager(this.map);
    
    GEvent.bind(this.map, "moveend", this, this.map_moveend);
    
    this.refresh_markers();
    
    if (lat && lng && zoom)
    {
        var point = new GLatLng(lat, lng); 
        this.map.setCenter(point);
        this.map.setZoom(zoom);
    }
}

MapViewer.prototype.map_moveend = function() 
{
    this.refresh_markers();
}

MapViewer.prototype.refresh_markers = function()
{
    var zoom        = this.map.getZoom();
    var center      = this.map.getCenter();
    var current_lat = center.lat();
    var current_lng = center.lng();
    
    if (zoom >= 12) 
    {
        if (!this.origin || (this.origin != center && center.distanceFrom(this.origin) > 25000)) { // 25km
            this.request_markers(current_lat, current_lng, 25)
            this.origin = center;
        }
    }
}

MapViewer.prototype.request_markers = function(lat, lng, distance) 
{
    var o = this;

    for (var i = 0; i < this.marker_types.length; i++) {
        var marker_type = this.marker_types[i];

        new Ajax.Request('/' + marker_type + '/find_within', {
            method: 'get',
            parameters: { lat: lat, lng: lng, distance: distance * 2 },
            onSuccess: function(request) {
                //o.process_xml(marker_type, request.responseText);
                o.process_xml(request.responseText);
            }
        }); 
    }
}

//MapViewer.prototype.process_xml = function(marker_type, data)
MapViewer.prototype.process_xml = function(data)
{
    var xml         = GXml.parse(data);
    var marker_type = xml.documentElement.tagName;
    var markers     = xml.getElementsByTagName(marker_type)[0].getElementsByTagName("marker");
    var collection  = [];

    // we need logic here to process what type of marker we are placing
    if (marker_type == 'people')
    {
        var icon = new MapIcon('orange-people');            
    }
    else if (marker_type == 'maps')
    {
        var icon = new MapIcon('green');      
    }                            
    else if (marker_type == 'strides')
    {
        var icon = new MapIcon('blue');              
    }
    else
    {
        var icon = new MapIcon('gray');              
    }

    for (var i = 0; i < markers.length; i++) {
        var lat         = parseFloat(GXml.value(markers[i].getElementsByTagName("lat")[0]));
        var lng         = parseFloat(GXml.value(markers[i].getElementsByTagName("lng")[0]));
        var point       = new GLatLng(lat, lng); 
        var marker      = new GMarker(point, icon); 
        marker.marker_id = GXml.value(markers[i].getElementsByTagName("id")[0]);
        marker.info_window = false;

        GEvent.addListener(marker, "click", function() {
            
            var marker = this;
            
            if (marker.info_window == false)
            {
                marker.openInfoWindowHtml('<img src="/images/throbbers/throbber-20x20.gif" />');

                new Ajax.Request('/' + marker_type + '/info/'+marker.marker_id, {
                    method: 'get',
                    onSuccess: function(request) {
                        //o.process_xml(marker_type, request.responseText);
                        marker.info_window = request.responseText;
                        marker.openInfoWindowHtml(marker.info_window);
                    }
                });                
            }
            else
            {
                marker.openInfoWindowHtml(marker.info_window);                
            }
        });

        collection.push(marker);
    }

    this.manage_collection(collection);
}

MapViewer.prototype.manage_collection = function(collection)
{
    var new_collection = [];

    for (var i = 0, l = collection.length; i < l; i++) {
        var unique = true;
        for (var n = 0, m = this.markers.length; n < m; n++) {
            if (collection[i].getPoint().lat() == this.markers[n].getPoint().lat()) {
                unique = false;
            }
        }
        if (unique == true) {
            new_collection.push(collection[i]);
        }
    }

    this.markers = this.markers.concat(new_collection);
    this.manager.addMarkers(new_collection, 12);
    this.manager.refresh();
}
