/*
 * *****************************************************************************
 * Copyright (C) 2007, International Business Machines Corporation and others.
 * All Rights Reserved.
 * *****************************************************************************
 */
package com.ibm.icu.impl;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import com.ibm.icu.lang.UCharacter;
import com.ibm.icu.text.UTF16;

/**
 * TextTrieMap is a trie implementation for supporting
 * fast prefix match for the key.
 */
public class TextTrieMap {
    /**
     * Constructs a TextTrieMap object.
     * 
     * @param ignoreCase true to use case insensitive match
     */
    public TextTrieMap(boolean ignoreCase) {
        this.ignoreCase = ignoreCase;
    }

    /**
     * Adds the text key and its associated object in this object.
     * 
     * @param text The text.
     * @param o The object associated with the text.
     */
    public synchronized void put(String text, Object o) {
        CharacterNode node = root;
        for (int i = 0; i < text.length(); i++) {
            int ch = UTF16.charAt(text, i);
            node = node.addChildNode(ch);
            if (UTF16.getCharCount(ch) == 2) {
                i++;
            }
        }
        node.addObject(o);
    }

    /**
     * Gets an iterator of the objects associated with the
     * longest prefix matching string key.
     * 
     * @param text The text to be matched with prefixes.
     * @return An iterator of the objects associated with
     * the longest prefix matching matching key, or null
     * if no matching entry is found.
     */
    public Iterator get(String text) {
        return get(text, 0);
    }

    /**
     * Gets an iterator of the objects associated with the
     * longest prefix matching string key starting at the 
     * specified position.
     * 
     * @param text The text to be matched with prefixes.
     * @param start The start index of of the text
     * @return An iterator of the objects associated with the
     * longest prefix matching matching key, or null if no 
     * matching entry is found.
     */
    public Iterator get(String text, int start) {
        LongestMatchHandler handler = new LongestMatchHandler();
        find(text, start, handler);
        return handler.getMatches();
    }

    public void find(String text, ResultHandler handler) {
        find(text, 0, handler);
    }
    
    public void find(String text, int start, ResultHandler handler) {
        find(root, text, start, start, handler);
    }

    /*
     * Find an iterator of the objects associated with the
     * longest prefix matching string key under the specified node.
     * 
     * @param node The character node in this trie.
     * @param text The text to be matched with prefixes.
     * @param start The start index within the text.
     * @param index The current index within the text.
     * @param handler The result handler, ResultHandler#handlePrefixMatch
     * is called when any prefix match is found.
     */
    private synchronized void find(CharacterNode node, String text,
            int start, int index, ResultHandler handler) {
        Iterator itr = node.iterator();
        if (itr != null) {
            if (!handler.handlePrefixMatch(index - start, itr)) {
                return;
            }
        }
        if (index < text.length()) {
            List childNodes = node.getChildNodes();
            if (childNodes == null) {
                return;
            }
            int ch = UTF16.charAt(text, index);
            int chLen = UTF16.getCharCount(ch);
            for (int i = 0; i < childNodes.size(); i++) {
                CharacterNode child = (CharacterNode)childNodes.get(i);
                if (compare(ch, child.getCharacter())) {
                    find(child, text, start, index + chLen, handler);
                    break;
                }
            }
        }
    }
    
    /**
     * A private method used for comparing two characters.
     * 
     * @param ch1 The first character.
     * @param ch2 The second character.
     * @return true if the first character matches the second.
     */
    private boolean compare(int ch1, int ch2) {
        if (ch1 == ch2) {
            return true;
        }
        else if (ignoreCase) {
            if (UCharacter.toLowerCase(ch1) == UCharacter.toLowerCase(ch2)) {
                return true;
            }
            else if (UCharacter.toUpperCase(ch1) == UCharacter.toUpperCase(ch2)) {
                return true;
            }
        }
        return false;
    }

    // The root node of this trie
    private CharacterNode root = new CharacterNode(0);

    // Character matching option
    boolean ignoreCase;

    /**
     * Inner class representing a character node in the trie.
     */
    private class CharacterNode {
        int character;
        List children;
        List objlist;

        /**
         * Constructs a node for the character.
         * 
         * @param ch The character associated with this node.
         */
        public CharacterNode(int ch) {
            character = ch;
        }

        /**
         * Gets the character associated with this node.
         * 
         * @return The character
         */
        public int getCharacter() {
            return character;
        }

        /**
         * Adds the object to the node.
         *  
         * @param obj The object set in the leaf node.
         */
        public void addObject(Object obj) {
            if (objlist == null) {
                objlist = new LinkedList();
            }
            objlist.add(obj);
        }

        /**
         * Gets an iterator of the objects associated with
         * the leaf node.
         * 
         * @return The iterator or null if no objects are
         * associated with this node.
         */
        public Iterator iterator() {
            if (objlist == null) {
                return null;
            }
            return objlist.iterator();
        }

        /**
         * Adds a child node for the character under this character
         * node in the trie.  When the matching child node already
         * exists, the reference of the existing child node is
         * returned.
         * 
         * @param ch The character associated with a child node.
         * @return The child node.
         */
        public CharacterNode addChildNode(int ch) {
            if (children == null) {
                children = new ArrayList();
                CharacterNode newNode = new CharacterNode(ch);
                children.add(newNode);
                return newNode;
            }
            CharacterNode node = null;
            for (int i = 0; i < children.size(); i++) {
                CharacterNode cur = (CharacterNode)children.get(i);
                if (compare(ch, cur.getCharacter())) {
                    node = cur;
                    break;
                }               
            }
            if (node == null) {
                node = new CharacterNode(ch);
                children.add(node);
            }
            return node;
        }

        /**
         * Gets the list of child nodes under this node.
         * 
         * @return The list of child nodes.
         */
        public List getChildNodes() {
            return children;
        }
    }

    /**
     * Callback handler for processing prefix matches used by
     * find method.
     */
    public interface ResultHandler {
        /**
         * Handles a prefix key match
         * 
         * @param matchLength Matched key's length
         * @param values An iterator of the objects associated with the matched key
         * @return Return true to continue the search in the trie, false to quit.
         */
        public boolean handlePrefixMatch(int matchLength, Iterator values);
    }

    private static class LongestMatchHandler implements ResultHandler {
        private Iterator matches = null;
        private int length = 0;

        public boolean handlePrefixMatch(int matchLength, Iterator values) {
            if (matchLength > length) {
                length = matchLength;
                matches = values;
            }
            return true;
        }

        public Iterator getMatches() {
            return matches;
        }
    }
}
