/*
 * KeywordMap.java - Fast keyword->id map
 * Copyright (C) 1998, 1999 Slava Pestov
 * Copyright (C) 1999 Mike Dillon
 *
 * You may use and modify this package for any purpose. Redistribution is
 * permitted, in both source and binary form, provided that this notice
 * remains intact in all source distributions of this package.
 */

package processing.app.syntax;

import javax.swing.text.Segment;

/**
 * A <code>KeywordMap</code> is similar to a hashtable in that it maps keys
 * to values. However, the `keys' are Swing segments. This allows lookups of
 * text substrings without the overhead of creating a new string object.
 * <p>
 * This class is used by <code>CTokenMarker</code> to map keywords to ids.
 *
 * @author Slava Pestov, Mike Dillon
 * @version $Id: KeywordMap.java 2050 2006-03-11 00:50:01Z fry $
 */
public class KeywordMap
{
        /**
         * Creates a new <code>KeywordMap</code>.
         * @param ignoreCase True if keys are case insensitive
         */
        public KeywordMap(boolean ignoreCase)
        {
                this(ignoreCase, 52);
                this.ignoreCase = ignoreCase;
        }

        /**
         * Creates a new <code>KeywordMap</code>.
         * @param ignoreCase True if the keys are case insensitive
         * @param mapLength The number of `buckets' to create.
         * A value of 52 will give good performance for most maps.
         */
        public KeywordMap(boolean ignoreCase, int mapLength)
        {
                this.mapLength = mapLength;
                this.ignoreCase = ignoreCase;
                map = new Keyword[mapLength];
        }

        /**
         * Looks up a key.
         * @param text The text segment
         * @param offset The offset of the substring within the text segment
         * @param length The length of the substring
         */
        public byte lookup(Segment text, int offset, int length)
        {
                if(length == 0)
                        return Token.NULL;
                Keyword k = map[getSegmentMapKey(text, offset, length)];
                while(k != null)
                {
                        if(length != k.keyword.length)
                        {
                                k = k.next;
                                continue;
                        }
                        if(SyntaxUtilities.regionMatches(ignoreCase,text,offset,
                                k.keyword))
                                return k.id;
                        k = k.next;
                }
                return Token.NULL;
        }

        /**
         * Adds a key-value mapping.
         * @param keyword The key
         * @param id The value
         */
        public void add(String keyword, byte id)
        {
                int key = getStringMapKey(keyword);
                map[key] = new Keyword(keyword.toCharArray(),id,map[key]);
        }

        /**
         * Returns true if the keyword map is set to be case insensitive,
         * false otherwise.
         */
        public boolean getIgnoreCase()
        {
                return ignoreCase;
        }

        /**
         * Sets if the keyword map should be case insensitive.
         * @param ignoreCase True if the keyword map should be case
         * insensitive, false otherwise
         */
        public void setIgnoreCase(boolean ignoreCase)
        {
                this.ignoreCase = ignoreCase;
        }

        // protected members
        protected int mapLength;

        protected int getStringMapKey(String s)
        {
                return (Character.toUpperCase(s.charAt(0)) +
                                Character.toUpperCase(s.charAt(s.length()-1)))
                                % mapLength;
        }

        protected int getSegmentMapKey(Segment s, int off, int len)
        {
                return (Character.toUpperCase(s.array[off]) +
                                Character.toUpperCase(s.array[off + len - 1]))
                                % mapLength;
        }

        // private members
        class Keyword
        {
                public Keyword(char[] keyword, byte id, Keyword next)
                {
                        this.keyword = keyword;
                        this.id = id;
                        this.next = next;
                }

                public char[] keyword;
                public byte id;
                public Keyword next;
        }

        private Keyword[] map;
        private boolean ignoreCase;
}
