/*
 * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */


import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.File;
import java.util.regex.Pattern;
import java.util.ArrayList;

/**
 * The UnicodeSpec class provides a way to read in Unicode character
 * properties from a Unicode data file.  One instance of class UnicodeSpec
 * holds a decoded version of one line of the data file.  The file may
 * be obtained from www.unicode.org.  The method readSpecFile returns an array
 * of UnicodeSpec objects.
 *
 * @author      Guy Steele
 * @author  John O'Conner
 */

public class UnicodeSpec {

    public UnicodeSpec() {
        this(0xffff);
    }

    public UnicodeSpec(int codePoint) {
        this.codePoint = codePoint;
        generalCategory = UNASSIGNED;
        bidiCategory = DIRECTIONALITY_UNDEFINED;
        mirrored = false;
        titleMap = 0xFFFF;
        upperMap = 0xFFFF;
        lowerMap = 0xFFFF;
        decimalValue = -1;
        digitValue = -1;
        numericValue = "";
                oldName = null;
                comment = null;
                name = null;
    }

    public String toString() {
        StringBuffer result = new StringBuffer(hex6(codePoint));
        if (getUpperMap() != 0xffff) {
            result.append(", upper=").append(hex6(upperMap));
        }
        if (getLowerMap() != 0xffff) {
            result.append(", lower=").append(hex6(lowerMap));
        }
        if (getTitleMap() != 0xffff) {
            result.append(", title=").append(hex6(titleMap));
        }
        return result.toString();
    }

    static String hex4(int n) {
        String q = Long.toHexString(n & 0xFFFF).toUpperCase();
        return "0000".substring(Math.min(4, q.length())) + q;
    }

        static String hex6(int n) {
                String str = Integer.toHexString(n & 0xFFFFFF).toUpperCase();
                return "000000".substring(Math.min(6, str.length())) + str;

        }


    /**
    * Given one line of a Unicode data file as a String, parse the line
    * and return a UnicodeSpec object that contains the same character information.
    *
    * @param s a line of the Unicode data file to be parsed
    * @return a UnicodeSpec object, or null if the parsing process failed for some reason
    */
    public static UnicodeSpec parse(String s) {
        UnicodeSpec spec = null;
        String[] tokens = null;

        try {
                        tokens = tokenSeparator.split(s, REQUIRED_FIELDS);
            spec = new UnicodeSpec();
            spec.setCodePoint(parseCodePoint(tokens[FIELD_VALUE]));
            spec.setName(parseName(tokens[FIELD_NAME]));
            spec.setGeneralCategory(parseGeneralCategory(tokens[FIELD_CATEGORY]));
            spec.setBidiCategory(parseBidiCategory(tokens[FIELD_BIDI]));
            spec.setCombiningClass(parseCombiningClass(tokens[FIELD_CLASS]));
            spec.setDecomposition(parseDecomposition(tokens[FIELD_DECOMPOSITION]));
            spec.setDecimalValue(parseDecimalValue(tokens[FIELD_DECIMAL]));
            spec.setDigitValue(parseDigitValue(tokens[FIELD_DIGIT]));
            spec.setNumericValue(parseNumericValue(tokens[FIELD_NUMERIC]));
            spec.setMirrored(parseMirrored(tokens[FIELD_MIRRORED]));
            spec.setOldName(parseOldName(tokens[FIELD_OLDNAME]));
            spec.setComment(parseComment(tokens[FIELD_COMMENT]));
            spec.setUpperMap(parseUpperMap(tokens[FIELD_UPPERCASE]));
            spec.setLowerMap(parseLowerMap(tokens[FIELD_LOWERCASE]));
            spec.setTitleMap(parseTitleMap(tokens[FIELD_TITLECASE]));
        }
        catch(Exception e) {
            spec = null;
            System.out.println("Error parsing spec line.");
        }
        return spec;
    }

    /**
    * Parse the codePoint attribute for a Unicode character.  If the parse succeeds,
    * the codePoint field of this UnicodeSpec object is updated and false is returned.
    *
    * The codePoint attribute should be a four-digit hexadecimal integer.
    *
    * @param s   the codePoint attribute extracted from a line of the Unicode data file
    * @return   code point if successful
    * @exception NumberFormatException if unable to parse argument
    */
    public static int parseCodePoint(String s) throws NumberFormatException {
        return Integer.parseInt(s, 16);
    }

