package org.greenstone.atlas.server;

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

public class GazetteerTrieSmallNode implements Serializable
{
	private static final long serialVersionUID = 8121262849365540679L;
	protected boolean _nameEnd = false;
	// protected GazetteerTrieSmallNode[] _children = new
	// GazetteerTrieSmallNode[26];
	protected HashMap<Character, GazetteerTrieSmallNode> _unicodeCharacters = null;

	/**
	 * Basic constructor for a non-unicode trie node
	 * 
	 * @param nameEnd
	 *            defines whether the new node represents the end of a place
	 *            name
	 */
	protected GazetteerTrieSmallNode(boolean nameEnd)
	{
		_nameEnd = nameEnd;
	}

	/**
	 * Add a child to the current node
	 * 
	 * @param c
	 *            is the character used to decide where to add the child node
	 * @param nameEnd
	 *            is whether or not this character represents the end of a place
	 *            name
	 * @return true if a child was added and false if one already existed
	 */
	protected boolean addChild(char c, boolean nameEnd)
	{
		if (c >= 65 && c <= 90)
		{
			c += 32;
		}
		// If the node does not currently have a unicode character map then make
		// one
		if (_unicodeCharacters == null)
		{
			_unicodeCharacters = new HashMap<Character, GazetteerTrieSmallNode>();
			_unicodeCharacters.put(c, new GazetteerTrieSmallNode(nameEnd));
			return true;
		}

		// Add the unicode character to the map only if it either does not exist
		// already or signifies the end of a place name
		GazetteerTrieSmallNode value;
		if ((value = _unicodeCharacters.get(c)) != null)
		{
			if (value.isNameEnd())
			{
				return false;
			}
			else
			{
				value.setNameEnd(nameEnd);
			}
		}
		else
		{
			_unicodeCharacters.put(c, new GazetteerTrieSmallNode(nameEnd));
		}

		return true;
	}

	/**
	 * @return whether or not this node represents the end of a place name
	 */
	protected boolean isNameEnd()
	{
		return _nameEnd;
	}

	/**
	 * Set whether or not this node represents the end of a place name
	 * 
	 * @param nameEnd
	 *            is the value to set it to
	 */
	protected void setNameEnd(boolean nameEnd)
	{
		_nameEnd = nameEnd;
	}

	/**
	 * Returns the child at the given index
	 * 
	 * @param index
	 *            is the index of the child to return
	 * @return the child at the given index
	 */
	protected GazetteerTrieSmallNode getChild(char c)
	{
		if (c >= 65 && c <= 90)
		{
			c += 32;
		}

		if (_unicodeCharacters == null)
		{
			return null;
		}
		return _unicodeCharacters.get(c);
	}

	public void output()
	{
		System.out.println("Please implement a output method for GazetteerTrieSmallNode");
	}
}
