/**
 *******************************************************************************
 * Copyright (C) 1996-2010, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 *
 * $Date: 2009-08-07 15:01:31 -0700 (Fri, 07 Aug 2009) $
 * $Revision: 4231 $
 *
 *******************************************************************************
 */

package com.ibm.icu.dev.test.collator;


import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;

public class Counter<T> implements Iterable<T>, Comparable<Counter<T>> {
  Map<T,RWLong> map;
  Comparator<T> comparator;
  
  public Counter() {
    this(null);
  }
  
  public Counter(Comparator<T> comparator) {
    if (comparator != null) {
      this.comparator = comparator;
      map = new TreeMap<T, RWLong>(comparator);
    } else {
      map = new LinkedHashMap<T, RWLong>();
    }
  }
  
  static private final class RWLong implements Comparable<RWLong> {
    // the uniqueCount ensures that two different RWIntegers will always be different
    static int uniqueCount;
    public long value;
    private final int forceUnique;
    {
      synchronized (RWLong.class) { // make thread-safe
        forceUnique = uniqueCount++;
      }
    }

    public int compareTo(RWLong that) {
      if (that.value < value) return -1;
      if (that.value > value) return 1;
      if (this == that) return 0;
      synchronized (this) { // make thread-safe
        if (that.forceUnique < forceUnique) return -1;
      }
      return 1; // the forceUnique values must be different, so this is the only remaining case
    }
    public String toString() {
      return String.valueOf(value);
    }
  }

  public Counter<T> add(T obj, long countValue) {
    RWLong count = map.get(obj);
    if (count == null) map.put(obj, count = new RWLong());
    count.value += countValue;
    return this;
  }

  public long getCount(T obj) {
      return get(obj);
    }

  public long get(T obj) {
      RWLong count = map.get(obj);
      return count == null ? 0 : count.value;
    }

  public Counter<T> clear() {
    map.clear();
    return this;
  }

  public long getTotal() {
    long count = 0;
    for (T item : map.keySet()) {
      count += map.get(item).value;
    }
    return count;
  }

  public int getItemCount() {
    return size();
  }
  
  private static class Entry<T> {
    RWLong count;
    T value;
    int uniqueness;
    public Entry(RWLong count, T value, int uniqueness) {
      this.count = count;
      this.value = value;
      this.uniqueness = uniqueness;
    }
  }
  
  private static class EntryComparator<T> implements Comparator<Entry<T>>{
    int countOrdering;
    Comparator<T> byValue;
    
    public EntryComparator(boolean ascending, Comparator<T> byValue) {
      countOrdering = ascending ? 1 : -1;
      this.byValue = byValue;
    }
    public int compare(Entry<T> o1, Entry<T> o2) {
      if (o1.count.value < o2.count.value) return -countOrdering;
      if (o1.count.value > o2.count.value) return countOrdering;
      if (byValue != null) {
        return byValue.compare(o1.value, o2.value);
      }
      return o1.uniqueness - o2.uniqueness;
    }
  }

  public Set<T> getKeysetSortedByCount(boolean ascending) {
    return getKeysetSortedByCount(ascending, null);
  }
  
  public Set<T> getKeysetSortedByCount(boolean ascending, Comparator<T> byValue) {
    Set<Entry<T>> count_key = new TreeSet<Entry<T>>(new EntryComparator<T>(ascending, byValue));
    int counter = 0;
    for (T key : map.keySet()) {
      count_key.add(new Entry<T>(map.get(key), key, counter++));
    }
    Set<T> result = new LinkedHashSet<T>();
    for (Entry<T> entry : count_key) {
       result.add(entry.value);
    }
    return result;
  }

  public Set<T> getKeysetSortedByKey() {
    Set<T> s = new TreeSet<T>(comparator);
    s.addAll(map.keySet());
    return s;
  }

//public Map<T,RWInteger> getKeyToKey() {
//Map<T,RWInteger> result = new HashMap<T,RWInteger>();
//Iterator<T> it = map.keySet().iterator();
//while (it.hasNext()) {
//Object key = it.next();
//result.put(key, key);
//}
//return result;
//}

  public Set<T> keySet() {
    return map.keySet();
  }

  public Iterator<T> iterator() {
    return map.keySet().iterator();
  }

  public Map<T, RWLong> getMap() {
    return map; // older code was protecting map, but not the integer values.
  }

  public int size() {
    return map.size();
  }

  public String toString() {
    return map.toString();
  }

  public Counter<T> addAll(Collection<T> keys, int delta) {
    for (T key : keys) {
      add(key, delta);
    }
    return this;
  }
  
  public Counter<T> addAll(Counter<T> keys) {
    for (T key : keys) {
      add(key, keys.getCount(key));
    }
    return this;
  }

  public int compareTo(Counter<T> o) {
    Iterator<T> i = map.keySet().iterator();
    Iterator<T> j = o.map.keySet().iterator();
    while (true) {
      boolean goti = i.hasNext();
      boolean gotj = j.hasNext();
      if (!goti || !gotj) {
        return goti ? 1 : gotj ? -1 : 0;
      }
      T ii = i.next();
      T jj = i.next();
      int result = ((Comparable<T>)ii).compareTo(jj);
      if (result != 0) {
        return result;
      }
      final long iv = map.get(ii).value;
      final long jv = o.map.get(jj).value;
      if (iv != jv) return iv < jv ? -1 : 0;
    }
  }

  public Counter<T> increment(T key) {
    return add(key, 1);
  }

public boolean containsKey(T key) {
    return map.containsKey(key);
}

public boolean equals(Object o) {
    return map.equals(o);
}

public int hashCode() {
    return map.hashCode();
}

public boolean isEmpty() {
    return map.isEmpty();
}

public Counter<T> remove(T key) {
    map.remove(key);
    return this;
}

//public RWLong put(T key, RWLong value) {
//    return map.put(key, value);
//}
//
//public void putAll(Map<? extends T, ? extends RWLong> t) {
//    map.putAll(t);
//}
//
//public Set<java.util.Map.Entry<T, Long>> entrySet() {
//    return map.entrySet();
//}
//
//public Collection<RWLong> values() {
//    return map.values();
//}

}