    public static String parseName(String s) throws Exception {
        if (s==null) throw new Exception("Cannot parse name.");
        return s;
    }

    public static byte parseGeneralCategory(String s) throws Exception {
        byte category = GENERAL_CATEGORY_COUNT;

        for (byte x=0; x<generalCategoryList.length; x++) {
            if (s.equals(generalCategoryList[x][SHORT])) {
                category = x;
                break;
            }
        }
        if (category >= GENERAL_CATEGORY_COUNT) {
            throw new Exception("Could not parse general category.");
        }
        return category;
    }

    public static byte parseBidiCategory(String s) throws Exception {
        byte category = DIRECTIONALITY_CATEGORY_COUNT;

        for (byte x=0; x<bidiCategoryList.length; x++) {
            if (s.equals(bidiCategoryList[x][SHORT])) {
                category = x;
                break;
            }
        }
        if (category >= DIRECTIONALITY_CATEGORY_COUNT) {
            throw new Exception("Could not parse bidi category.");
        }
        return category;
    }


    /**
    * Parse the combining attribute for a Unicode character.  If there is a combining
    * attribute and the parse succeeds, then the hasCombining field is set to true,
    * the combining field of this UnicodeSpec object is updated, and false is returned.
    * If the combining attribute is an empty string, the parse succeeds but the
    * hasCombining field is set to false. (and false is returned).
    *
    * The combining attribute, if any, should be a nonnegative decimal integer.
    *
    * @param s   the combining attribute extracted from a line of the Unicode data file
    * @return   the combining class value if any, -1 if property not defined
    * @exception Exception if can't parse the combining class
    */

    public static int parseCombiningClass(String s) throws Exception {
        int combining = -1;
        if (s.length()>0) {
            combining = Integer.parseInt(s, 10);
        }
        return combining;
    }

    /**
    * Parse the decomposition attribute for a Unicode character.  If the parse succeeds,
    * the decomposition field of this UnicodeSpec object is updated and false is returned.
    *
    * The decomposition attribute is complicated; for now, it is treated as a string.
    *
    * @param s   the decomposition attribute extracted from a line of the Unicode data file
    * @return   true if the parse failed; otherwise false
    */

    public static String parseDecomposition(String s) throws Exception {
        if (s==null) throw new Exception("Cannot parse decomposition.");
        return s;
    }


    /**
    * Parse the decimal value attribute for a Unicode character.  If there is a decimal value
    * attribute and the parse succeeds, then the hasDecimalValue field is set to true,
    * the decimalValue field of this UnicodeSpec object is updated, and false is returned.
    * If the decimal value attribute is an empty string, the parse succeeds but the
    * hasDecimalValue field is set to false. (and false is returned).
    *
    * The decimal value attribute, if any, should be a nonnegative decimal integer.
    *
    * @param s   the decimal value attribute extracted from a line of the Unicode data file
    * @return   the decimal value as an int, -1 if no decimal value defined
    * @exception NumberFormatException if the parse fails
    */
    public static int parseDecimalValue(String s) throws NumberFormatException {
        int value = -1;

        if (s.length() > 0) {
            value = Integer.parseInt(s, 10);
        }
        return value;
    }

    /**
    * Parse the digit value attribute for a Unicode character.  If there is a digit value
    * attribute and the parse succeeds, then the hasDigitValue field is set to true,
    * the digitValue field of this UnicodeSpec object is updated, and false is returned.
    * If the digit value attribute is an empty string, the parse succeeds but the
    * hasDigitValue field is set to false. (and false is returned).
    *
    * The digit value attribute, if any, should be a nonnegative decimal integer.
    *
    * @param s   the digit value attribute extracted from a line of the Unicode data file
    * @return   the digit value as an non-negative int, or -1 if no digit property defined
    * @exception NumberFormatException if the parse fails
    */
    public static int parseDigitValue(String s) throws NumberFormatException {
        int value = -1;

        if (s.length() > 0) {
            value = Integer.parseInt(s, 10);
        }
        return value;
    }

    public static String parseNumericValue(String s) throws Exception {
        if (s == null) throw new Exception("Cannot parse numeric value.");
        return s;
    }

    public static String parseComment(String s) throws Exception {
        if (s == null) throw new Exception("Cannot parse comment.");
        return s;
    }

