package com.conveyal.r5.analyst;

import com.conveyal.r5.profile.StreetMode;
import gnu.trove.map.TIntIntMap;
import gnu.trove.map.TIntObjectMap;
import gnu.trove.map.hash.TIntIntHashMap;
import gnu.trove.map.hash.TIntObjectHashMap;

/**
 * Contains a map from stop vertex to the clock time at which, and mode by which, the stop is reached, plus utility
 * methods for updating/processing this map.
 */
public class StreetTimesAndModes {
    public TIntObjectMap<StreetTimeAndMode> streetTimesAndModes = new TIntObjectHashMap<StreetTimeAndMode>();

    public static class StreetTimeAndMode {
        public int time;
        public StreetMode mode;

        public StreetTimeAndMode(int time, StreetMode mode) {
            this.time = time;
            this.mode = mode;
        }

        @Override
        public String toString(){
            return mode.toString() +(" ") + (String.format("%.1f", time / 60.0)) + (" min.");
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            StreetTimeAndMode streetTimeAndMode = (StreetTimeAndMode) o;
            return this.mode == streetTimeAndMode.mode &&
                    this.time == streetTimeAndMode.time;
        }
    };

    /**
     * Strips out mode information
     * @return map from stop vertex to time
     */
    public TIntIntMap getTimes() {
        TIntIntMap times = new TIntIntHashMap();
        streetTimesAndModes.forEachEntry((stop, timeAndMode) -> {
            times.put(stop, timeAndMode.time);
            return true; // Trove signal to continue iteration
        });
        return times;
    }

    /**
     * Merges the supplied values with the ones in this map, keeping the value with the minimum time when keys collide.
     * @param times map from stop vertex to clock time at which the stop was reached in a street search
     * @param streetMode used to obtain these times
     */
    void update(TIntIntMap times, StreetMode streetMode) {
        times.forEachEntry((stop, time) -> {
            if (!streetTimesAndModes.containsKey(stop) || time < streetTimesAndModes.get(stop).time) {
                streetTimesAndModes.put(stop, new StreetTimeAndMode(time, streetMode));
            }
            return true;
        });
    }

}

@@ -227,16 +227,43 @@
 shMap;%0A%0A
+import java.util.Objects;%0A%0A
 /**%0A * C
@@ -282,28 +282,27 @@
 p from stop 
-vert
+ind
 ex to the cl
@@ -299,29 +299,31 @@
  to the 
-clock
+elapsed
  time 
-at
+in
  which, 
@@ -1327,24 +1327,141 @@
 ;%0A        %7D%0A
+%0A        @Override%0A        public int hashCode() %7B%0A            return Objects.hash(this.time, this.mode);%0A        %7D%0A%0A
     %7D;%0A%0A    

add custom hash function, and correct javadoc