package org.opentripplanner.streets;

import com.google.common.base.Strings;
import gnu.trove.map.TIntIntMap;
import gnu.trove.map.hash.TIntIntHashMap;

/**
 * For design and debugging purposes, a simple class that tracks the frequency of different numbers.
 */
public class Histogram {

    private String title;
    private TIntIntMap bins = new TIntIntHashMap();
    private int maxBin = 0;

    public Histogram (String title) {
        this.title = title;
    }

    public void add (int i) {
        bins.adjustOrPutValue(i, 1, 1);
        if (i > maxBin) {
            maxBin = i;
        }
    }

    private static String makeBar (int value, int max) {
        final int WIDTH = 20;
        int n = value * WIDTH / max;
        String bar = Strings.repeat("#", n);
        String space = Strings.repeat("_", WIDTH - n);
        return bar + space + "  ";
    }

    public void display () {
        int[] lessEqual = new int[maxBin + 1];
        System.out.println("--- Histogram: " + title + " ---");
        System.out.println(" n       ==      <=       >");
        int sum = 0;
        int maxCount = 0;
        for (int i = 0; i <= maxBin; i++) {
            int n = bins.get(i);
            if (n > maxCount) {
                maxCount = n;
            }
            sum += n;
            lessEqual[i] = sum;
        }
        // Sum now equals the sum of all bins.
        for (int i = 0; i <= maxBin; i++) {
            if (((double)lessEqual[i]) / sum > 0.999) {
                System.out.println("Ending display at 99.9% of total objects.");
                break;
            }
            System.out.printf("%2d: %7d %7d %7d ", i, bins.get(i), lessEqual[i], sum - lessEqual[i]);
            System.out.print(makeBar(bins.get(i), maxCount));
            System.out.print(makeBar(lessEqual[i], sum));
            System.out.print(makeBar(sum - lessEqual[i], sum));
            System.out.println();
        }
        System.out.println();
    }

}

@@ -70,16 +70,59 @@
 trings;%0A
+import gnu.trove.iterator.TIntIntIterator;%0A
 import g
@@ -427,17 +427,129 @@
 axBin = 
-0
+Integer.MIN_VALUE;%0A    private int minBin = Integer.MAX_VALUE;%0A    private long count = 0;%0A    private int maxVal
 ;%0A%0A    p
@@ -653,16 +653,46 @@
 %0A       
+ count++;%0A        int binVal =
  bins.ad
@@ -720,49 +720,170 @@
 1);%0A
-        if (i %3E maxBin) %7B%0A            max
+%0A        if (binVal %3E maxVal)%0A            maxVal = binVal;%0A%0A        if (i %3E maxBin) %7B%0A            maxBin = i;%0A        %7D%0A%0A        if (i %3C minBin) %7B%0A            min
 Bin 
@@ -1429,33 +1429,38 @@
    for (int i = 
-0
+minBin
 ; i %3C= maxBin; i
@@ -2270,10 +2270,1568 @@
 %0A    %7D%0A%0A
+    public void displayHorizontal () %7B%0A        System.out.println(%22--- Histogram: %22 + title + %22 ---%22);%0A%0A        // TODO: horizontal scale%0A        double vscale = 30d / maxVal;%0A%0A        for (int i = 0; i %3C 30; i++) %7B%0A            StringBuilder row = new StringBuilder(maxBin - minBin + 1);%0A%0A            int minValToDisplayThisRow = (int) (i / vscale);%0A            for (int j = minBin; j %3C= maxBin; j++) %7B%0A                if (bins.get(j) %3E minValToDisplayThisRow)%0A                    row.append('#');%0A                else%0A                    row.append(' ');%0A            %7D%0A%0A            System.out.println(row);%0A        %7D%0A%0A        // put a mark at zero and at the ends%0A        if (minBin %3C 0 && maxBin %3E 0) %7B%0A            StringBuilder ticks = new StringBuilder();%0A            for (int i = minBin; i %3C 0; i++)%0A                ticks.append(' ');%0A            ticks.append('%7C');%0A            System.out.println(ticks);%0A        %7D%0A%0A        StringBuilder row = new StringBuilder();%0A        for (int i = minBin; i %3C maxBin; i++) %7B%0A            row.append(' ');%0A        %7D%0A%0A        String start = new Integer(minBin).toString();%0A        row.replace(0, start.length(), start);%0A        String end = new Integer(maxBin).toString();%0A        row.replace(row.length() - end.length(), end.length(), end);%0A        System.out.println(row);%0A    %7D%0A%0A    public int mean() %7B%0A        long sum = 0;%0A        for (TIntIntIterator it = bins.iterator(); it.hasNext();) %7B%0A            it.advance();%0A%0A            sum += it.key() * it.value();%0A        %7D%0A%0A        return (int) (sum / count);%0A    %7D%0A
 %7D%0A

bump histogram file version.