/*
 * Copyright (C) 2008-2012  OMRON SOFTWARE Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package jp.co.omronsoft.openwnn;


/**
 * The interface of dictionary searcher used by {@link OpenWnn}.
 *
 * @author Copyright (C) 2008-2009, OMRON SOFTWARE CO., LTD.  All Rights Reserved.
 */
public interface WnnDictionary {
    /*
     * DEFINITION OF CONSTANTS
     */
    /**
     * Predefined approximate pattern set (capital letters from small letters).
     * 
     * This pattern includes the rules for ambiguous searching capital letters from small letters.<br>
     * ex. "a" to "A", "b" to "B", ... , "z" to "Z"
     */
    public static final int APPROX_PATTERN_EN_TOUPPER               = 0;
    /**
     * Predefined approximate pattern set (small letters from capital letters).
     *
     * This pattern includes the rules for ambiguous searching small letters from capital letters.<br>
     * ex. "A" to "a", "B" to "b", ... , "Z" to "z"
     */
    public static final int APPROX_PATTERN_EN_TOLOWER               = 1;
    /**
     * Predefined approximate pattern set (QWERTY neighbor keys).
     *
     * This pattern includes the rules for ambiguous searching neighbor keys on QWERTY keyboard.
     * Only alphabet letters are defined; numerical or symbol letters are not defined as the rules.<br>
     * ex. "a" to "q"/"w"/"s"/"z", "b" to "v"/"g"/"h"/"n", ... ,"z" to "a"/"s"/"x"
     */
    public static final int APPROX_PATTERN_EN_QWERTY_NEAR           = 2;
    /**
     * Predefined approximate pattern set (QWERTY neighbor keys/capital letters).
     *
     * This pattern includes the rules for ambiguous searching capital letters of neighbor keys on QWERTY keyboard.
     * Only alphabet letters are defined; numerical or symbol letters are not defined as the rules.<br>
     * ex. "a" to "Q"/"W"/"S"/"Z", "b" to "V"/"G"/"H"/"N", ... ,"z" to "A"/"S"/"X"
     */
    public static final int APPROX_PATTERN_EN_QWERTY_NEAR_UPPER     = 3;
    /**
     * Predefined approximate pattern set (for Japanese 12-key keyboard).
     *
     * This pattern includes the standard rules for Japanese multi-tap 12-key keyboard.
     * ex. "&#x306F;" to "&#x3070;"/"&#x3071;", "&#x3064;" to "&#x3063;"/"&#x3065;"
     */
    public static final int APPROX_PATTERN_JAJP_12KEY_NORMAL        = 4;

    /** Search operation mode (exact matching). */
    public static final int SEARCH_EXACT                            = 0;
    /** Search operation mode (prefix matching). */
    public static final int SEARCH_PREFIX                           = 1;
    /** Search operation mode (link search). */
    public static final int SEARCH_LINK                             = 2;

    /** Sort order (frequency in descending). */
    public static final int ORDER_BY_FREQUENCY                      = 0;
    /** Sort order (character code of key string in ascending). */
    public static final int ORDER_BY_KEY                            = 1;

    /** Type of a part of speech (V1) */
    public static final int POS_TYPE_V1                             = 0;
    /** Type of a part of speech (V2) */
    public static final int POS_TYPE_V2                             = 1;
    /** Type of a part of speech (V3) */
    public static final int POS_TYPE_V3                             = 2;
    /** Type of a part of speech (Top of sentence) */
    public static final int POS_TYPE_BUNTOU                         = 3;
    /** Type of a part of speech (Single Chinese character) */
    public static final int POS_TYPE_TANKANJI                       = 4;
    /** Type of a part of speech (Numeric) */
    public static final int POS_TYPE_SUUJI                          = 5;
    /** Type of a part of speech (Noun) */
    public static final int POS_TYPE_MEISI                          = 6;
    /** Type of a part of speech (Person's name) */
    public static final int POS_TYPE_JINMEI                         = 7;
    /** Type of a part of speech (Place name) */
    public static final int POS_TYPE_CHIMEI                         = 8;
    /** Type of a part of speech (Symbol) */
    public static final int POS_TYPE_KIGOU                          = 9;

    /** Index of the user dictionary for {@link #setDictionary(int, int, int)} */
    public static final int INDEX_USER_DICTIONARY                   = -1;
    /** Index of the learn dictionary for {@link #setDictionary(int, int, int)} */
    public static final int INDEX_LEARN_DICTIONARY                  = -2;

    
    /**
     * Whether this dictionary module is active.
     * @return {@code true} if this dictionary module is active; {@code false} if not.
     */
    public boolean isActive();
    
