package com.github.gfx.hankei_n.model;

import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.model.Circle;
import com.google.android.gms.maps.model.Marker;

import com.github.gfx.hankei_n.dependency.scope.ContextScope;

import android.support.annotation.NonNull;
import android.support.v4.util.LongSparseArray;

import java.util.NoSuchElementException;

import javax.inject.Inject;

@ContextScope
public class MarkerManager {

    final LongSparseArray<MarkerHolder> markers = new LongSparseArray<>();

    @Inject
    public MarkerManager() {
    }

    @NonNull
    public Marker get(@NonNull LocationMemo memo) {
        assert memo.id > 0;
        return markers.get(memo.id).marker;
    }


    public LocationMemo findMemoByMarker(Iterable<LocationMemo> memos, Marker marker) {
        for (LocationMemo item : memos) {
            if (marker.equals(get(item))) {
                return item;
            }
        }
        throw new NoSuchElementException("Marker not found for id=" + marker.getId());
    }

    public Marker create(@NonNull GoogleMap map, @NonNull LocationMemo memo) {
        assert memo.id > 0;

        remove(memo);

        Marker marker = map.addMarker(memo.buildMarkerOptions());
        Circle circle = null;
        if (memo.radius > 0 && memo.drawCircle) {
            circle = map.addCircle(memo.buildCircleOptions());
        }

        markers.put(memo.id, new MarkerHolder(marker, circle));

        return marker;
    }

    public void remove(LocationMemo memo) {
        assert memo.id > 0;
        MarkerHolder holder = markers.get(memo.id);
        if (holder != null) {
            holder.removeFromMap();
            markers.remove(memo.id);
        }
    }

    public void clear() {
        for (int i = 0; i < markers.size(); i++) {
            long id = markers.keyAt(i);
            markers.get(id).removeFromMap();
        }
    }

    static class MarkerHolder {

        Marker marker;

        Circle circle;

        public MarkerHolder(Marker marker, Circle circle) {
            this.marker = marker;
            this.circle = circle;
        }

        void removeFromMap() {
            if (marker != null) {
                marker.remove();
            }
            if (circle != null) {
                circle.remove();
            }
        }

    }
}

@@ -311,33 +311,159 @@
 ort.
-v4.util.LongSparseArray;%0A
+annotation.Nullable;%0Aimport android.support.v4.util.LongSparseArray;%0Aimport android.text.TextUtils;%0A%0Aimport java.util.ArrayList;%0Aimport java.util.List;
 %0Aimp
@@ -620,16 +620,22 @@
 %3E marker
+Holder
 s = new 
@@ -781,63 +781,475 @@
     
-assert memo.id %3E 0;%0A        return markers.get(memo.id)
+Marker marker = getOrNull(memo);%0A        if (marker == null) %7B%0A            throw new NoSuchElementException(%22No MarkerHolder for %22 + memo + %22 in %22 + this);%0A        %7D%0A        return marker;%0A    %7D%0A%0A    @Nullable%0A    private Marker getOrNull(@NonNull LocationMemo memo) %7B%0A        assert memo.isPersistent();%0A        MarkerHolder markerHolder = markerHolders.get(memo.id);%0A        if (markerHolder == null) %7B%0A            return null;%0A        %7D%0A        return markerHolder
 .mar
@@ -1260,17 +1260,16 @@
 %0A    %7D%0A%0A
-%0A
     publ
@@ -1386,24 +1386,108 @@
  : memos) %7B%0A
+            // Use getOrNull() because all the markers are not necessarily prepared%0A
             
@@ -1507,16 +1507,22 @@
 uals(get
+OrNull
 (item)))
@@ -2036,16 +2036,22 @@
   marker
+Holder
 s.put(me
@@ -2227,24 +2227,30 @@
 der = marker
+Holder
 s.get(memo.i
@@ -2337,16 +2337,22 @@
   marker
+Holder
 s.remove
@@ -2439,16 +2439,22 @@
 %3C marker
+Holder
 s.size()
@@ -2490,16 +2490,22 @@
 = marker
+Holder
 s.keyAt(
@@ -2526,16 +2526,22 @@
   marker
+Holder
 s.get(id
@@ -2572,24 +2572,365 @@
    %7D%0A    %7D%0A%0A
+    @Override%0A    public String toString() %7B%0A        List%3CString%3E list = new ArrayList%3C%3E();%0A        for (int i = 0; i %3C this.markerHolders.size(); i++) %7B%0A            long id = markerHolders.keyAt(i);%0A            list.add(id + %22=%22 + markerHolders.get(id));%0A        %7D%0A        return %22MarkerManager%7B%22 + TextUtils.join(%22, %22, list) + %22%7D%22;%0A    %7D%0A%0A
     static c
@@ -3337,20 +3337,144 @@
 %0A        %7D%0A%0A
+        @Override%0A        public String toString() %7B%0A            return marker.getId() + %22/%22 + marker.getTitle();%0A        %7D%0A
     %7D%0A%7D%0A

fix possible crashes in MarkerManager