/**
 *  Licensed under GPL. For more information, see
 *    http://jaxodraw.sourceforge.net/license.html
 *  or the LICENSE file in the jaxodraw distribution.
 */
package net.sf.jaxodraw.util;


/**
 * Defines a number of greek letters and some methods to convert them into
 * LaTeX strings and back.
 *
 * @since 2.0
 */
public final class JaxoGreek {
    // lower case greek letters

    /** The greek letter alpha. */
    public static final char ALPHA = (char) (1 + (11 * 16) + (3 * 256));

    /** The greek letter beta. */
    public static final char BETA = (char) (2 + (11 * 16) + (3 * 256));

    /** The greek letter gamma. */
    public static final char GAMMA = (char) (3 + (11 * 16) + (3 * 256));

    /** The greek letter delta. */
    public static final char DELTA = (char) (4 + (11 * 16) + (3 * 256));

    /** The greek letter epsilon. */
    public static final char EPSILON = (char) (5 + (11 * 16) + (3 * 256));

    /** The greek letter zeta. */
    public static final char ZETA = (char) (6 + (11 * 16) + (3 * 256));

    /** The greek letter eta. */
    public static final char ETA = (char) (7 + (11 * 16) + (3 * 256));

    /** The greek letter theta. */
    public static final char THETA = (char) (8 + (11 * 16) + (3 * 256));

    /** The greek letter iota. */
    public static final char IOTA = (char) (9 + (11 * 16) + (3 * 256));

    /** The greek letter kappa. */
    public static final char KAPPA = (char) (10 + (11 * 16) + (3 * 256));

    /** The greek letter lambda. */
    public static final char LAMBDA = (char) (11 + (11 * 16) + (3 * 256));

    /** The greek letter mu. */
    public static final char MU = (char) (12 + (11 * 16) + (3 * 256));

    /** The greek letter nu. */
    public static final char NU = (char) (13 + (11 * 16) + (3 * 256));

    /** The greek letter xi. */
    public static final char XI = (char) (14 + (11 * 16) + (3 * 256));

    /** The greek letter omikron. */
    public static final char OMIKRON = (char) (15 + (11 * 16) + (3 * 256));

    /** The greek letter pi. */
    public static final char PI = (char) (0 + (12 * 16) + (3 * 256));

    /** The greek letter rho. */
    public static final char RHO = (char) (1 + (12 * 16) + (3 * 256));

    /** The greek letter sigma (corresponding to LaTeX's \varsigma). */
    public static final char VARSIGMA = (char) (2 + (12 * 16) + (3 * 256));

    /** The greek letter sigma. */
    public static final char SIGMA = (char) (3 + (12 * 16) + (3 * 256));

    /** The greek letter tau. */
    public static final char TAU = (char) (4 + (12 * 16) + (3 * 256));

    /** The greek letter upsilon. */
    public static final char UPSILON = (char) (5 + (12 * 16) + (3 * 256));

    /** The greek letter phi. */
    public static final char PHI = (char) (6 + (12 * 16) + (3 * 256));

    /** The greek letter chi. */
    public static final char CHI = (char) (7 + (12 * 16) + (3 * 256));

    /** The greek letter psi. */
    public static final char PSI = (char) (8 + (12 * 16) + (3 * 256));

    /** The greek letter omega. */
    public static final char OMEGA = (char) (9 + (12 * 16) + (3 * 256));

    /** The greek letter theta (corresponding to LaTeX's \vartheta). */
    public static final char VARTHETA = (char) (1 + (13 * 16) + (3 * 256));

    /** The greek letter phi (corresponding to LaTeX's \varphi). */
    public static final char VARPHI = (char) (5 + (13 * 16) + (3 * 256));

    // upper case greek letters

    /** The greek upper case letter gamma. */
    public static final char UPPER_GAMMA = (char) (3 + (9 * 16) + (3 * 256));

    /** The greek upper case letter delta. */
    public static final char UPPER_DELTA = (char) (4 + (9 * 16) + (3 * 256));

    /** The greek upper case letter theta. */
    public static final char UPPER_THETA = (char) (8 + (9 * 16) + (3 * 256));

    /** The greek upper case letter lambda. */
    public static final char UPPER_LAMBDA = (char) (11 + (9 * 16) + (3 * 256));

    /** The greek upper case letter xi. */
    public static final char UPPER_XI = (char) (14 + (9 * 16) + (3 * 256));

    /** The greek upper case letter pi. */
    public static final char UPPER_PI = (char) (0 + (10 * 16) + (3 * 256));

    /** The greek upper case letter sigma. */
    public static final char UPPER_SIGMA = (char) (3 + (10 * 16) + (3 * 256));

    /** The greek upper case letter phi. */
    public static final char UPPER_PHI = (char) (6 + (10 * 16) + (3 * 256));