    /**
     * Set "in use" state.
     *
     * When the flag set true, the user dictionary is locked.
     *
     * @param flag      {@code true} if the user dictionary is locked; {@code false} if the user dictionary is unlocked.
     */
    public void setInUseState( boolean flag );

    /**
     * Clear all dictionary settings.
     *
     * All the dictionaries are set to be unused.
     *
     * @return          0 if success; minus value(error code) if fail.
     */
    public int clearDictionary( );

    /**
     * Sets a dictionary information for using specified dictionary.
     *
     * <p>
     * A dictionary information contains parameters:<br>
     * {@code base} is the bias of frequency for the dictionary.<br>
     * {@code high} is the upper limit of frequency for the dictionary.
     * </p>
     * Searched word's frequency in the dictionary is mapped to the range from {@code base} to {@code high}.
     * <br>
     * The maximum value of {@code base} and {@code high} is 1000.
     * To set a dictionary unused, specify -1 to {@code base} and {@code high}.
     *
     * @param index     A dictionary index
     * @param base      The base frequency for the dictionary
     * @param high      The maximum frequency for the dictionary
     * @return          0 if success; minus value(error code) if fail.
     */
    public int setDictionary(int index, int base, int high );

    /**
     * Clears approximate patterns.
     *
     * This clears all approximate search patterns in the search condition.
     */
    public void clearApproxPattern( );

    /**
     * Sets a approximate pattern.
     *
     * This adds an approximate search pattern(replacement of character) to the search condition.
     * The pattern rule is defined as replacing a character({@code src}) to characters({@code dst}).
     * <br>
     * The length of {@code src} must be 1 and the length of {@code dst} must be lower than 4.<br>
     * The maximum count of approximate patterns is 255.
     *
     * @param src       A character replace from
     * @param dst       Characters replace to
     * @return          0 if success; minus value(error code) if fail.
     */
    public int setApproxPattern( String src, String dst );

    /**
     * Sets a predefined approximate pattern.
     *
     * The patterns included predefined approximate search pattern set specified by
     * {@code approxPattern} are added to the search condition.
     *
     * @param approxPattern     A predefined approximate pattern set
     * @see jp.co.omronsoft.openwnn.WnnDictionary#APPROX_PATTERN_EN_TOUPPER
     * @see jp.co.omronsoft.openwnn.WnnDictionary#APPROX_PATTERN_EN_TOLOWER
     * @see jp.co.omronsoft.openwnn.WnnDictionary#APPROX_PATTERN_EN_QWERTY_NEAR
     * @see jp.co.omronsoft.openwnn.WnnDictionary#APPROX_PATTERN_EN_QWERTY_NEAR_UPPER
     *
     * @return                  0 if success; minus value(error code) if fail.
     */
    public int setApproxPattern( int approxPattern );

    /**
     * Search words from dictionaries with specified conditions.
     * <p>
     * To get the searched word's information, use {@link #getNextWord()}.<br>
     * If a same word existed in the set of dictionary, the search result may contain some same words.<br>
     * <br>
     * If approximate patterns were set, the first word in search
     * results is the highest approximation word which contains best
     * matched character in the key string. <br>
     * For example, If a key string is "bbc", a approximate pattern
     * "b" to "a" is specified and the dictionary includes "abc
     * (frequency 10)" "bbcd (frequency 1)" "aac (frequency 5)"; the
     * result of prefix search is output by following order: "bbcd",
     * "abc", "aac".
     * </p>
     * <p>
     * The supported combination of parameters is:
     * <table>
     * <th><td>Search Mode</td><td>Sort Order</td><td>Ambiguous Search</td></th>
     * <tr><td>exact matching</td><td>frequency descending</td><td>no</td></tr>
     * <tr><td>prefix matching</td><td>frequency descending</td><td>no</td></tr>
     * <tr><td>prefix matching</td><td>frequency descending</td><td>yes</td></tr>
     * <tr><td>prefix matching</td><td>character code ascending</td><td>no</td></tr>
     * </table>
     * </p>
     *
     * @param operation     The search operation
     * @see jp.co.omronsoft.openwnn.WnnDictionary#SEARCH_EXACT
     * @see jp.co.omronsoft.openwnn.WnnDictionary#SEARCH_PREFIX
     * @param order         The sort order
     * @see jp.co.omronsoft.openwnn.WnnDictionary#ORDER_BY_FREQUENCY
     * @see jp.co.omronsoft.openwnn.WnnDictionary#ORDER_BY_KEY
     * @param keyString     The key string
     *
     * @see jp.co.omronsoft.openwnn.WnnDictionary#getNextWord
     *
     * @return              0 if no word is found; 1 if some words found; minus value if a error occurs.
     */
    public int searchWord(int operation, int order, String keyString );