    public static boolean parseMirrored(String s) throws Exception {
        boolean mirrored;
        if (s.length() == 1) {
            if (s.charAt(0) == 'Y') {mirrored = true;}
            else if (s.charAt(0) == 'N') {mirrored = false;}
            else {throw new Exception("Cannot parse mirrored property.");}
        }
        else { throw new Exception("Cannot parse mirrored property.");}
        return mirrored;
    }

    public static String parseOldName(String s) throws Exception {
        if (s == null) throw new Exception("Cannot parse old name");
        return s;
    }

    /**
    * Parse the uppercase mapping attribute for a Unicode character.  If there is a uppercase
    * mapping attribute and the parse succeeds, then the hasUpperMap field is set to true,
    * the upperMap field of this UnicodeSpec object is updated, and false is returned.
    * If the uppercase mapping attribute is an empty string, the parse succeeds but the
    * hasUpperMap field is set to false. (and false is returned).
    *
    * The uppercase mapping attribute should be a four-digit hexadecimal integer.
    *
    * @param s   the uppercase mapping attribute extracted from a line of the Unicode data file
    * @return   uppercase char if defined, \uffff otherwise
    * @exception NumberFormatException if parse fails
    */
    public static int parseUpperMap(String s) throws NumberFormatException {
        int upperCase = 0xFFFF;

        if (s.length() >= 4) {
            upperCase = Integer.parseInt(s, 16);
        }
        else if (s.length() != 0) {
            throw new NumberFormatException();
        }
        return upperCase;
    }

    /**
    * Parse the lowercase mapping attribute for a Unicode character.  If there is a lowercase
    * mapping attribute and the parse succeeds, then the hasLowerMap field is set to true,
    * the lowerMap field of this UnicodeSpec object is updated, and false is returned.
    * If the lowercase mapping attribute is an empty string, the parse succeeds but the
     * hasLowerMap field is set to false. (and false is returned).
    *
    * The lowercase mapping attribute should be a four-digit hexadecimal integer.
    *
    * @param s   the lowercase mapping attribute extracted from a line of the Unicode data file
    * @return   lowercase char mapping if defined, \uFFFF otherwise
    * @exception NumberFormatException if parse fails
    */
    public static int parseLowerMap(String s) throws NumberFormatException {
        int lowerCase = 0xFFFF;

        if (s.length() >= 4) {
            lowerCase = Integer.parseInt(s, 16);
        }
        else if (s.length() != 0) {
            throw new NumberFormatException();
        }
        return lowerCase;
    }

    /**
    * Parse the titlecase mapping attribute for a Unicode character.  If there is a titlecase
    * mapping attribute and the parse succeeds, then the hasTitleMap field is set to true,
    * the titleMap field of this UnicodeSpec object is updated, and false is returned.
    * If the titlecase mapping attribute is an empty string, the parse succeeds but the
    * hasTitleMap field is set to false. (and false is returned).
    *
    * The titlecase mapping attribute should be a four-digit hexadecimal integer.
    *
    * @param s   the titlecase mapping attribute extracted from a line of the Unicode data file
    * @return   title case char mapping if defined, \uFFFF otherwise
    * @exception NumberFormatException if parse fails
    */
    public static int parseTitleMap(String s) throws NumberFormatException {
        int titleCase = 0xFFFF;

        if (s.length() >= 4) {
            titleCase = Integer.parseInt(s, 16);
        }
        else if (s.length() != 0) {
            throw new NumberFormatException();
        }
        return titleCase;
    }

    /**
    * Read and parse a Unicode data file.
    *
    * @param file   a file specifying the Unicode data file to be read
    * @return   an array of UnicodeSpec objects, one for each line of the
    *           Unicode data file that could be successfully parsed as
    *           specifying Unicode character attributes
    */

    public static UnicodeSpec[] readSpecFile(File file, int plane) throws FileNotFoundException {
                ArrayList<UnicodeSpec> list = new ArrayList<>(3000);
        UnicodeSpec[] result = null;
        int count = 0;
        BufferedReader f = new BufferedReader(new FileReader(file));
                String line = null;
        loop:
        while(true) {
            try {
                line = f.readLine();
            }
            catch (IOException e) {
                                break loop;
                        }
            if (line == null) break loop;
            UnicodeSpec item = parse(line.trim());
                        int specPlane = item.getCodePoint() >>> 16;
                        if (specPlane < plane) continue;
                        if (specPlane > plane) break;

            if (item != null) {
                                list.add(item);
            }
        }
                result = new UnicodeSpec[list.size()];
                list.toArray(result);
        return result;
    }