    /** The greek upper case letter psi. */
    public static final char UPPER_PSI = (char) (8 + (10 * 16) + (3 * 256));

    /** The greek upper case letter omega. */
    public static final char UPPER_OMEGA = (char) (9 + (10 * 16) + (3 * 256));

    /** A character array holding all the defined greek characters. */
    private static final char[] GREEK_CHARS =
    {
        ALPHA, BETA, GAMMA, DELTA, EPSILON, ZETA, ETA, THETA, IOTA, KAPPA,
        LAMBDA, MU, NU, XI, OMIKRON, PI, RHO, VARSIGMA, SIGMA, TAU, UPSILON,
        PHI, CHI, PSI, OMEGA, VARTHETA, VARPHI, UPPER_GAMMA, UPPER_DELTA,
        UPPER_THETA, UPPER_LAMBDA, UPPER_XI, UPPER_PI, UPPER_SIGMA, UPPER_PHI,
        UPPER_PSI, UPPER_OMEGA
    };

    /** The number of greek letters defined by this class. */
    private static final int NOF_GREEK_CHARS = GREEK_CHARS.length;

    /**
     * An array of strings, holding all the LaTeX commands corresponding
     * to the greek characters defined in this class.
     */
    private static final String[] LATEX_COMMANDS =
    {
        "\\alpha", "\\beta", "\\gamma", "\\delta", "\\epsilon", "\\zeta",
        "\\eta", "\\theta", "\\iota", "\\kappa", "\\lambda", "\\mu", "\\nu",
        "\\xi", "o", "\\pi", "\\rho", "\\varsigma", "\\sigma", "\\tau",
        "\\upsilon", "\\phi", "\\chi", "\\psi", "\\omega", "\\vartheta",
        "\\varphi", "\\Gamma", "\\Delta", "\\Theta", "\\Lambda", "\\Xi", "\\Pi",
        "\\Sigma", "\\Phi", "\\Psi", "\\Omega"
    };

    /**
     * Empty private constructor to prevent the class from being
     * explicitly instantiated.
     */
    private JaxoGreek() {
        // empty on purpose
    }

    /**
     * Gets the LaTeX command for the greek character a.
     *
     * @param a The greek character whose LaTex command is to be returned.
     *
     * @return The LaTeX command of the greek character a or null if
     *  a does not correspond to any greek character.
     */
    public static String getLatexCommand(final char a) {
        final int i = getIndex(a);

        return (i < NOF_GREEK_CHARS) ? LATEX_COMMANDS[i] : null;
    }

    /**
     * Returns the greek character whose LaTex command is s.
     *
     * @param command The LaTeX command whose corresponding greek character
     * is to be returned.
     *
     * @return The greek character corresponding to the LaTex command
     * or '\u0000' (NUL) if command does not correspond to any greek character.
     */
    public static char getCharacter(final String command) {
        final int i = getIndex(command);

        return (i < NOF_GREEK_CHARS) ? GREEK_CHARS[i] : '\u0000';
    }

    /**
     * Tests whether the given character corresponds to one of the
     * greek characters defined in this class.
     *
     * @param a A character.
     *
     * @return True if a corresponds to one of the greek characters
     * defined in this class, false otherwise.
     */
    public static boolean isGreekCharacter(final char a) {
        return getIndex(a) < NOF_GREEK_CHARS;
    }

    /**
     * Tests whether the given latex command corresponds to one of the
     * greek characters defined in this class.
     *
     * @param command a latex string (\\alpha etc.)
     *
     * @return True if command corresponds to one of the greek characters
     * defined in this class, false otherwise.
     */
    public static boolean isLatexCommand(final String command) {
        return getIndex(command) < NOF_GREEK_CHARS;
    }

      //
     // private
    //

    /**
     * Returns the index of the greek character a.
     *
     * @param a A greek character.
     *
     * @return The index of a if a is a greek character,
     *      otherwise returns nofGreekLetters.
     */
    private static int getIndex(final char a) {
        for (int i = 0; i < NOF_GREEK_CHARS; i++) {
            if (GREEK_CHARS[i] == a) {
                return i;
            }
        }

        return NOF_GREEK_CHARS;
    }

    /**
     * Returns the index of the LaTeX string s that corresponds to a
     * greek character.
     *
     * @param s A string with a latex command for a greek character.
     *
     * @return The index of s if it corresponds to the LaTeX command of a
     *      greek character, otherwise returns nofGreekLetters.
     */
    private static int getIndex(final String s) {
        for (int i = 0; i < NOF_GREEK_CHARS; i++) {
            if (LATEX_COMMANDS[i].equals(s)) {
                return i;
            }
        }

        return NOF_GREEK_CHARS;
    }

}
