/**
 * Created by Nicholas Hallahan on 1/22/15.
 * nhallahan@spatialdev.com 
 */

package com.spatialdev.osm.renderer;

import android.graphics.Canvas;

import com.mapbox.mapboxsdk.geometry.BoundingBox;
import com.mapbox.mapboxsdk.overlay.Overlay;
import com.mapbox.mapboxsdk.views.MapView;
import com.spatialdev.osm.model.JTSModel;
import com.spatialdev.osm.model.OSMNode;
import com.spatialdev.osm.model.OSMElement;
import com.spatialdev.osm.model.OSMWay;
import com.vividsolutions.jts.geom.Envelope;

import java.util.ArrayList;
import java.util.List;

public class OSMOverlay extends Overlay {

    private static final int DEFAULT_OVERLAY_INDEX = 4;
    
    private JTSModel model;
    private Envelope envelope;
    
    private float minVectorRenderZoom = 0;
    private float zoom = 0; // current zoom of map

    /**
     * This should only be created by OSMMap.
     * * *
     * @param model
     */
    public OSMOverlay(JTSModel model) {
        this.model = model;
        setOverlayIndex(DEFAULT_OVERLAY_INDEX);
    }

    /**
     * This should only be created by OSMMap.
     * * *
     * @param model
     * @param minVectorRenderZoom
     */
    public OSMOverlay(JTSModel model, float minVectorRenderZoom) {
        this(model);
        this.minVectorRenderZoom = minVectorRenderZoom;
    }
    
    public void updateBoundingBox(BoundingBox bbox) {
        double x1 = bbox.getLonWest();
        double x2 = bbox.getLonEast();
        double y1 = bbox.getLatSouth();
        double y2 = bbox.getLatNorth();
        envelope = new Envelope(x1, x2, y1, y2);
    }

    /**
     * Have the map set the current zoom.
     * * 
     * @param zoom
     */
    public void updateZoom(float zoom) {
        this.zoom = zoom;
    }
    
    @Override
    protected void draw(Canvas c, MapView mapView, boolean shadow) {
        // no shadow support & need a bounding box to query rtree & at or above min render zoom
        if (shadow || envelope == null || zoom < minVectorRenderZoom) {
            return;
        }

        List<OSMWay> polys = new ArrayList<>();
        List<OSMWay> lines = new ArrayList<>();
        List<OSMNode> points = new ArrayList<>();
        
        List<OSMElement> viewPortElements = model.queryFromEnvelope(envelope);
        
        // Sort the elements into their geom types so we can draw 
        // points on top of lines on top of polys.
        for (OSMElement el : viewPortElements) {
            if (el instanceof OSMWay) {
                OSMWay w = (OSMWay) el;
                if (w.isClosed()) {
                    polys.add(w);
                } else {
                    lines.add(w);
                }
                continue;
            }
            // if it isn't a Way, it's a Node.
            points.add((OSMNode)el);
        }
        
        // Draw polygons
        for (OSMWay w : polys) {
            w.getOSMPath(mapView).draw(c);
        }
        
        // Draw lines
        for (OSMWay w : lines) {
            w.getOSMPath(mapView).draw(c);
        }
    }
    
}

@@ -812,24 +812,86 @@
 of map%0A%0A
+    private List%3COSMNode%3E viewPortNodes = new ArrayList%3C%3E();%0A%0A
     /**%0A
      * T
@@ -874,32 +874,32 @@
 t%3C%3E();%0A%0A    /**%0A
-
      * This shou
@@ -1791,32 +1791,115 @@
 om = zoom;%0A    %7D
+%0A%0A    public List%3COSMNode%3E getViewPortNodes() %7B%0A        return viewPortNodes;%0A    %7D
 %0A    %0A    @Overr
@@ -2262,32 +2262,33 @@
 ayList%3C%3E();%0A
+%0A
         
 List%3COSMNode
@@ -2279,46 +2279,147 @@
     
-List%3COSMNode%3E points = new ArrayList%3C%3E
+// We want to always be referring to the same list so external sources%0A        // do not reference stale lists.%0A        viewPortNodes.clear
 ();%0A
@@ -3008,21 +3008,28 @@
         
-point
+viewPortNode
 s.add((O
@@ -3035,16 +3035,17 @@
 OSMNode)
+ 
 el);%0A   
@@ -3294,15 +3294,11 @@
 %7D%0A    %7D%0A
-    
 %0A%7D%0A

Maintain one list of viewPortNodes in OSMOverlay #31