package org.apache.slide.util;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/*
 * Created on 01.12.2003
 *
 * To change the template for this generated file go to
 * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
 */

/**
 * @author olli
 *
 * To change the template for this generated type comment go to
 * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
 */
public class TableDFAMap implements Map {

	String symbols;
	State startState;
	Map symbolsCache = null;

	public TableDFAMap(String symbols) {
		this.symbols = symbols;
		// HACK
		this.symbols = "key-valu0123456789";
		startState = new State();
//		createSymbolsCache();
	}

	void createSymbolsCache() {
		symbolsCache = new HashMap();
		for (int i = 0; i < symbols.length(); i++) {
			char c = symbols.charAt(i);
			symbolsCache.put(new Character(c), new Integer(i));
		}
	}

	int charToSymbol(char c) {
		// HACK
		switch (c) {
			case 'k' : return 0;
			case 'e' : return 1;
			case 'y' : return 2;
			case '-' : return 3;
			case 'v' : return 4;
			case 'a' : return 5;
			case 'l' : return 6;
			case 'u' : return 7;
			case '0' : return 8;
			case '1' : return 9;
			case '2' : return 10;
			case '3' : return 11;
			case '4' : return 12;
			case '5' : return 13;
			case '6' : return 14;
			case '7' : return 15;
			case '8' : return 16;
			case '9' : return 17;
			
		}
		if (symbolsCache == null) {

			for (int i = 0; i < symbols.length(); i++) {
				if (symbols.charAt(i) == c) {
					return i;
				}
			}
		} else {
			return ((Integer) symbolsCache.get(new Character(c))).intValue();
		}
		throw new RuntimeException(
			"character '" + c + "' is not part of symbols '" + symbols + "'");

	}

	private class State {
		Object value = null;
		Object key = null;

		State[] transitStates = new State[symbols.length()];

		State transit(Character c) {
			int symbol = charToSymbol(c.charValue());
			return transitStates[symbol];
		}

		void putTransition(Character c, State state) {
			int symbol = charToSymbol(c.charValue());
			transitStates[symbol] = state;
		}

		Object get(char[] key, int pos) {
			if (pos == key.length) {
				return value;
			} else {
				Character c = new Character(key[pos]);
				State nextState = transit(c);
				if (nextState == null) {
					return null;
				} else {
					return nextState.get(key, pos + 1);
				}

			}
		}

		Object remove(char[] key, int pos) {
			// XXX simply overwrite
			return put(key, pos, null);
		}

		Object put(char[] key, int pos, Object value) {
			if (pos == key.length) {
				this.key = new String(key);
				Object oldValue = this.value;
				this.value = value;
				return oldValue;
			} else {
				Character c = new Character(key[pos]);
				State nextState = transit(c);
				if (nextState == null) {
					nextState = new State();
					putTransition(c, nextState);
				}
				return nextState.put(key, pos + 1, value);
			}
		}
	}

	/* (non-Javadoc)
	 * @see java.util.Map#size()
	 */
	public int size() {
		// TODO Auto-generated method stub
		return 0;
	}

	/* (non-Javadoc)
	 * @see java.util.Map#isEmpty()
	 */
	public boolean isEmpty() {
		// TODO Auto-generated method stub
		return false;
	}

	/* (non-Javadoc)
	 * @see java.util.Map#containsKey(java.lang.Object)
	 */
	public boolean containsKey(Object key) {
		// TODO Auto-generated method stub
		return false;
	}

	/* (non-Javadoc)
	 * @see java.util.Map#containsValue(java.lang.Object)
	 */
	public boolean containsValue(Object value) {
		// TODO Auto-generated method stub
		return false;
	}

	/* (non-Javadoc)
	 * @see java.util.Map#get(java.lang.Object)
	 */
	public Object get(Object key) {
		return startState.get(key.toString().toCharArray(), 0);
	}

	/* (non-Javadoc)
	 * @see java.util.Map#put(java.lang.Object, java.lang.Object)
	 */
	public Object put(Object key, Object value) {
		return startState.put(key.toString().toCharArray(), 0, value);
	}

	/* (non-Javadoc)
	 * @see java.util.Map#remove(java.lang.Object)
	 */
	public Object remove(Object key) {
		return put(key, null);
	}

	/* (non-Javadoc)
	 * @see java.util.Map#putAll(java.util.Map)
	 */
	public void putAll(Map t) {
		// TODO Auto-generated method stub

	}

	/* (non-Javadoc)
	 * @see java.util.Map#clear()
	 */
	public void clear() {
		// TODO Auto-generated method stub
	}

	/* (non-Javadoc)
	 * @see java.util.Map#keySet()
	 */
	public Set keySet() {
		// TODO Auto-generated method stub
		return null;
	}

	/* (non-Javadoc)
	 * @see java.util.Map#values()
	 */
	public Collection values() {
		// TODO Auto-generated method stub
		return null;
	}

	/* (non-Javadoc)
	 * @see java.util.Map#entrySet()
	 */
	public Set entrySet() {
		// TODO Auto-generated method stub
		return null;
	}
}