    /**
     * Search words from dictionaries with specified conditions and previous word.
     * <p>
     * For using link search function, specify the {@code wnnWord} as previous word and
     * set {@code SEARCH_LINK} mode to {@code operation}. The other arguments are
     * the same as {@link #searchWord(int operation, int order, String keyString)}.
     * <p>
     * If the prediction dictionary for reading is set to use, the previous word must contain
     * the {@code stroke} and the {@code candidate} information. If the prediction dictionary
     * for part of speech is set to use, the previous word must contain the {@code partOfSpeech} information.
     *
     * @param wnnWord       The previous word
     * @see jp.co.omronsoft.openwnn.WnnDictionary#searchWord
     * 
     * @return              0 if no word is found; 1 if some words found; minus value if a error occurs.
     */
    public int searchWord(int operation, int order, String keyString, WnnWord wnnWord );

    /**
     * Retrieve a searched word information.
     *
     * It returns a word information from top of the {@code searchWord()}'s result.
     * To get all word's information of the result, call this method repeatedly until it returns null.
     *
     * @return              An instance of WnnWord; null if no result or an error occurs.
     */
    public WnnWord getNextWord( );

    /**
     * Retrieve a searched word information with condition of length.
     *
     * It returns a word information from top of the {@code searchWord()}'s result.
     * To get all word's information of the result, call this method repeatedly until it returns null.
     *
     * @param length    >0 if only the result of specified length is retrieved; 0 if no condition exist
     * @return          An instance of WnnWord; null if no result or an error occurs.
     */
    public WnnWord getNextWord( int length );

    /**
     * Retrieve all word in the user dictionary.
     *
     * @return          The array of WnnWord objects.
     */
    public WnnWord[] getUserDictionaryWords( );

    /**
     * Retrieve the connect matrix.
     *
     * @return          The array of the connect matrix; null if an error occurs.
     */
    public byte[][] getConnectMatrix( );

    /**
     * Retrieve the part of speech information specified POS type.
     *
     * @param type      The type of a part of speech
     * @return          The part of speech information; null if invalid type is specified or  an error occurs.
     *
     * @see jp.co.omronsoft.openwnn.WnnDictionary#POS_TYPE_V1
     * @see jp.co.omronsoft.openwnn.WnnDictionary#POS_TYPE_V2
     * @see jp.co.omronsoft.openwnn.WnnDictionary#POS_TYPE_V3
     * @see jp.co.omronsoft.openwnn.WnnDictionary#POS_TYPE_BUNTOU
     * @see jp.co.omronsoft.openwnn.WnnDictionary#POS_TYPE_TANKANJI
     * @see jp.co.omronsoft.openwnn.WnnDictionary#POS_TYPE_SUUJI
     * @see jp.co.omronsoft.openwnn.WnnDictionary#POS_TYPE_MEISI
     * @see jp.co.omronsoft.openwnn.WnnDictionary#POS_TYPE_JINMEI
     * @see jp.co.omronsoft.openwnn.WnnDictionary#POS_TYPE_CHIMEI
     * @see jp.co.omronsoft.openwnn.WnnDictionary#POS_TYPE_KIGOU
    */
    public WnnPOS getPOS( int type );

    /**
     * Clear the user dictionary.
     * 
     * @return      0 if no error occur; <0 if an error occur
     */
    public int clearUserDictionary();
    /**
     * Clear the learn dictionary.
     * 
     * @return      0 if no error occur; <0 if an error occur
     */
    public int clearLearnDictionary();

    /**
     * Add the words to user dictionary.
     *
     * @param word      The array of word
     * @return          0 if no error occur; <0 if an error occur
     */
    public int addWordToUserDictionary( WnnWord[] word );
    /**
     * Add the word to user dictionary.
     *
     * @param word      The word
     * @return          0 if no error occur; <0 if an error occur
     */
    public int addWordToUserDictionary( WnnWord word );

    /**
     * Remove the words from user dictionary.
     *
     * @param word      The array of word
     * @return          0 if no error occur; <0 if an error occur
     */
    public int removeWordFromUserDictionary( WnnWord[] word );
    /**
     * Remove the word from user dictionary.
     *
     * @param word      The word
     * @return          0 if no error occur; <0 if an error occur
     */
    public int removeWordFromUserDictionary( WnnWord word );

    /**
     * Learn the word.
     *
     * @param word      The word for learning
     * @return          0 if no error occur; <0 if an error occur
     */
    public int learnWord( WnnWord word );

    /**
     * Learn the word with connection.
     *
     * @param word              The word for learning
     * @param previousWord      The word for link learning
     * @return                  0 if no error occur; <0 if an error occur
     */
    public int learnWord( WnnWord word, WnnWord previousWord );
}