    void setCodePoint(int value) {
        codePoint = value;
    }

    /**
     * Return the code point in this Unicode specification
     * @return the char code point representing by the specification
     */
    public int getCodePoint() {
        return codePoint;
    }

    void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    void setGeneralCategory(byte category) {
        generalCategory = category;
    }

    public byte getGeneralCategory() {
        return generalCategory;
    }

    void setBidiCategory(byte category) {
        bidiCategory = category;
    }

    public byte getBidiCategory() {
        return bidiCategory;
    }

    void setCombiningClass(int combiningClass) {
        this.combiningClass = combiningClass;
    }

    public int getCombiningClass() {
        return combiningClass;
    }

    void setDecomposition(String decomposition) {
        this.decomposition = decomposition;
    }

    public String getDecomposition() {
         return decomposition;
    }

    void setDecimalValue(int value) {
        decimalValue = value;
    }

    public int getDecimalValue() {
        return decimalValue;
    }

    public boolean isDecimalValue() {
        return decimalValue != -1;
    }

    void setDigitValue(int value) {
        digitValue = value;
    }

    public int getDigitValue() {
        return digitValue;
    }

    public boolean isDigitValue() {
        return digitValue != -1;
    }

    void setNumericValue(String value) {
        numericValue = value;
    }

    public String getNumericValue() {
        return numericValue;
    }

    public boolean isNumericValue() {
        return numericValue.length() > 0;
    }

    void setMirrored(boolean value) {
        mirrored = value;
    }

    public boolean isMirrored() {
        return mirrored;
    }

    void setOldName(String name) {
        oldName = name;
    }

    public String getOldName() {
        return oldName;
    }

    void setComment(String comment) {
        this.comment = comment;
    }

    public String getComment() {
        return comment;
    }

    void setUpperMap(int ch) {
        upperMap = ch;
    };

    public int getUpperMap() {
        return upperMap;
    }

    public boolean hasUpperMap() {
        return upperMap != 0xffff;
    }

    void setLowerMap(int ch) {
        lowerMap = ch;
    }

    public int getLowerMap() {
        return lowerMap;
    }

    public boolean hasLowerMap() {
        return lowerMap != 0xffff;
    }

    void setTitleMap(int ch) {
        titleMap = ch;
    }

    public int getTitleMap() {
        return titleMap;
    }

    public boolean hasTitleMap() {
        return titleMap != 0xffff;
    }

    int codePoint;         // the characters UTF-32 code value
    String name;            // the ASCII name
    byte generalCategory;   // general category, available via Characte.getType()
    byte bidiCategory;      // available via Character.getBidiType()
    int combiningClass;     // not used in Character
    String decomposition;   // not used in Character
    int decimalValue;       // decimal digit value
    int digitValue;         // not all digits are decimal
    String numericValue;    // numeric value if digit or non-digit
    boolean mirrored;       //
    String oldName;
    String comment;
    int upperMap;
    int lowerMap;
    int titleMap;

    // this is the number of fields in one line of the UnicodeData.txt file
    // each field is separated by a semicolon (a token)
    static final int REQUIRED_FIELDS = 15;

