package kinesisFHM.utilities;

import java.io.IOException;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

public class HashTable2D<KeyType> implements Serializable {

	private HashMap<KeyType, HashMap<KeyType, Float>> e;
	private HashMap<KeyType, HashMap<KeyType, Float>> f;
	
	public HashTable2D() {
		e = new HashMap<KeyType, HashMap<KeyType, Float>>();
		f = new HashMap<KeyType, HashMap<KeyType, Float>>();
	}
	// gets the value at the specified indices or the default if the value
	// doesn't exist
	public Float get(KeyType i1, KeyType i2) {
		HashMap<KeyType, Float> h1;
		Float r; 
		if ( (h1 = e.get(i1)) != null)
			if ( (r = h1.get(i2)) != null) return r;
			else return 0f;
		else return 0f;
	}
	
	public HashMap<KeyType, Float> getRow(KeyType i) {
		HashMap<KeyType, Float> r = e.get(i);
		if (r == null) return new HashMap<KeyType, Float>();
		else return r;
	}

	public HashMap<KeyType, Float> getCol(KeyType i) {
		HashMap<KeyType, Float> r = f.get(i);
		if (r == null) return new HashMap<KeyType, Float>();
		else return r;
	}
/*	
	public Map.Entry<KeyType, Float> rowMax(KeyType i) {
		Float max = Float.MIN_VALUE;
		Map.Entry<KeyType, Float> maxEntry = null;
		for (Map.Entry<KeyType, Float> e : getRow(i).entrySet())
			if ( e.getValue() > max) { maxEntry = e; max = e.getValue(); }
		return maxEntry;
	}

	public Map.Entry<KeyType, Float> colMax(KeyType i) {
		Float max = Float.MIN_VALUE;
		Map.Entry<KeyType, Float> maxEntry = null;
		for (Map.Entry<KeyType, Float> e : getCol(i).entrySet())
			if ( e.getValue() > max) { maxEntry = e; max = e.getValue(); }
		return maxEntry;
	}
*/
	public Map.Entry<KeyType, Float> rowMaxButNot(KeyType i, KeyType butNot) {
		Float max = Float.MIN_VALUE;
		Map.Entry<KeyType, Float> maxEntry = null;
		for (Map.Entry<KeyType, Float> e : getRow(i).entrySet())
			if ( e.getValue() > max && !e.getKey().equals(butNot) ) { maxEntry = e; max = e.getValue(); }
		return maxEntry;
	}

	public Map.Entry<KeyType, Float> colMaxButNot(KeyType i, KeyType butNot) {
		Float max = Float.MIN_VALUE;
		Map.Entry<KeyType, Float> maxEntry = null;
		for (Map.Entry<KeyType, Float> e : getCol(i).entrySet())
			if ( e.getValue() > max && !e.getKey().equals(butNot) ) { maxEntry = e; max = e.getValue(); }
		return maxEntry;
	}


	// returns the previous value at the specified indices or
	// the default if there was no previous value
	public Float set(KeyType i1, KeyType i2, Float v) {
		HashMap<KeyType, Float> h1;
		Float r; 
		if ( (h1 = e.get(i1)) == null) {
			h1 = new HashMap<KeyType, Float>();
			e.put(i1, h1);
		}
		if ( (r = h1.put(i2, v)) == null) r = 0f;

		HashMap<KeyType, Float> h2;
		if ( (h2 = f.get(i2)) == null) {
			h2 = new HashMap<KeyType, Float>();
			f.put(i2, h2);
		}
		h2.put(i1, v);

		return r;
	}
	
	private void writeObject(java.io.ObjectOutputStream out) throws IOException {
		out.writeObject(e);
		out.writeObject(f);
	}

	private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
		this.e = (HashMap<KeyType, HashMap<KeyType, Float>>) in.readObject();
		this.f = (HashMap<KeyType, HashMap<KeyType, Float>>) in.readObject();
	}
	
	public String toString() {
		return e.toString() + "\n" + f.toString();
	}
}