    /**
     * General category types
     * To preserve compatibility, these values cannot be changed
     */
    public static final byte
        UNASSIGNED                  =  0, // Cn normative
        UPPERCASE_LETTER            =  1, // Lu normative
        LOWERCASE_LETTER            =  2, // Ll normative
        TITLECASE_LETTER            =  3, // Lt normative
        MODIFIER_LETTER             =  4, // Lm normative
        OTHER_LETTER                =  5, // Lo normative
        NON_SPACING_MARK            =  6, // Mn informative
        ENCLOSING_MARK              =  7, // Me informative
        COMBINING_SPACING_MARK      =  8, // Mc normative
        DECIMAL_DIGIT_NUMBER        =  9, // Nd normative
        LETTER_NUMBER               = 10, // Nl normative
        OTHER_NUMBER                = 11, // No normative
        SPACE_SEPARATOR             = 12, // Zs normative
        LINE_SEPARATOR              = 13, // Zl normative
        PARAGRAPH_SEPARATOR         = 14, // Zp normative
        CONTROL                     = 15, // Cc normative
        FORMAT                      = 16, // Cf normative
        // 17 is unused for no apparent reason,
        // but must preserve forward compatibility
        PRIVATE_USE                 = 18, // Co normative
        SURROGATE                   = 19, // Cs normative
        DASH_PUNCTUATION            = 20, // Pd informative
        START_PUNCTUATION           = 21, // Ps informative
        END_PUNCTUATION             = 22, // Pe informative
        CONNECTOR_PUNCTUATION       = 23, // Pc informative
        OTHER_PUNCTUATION           = 24, // Po informative
        MATH_SYMBOL                 = 25, // Sm informative
        CURRENCY_SYMBOL             = 26, // Sc informative
        MODIFIER_SYMBOL             = 27, // Sk informative
        OTHER_SYMBOL                = 28, // So informative
        INITIAL_QUOTE_PUNCTUATION   = 29, // Pi informative
        FINAL_QUOTE_PUNCTUATION     = 30, // Pf informative

        // this value is only used in the character generation tool
        // it can change to accommodate the addition of new categories.
        GENERAL_CATEGORY_COUNT      = 31; // sentinel value

    static final byte SHORT = 0, LONG = 1;
    // general category type strings
    // NOTE: The order of this category array is dependent on the assignment of
    // category constants above. We want to access this array using constants above.
    // [][SHORT] is the SHORT name, [][LONG] is the LONG name
    static final String[][] generalCategoryList = {
        {"Cn", "UNASSIGNED"},
        {"Lu", "UPPERCASE_LETTER"},
        {"Ll", "LOWERCASE_LETTER"},
        {"Lt", "TITLECASE_LETTER"},
        {"Lm", "MODIFIER_LETTER"},
        {"Lo", "OTHER_LETTER"},
        {"Mn", "NON_SPACING_MARK"},
        {"Me", "ENCLOSING_MARK"},
        {"Mc", "COMBINING_SPACING_MARK"},
        {"Nd", "DECIMAL_DIGIT_NUMBER"},
        {"Nl", "LETTER_NUMBER"},
        {"No", "OTHER_NUMBER"},
        {"Zs", "SPACE_SEPARATOR"},
        {"Zl", "LINE_SEPARATOR"},
        {"Zp", "PARAGRAPH_SEPARATOR"},
        {"Cc", "CONTROL"},
        {"Cf", "FORMAT"},
        {"xx", "unused"},
        {"Co", "PRIVATE_USE"},
        {"Cs", "SURROGATE"},
        {"Pd", "DASH_PUNCTUATION"},
        {"Ps", "START_PUNCTUATION"},
        {"Pe", "END_PUNCTUATION"},
        {"Pc", "CONNECTOR_PUNCTUATION"},
        {"Po", "OTHER_PUNCTUATION"},
        {"Sm", "MATH_SYMBOL"},
        {"Sc", "CURRENCY_SYMBOL"},
        {"Sk", "MODIFIER_SYMBOL"},
        {"So", "OTHER_SYMBOL"},
        {"Pi", "INITIAL_QUOTE_PUNCTUATION"},
        {"Pf", "FINAL_QUOTE_PUNCTUATION"}
    };

    /**
     * Bidirectional categories
     */
    public static final byte
                DIRECTIONALITY_UNDEFINED                  = -1,
        // Strong category
        DIRECTIONALITY_LEFT_TO_RIGHT              =  0, // L
        DIRECTIONALITY_RIGHT_TO_LEFT              =  1, // R
        DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC       =  2, // AL
        // Weak category
        DIRECTIONALITY_EUROPEAN_NUMBER            =  3, // EN
        DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR  =  4, // ES
        DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR =  5, // ET
        DIRECTIONALITY_ARABIC_NUMBER              =  6, // AN
        DIRECTIONALITY_COMMON_NUMBER_SEPARATOR    =  7, // CS
        DIRECTIONALITY_NONSPACING_MARK            =  8, // NSM
        DIRECTIONALITY_BOUNDARY_NEUTRAL           =  9, // BN
        // Neutral category
        DIRECTIONALITY_PARAGRAPH_SEPARATOR        = 10, // B
        DIRECTIONALITY_SEGMENT_SEPARATOR          = 11, // S
        DIRECTIONALITY_WHITESPACE                 = 12, // WS
        DIRECTIONALITY_OTHER_NEUTRALS              = 13, // ON

        DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING    = 14, // LRE
        DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE     = 15, // LRO
        DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING    = 16, // RLE
        DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE     = 17, // RLO
        DIRECTIONALITY_POP_DIRECTIONAL_FORMAT     = 18, // PDF

        DIRECTIONALITY_LEFT_TO_RIGHT_ISOLATE      = 19, // LRI
        DIRECTIONALITY_RIGHT_TO_LEFT_ISOLATE      = 20, // RLI
        DIRECTIONALITY_FIRST_STRONG_ISOLATE       = 21, // FSI
        DIRECTIONALITY_POP_DIRECTIONAL_ISOLATE    = 22, // PDI

        DIRECTIONALITY_CATEGORY_COUNT             = 23; // sentinel value

    // If changes are made to the above bidi category assignments, this
    // list of bidi category names must be changed to keep their order in synch.
    // Access this list using the bidi category constants above.
    static final String[][] bidiCategoryList = {
        {"L", "DIRECTIONALITY_LEFT_TO_RIGHT"},
        {"R", "DIRECTIONALITY_RIGHT_TO_LEFT"},
        {"AL", "DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC"},
        {"EN", "DIRECTIONALITY_EUROPEAN_NUMBER"},
        {"ES", "DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR"},
        {"ET", "DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR"},
        {"AN", "DIRECTIONALITY_ARABIC_NUMBER"},
        {"CS", "DIRECTIONALITY_COMMON_NUMBER_SEPARATOR"},
        {"NSM", "DIRECTIONALITY_NONSPACING_MARK"},
        {"BN", "DIRECTIONALITY_BOUNDARY_NEUTRAL"},
        {"B", "DIRECTIONALITY_PARAGRAPH_SEPARATOR"},
        {"S", "DIRECTIONALITY_SEGMENT_SEPARATOR"},
        {"WS", "DIRECTIONALITY_WHITESPACE"},
        {"ON", "DIRECTIONALITY_OTHER_NEUTRALS"},
        {"LRE", "DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING"},
        {"LRO", "DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE"},
        {"RLE", "DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING"},
        {"RLO", "DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE"},
        {"PDF", "DIRECTIONALITY_POP_DIRECTIONAL_FORMAT"},
        {"LRI", "DIRECTIONALITY_LEFT_TO_RIGHT_ISOLATE"},
        {"RLI", "DIRECTIONALITY_RIGHT_TO_LEFT_ISOLATE"},
        {"FSI", "DIRECTIONALITY_FIRST_STRONG_ISOLATE"},
        {"PDI", "DIRECTIONALITY_POP_DIRECTIONAL_ISOLATE"},

    };

    // Unicode specification lines have fields in this order.
    static final byte
        FIELD_VALUE         = 0,
        FIELD_NAME          = 1,
        FIELD_CATEGORY      = 2,
        FIELD_CLASS         = 3,
        FIELD_BIDI          = 4,
        FIELD_DECOMPOSITION = 5,
        FIELD_DECIMAL       = 6,
        FIELD_DIGIT         = 7,
        FIELD_NUMERIC       = 8,
        FIELD_MIRRORED      = 9,
        FIELD_OLDNAME       = 10,
        FIELD_COMMENT       = 11,
        FIELD_UPPERCASE     = 12,
        FIELD_LOWERCASE     = 13,
        FIELD_TITLECASE     = 14;

        static final Pattern tokenSeparator = Pattern.compile(";");

        public static void main(String[] args) {
                UnicodeSpec[] spec = null;
                if (args.length == 2 ) {
                        try {
                                File file = new File(args[0]);
                                int plane = Integer.parseInt(args[1]);
                                spec = UnicodeSpec.readSpecFile(file, plane);
                                System.out.println("UnicodeSpec[" + spec.length + "]:");
                                for (int x=0; x<spec.length; x++) {
                                        System.out.println(spec[x].toString());
                                }
                        }
                        catch(Exception e) {
                                e.printStackTrace();
                        }
                }

        }

}
