/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */

/* $Id$ */

package org.apache.fop.fonts;

import java.util.Arrays;

import org.apache.xmlgraphics.fonts.Glyphs;

import org.apache.fop.util.CharUtilities;

/**
 * Abstract base class for code point mapping classes (1-byte character encodings).
 */
public class AbstractCodePointMapping implements SingleByteEncoding {

    private final String name;
    private char[] latin1Map;
    private char[] characters;
    private char[] codepoints;
    private char[] unicodeMap; //code point to Unicode char
    private String[] charNameMap; //all character names in the encoding

    /**
     * Main constructor.
     * @param name the name of the encoding
     * @param table the table ([code point, unicode scalar value]+) with the mapping
     */
    public AbstractCodePointMapping(String name, int[] table) {
        this(name, table, null);
    }

    /**
     * Extended constructor.
     * @param name the name of the encoding
     * @param table the table ([code point, unicode scalar value]+) with the mapping
     * @param charNameMap all character names in the encoding (a value of null will be converted
     *                  to ".notdef")
     */
    public AbstractCodePointMapping(String name, int[] table, String[] charNameMap) {
        this.name = name;
        buildFromTable(table);
        if (charNameMap != null) {
            this.charNameMap = new String[256];
            for (int i = 0; i < 256; i++) {
                String charName = charNameMap[i];
                if (charName == null) {
                    this.charNameMap[i] = Glyphs.NOTDEF;
                } else {
                    this.charNameMap[i] = charName;
                }
            }
        }
    }

    /**
     * Builds the internal lookup structures based on a given table.
     * @param table the table ([code point, unicode scalar value]+) with the mapping
     */
    protected void buildFromTable(int[] table) {
        int nonLatin1 = 0;
        latin1Map = new char[256];
        unicodeMap = new char[256];
        Arrays.fill(unicodeMap, CharUtilities.NOT_A_CHARACTER);
        for (int i = 0; i < table.length; i += 2) {
            char unicode = (char)table[i + 1];
            if (unicode < 256) {
                if (latin1Map[unicode] == 0) {
                    latin1Map[unicode] = (char) table[i];
                }
            } else {
                ++nonLatin1;
            }
            if (unicodeMap[table[i]] == CharUtilities.NOT_A_CHARACTER) {
                unicodeMap[table[i]] = unicode;
            }
        }
        characters = new char[nonLatin1];
        codepoints = new char[nonLatin1];
        int top = 0;
        for (int i = 0; i < table.length; i += 2) {
            char c = (char) table[i + 1];
            if (c >= 256) {
               ++top;
               for (int j = top - 1; j >= 0; --j) {
                   if (j > 0 && characters[j - 1] >= c) {
                       characters[j] = characters[j - 1];
                       codepoints[j] = codepoints[j - 1];
                   } else {
                       characters[j] = c;
                       codepoints[j] = (char) table[i];
                       break;
                   }
               }
            }
        }
    }

    /** {@inheritDoc} */
    public String getName() {
        return this.name;
    }

    /** {@inheritDoc} */
    public final char mapChar(char c) {
        if (c < 256) {
            char latin1 = latin1Map[c];
            if (latin1 > 0) {
                return latin1;
            }
        }
        int bot = 0;
        int top = characters.length - 1;
        while (top >= bot) {
            int mid = (bot + top) / 2;
            char mc = characters[mid];

            if (c == mc) {
                return codepoints[mid];
            } else if (c < mc) {
                top = mid - 1;
            } else {
                bot = mid + 1;
            }
        }
        return NOT_FOUND_CODE_POINT;
    }

    /**
     * Returns the main Unicode value that is associated with the given code point in the encoding.
     * Note that multiple Unicode values can theoretically be mapped to one code point in the
     * encoding.
     * @param idx the code point in the encoding
     * @return the Unicode value (or \uFFFF (NOT A CHARACTER) if no Unicode value is at that point)
     */
    public final char getUnicodeForIndex(int idx) {
        return this.unicodeMap[idx];
    }

    /** {@inheritDoc} */
    public final char[] getUnicodeCharMap() {
        char[] copy = new char[this.unicodeMap.length];
        System.arraycopy(this.unicodeMap, 0, copy, 0, this.unicodeMap.length);
        return copy;
    }

    /**
     * Returns the index of a character/glyph with the given name. Note that this
     * method is relatively slow and should only be used for fallback operations.
     * @param charName the character name
     * @return the index of the character in the encoding or -1 if it doesn't exist
     */
    public short getCodePointForGlyph(String charName) {
        String[] names = this.charNameMap;
        if (names == null) {
            names = getCharNameMap();
        }
        for (short i = 0, c = (short)names.length; i < c; i++) {
            if (names[i].equals(charName)) {
                return i;
            }
        }
        return -1;
    }

    public String getNameFromCodePoint(int idx) {
        return getCharNameMap()[idx];
    }

    /** {@inheritDoc} */
    public String[] getCharNameMap() {
        if (this.charNameMap != null) {
            String[] copy = new String[this.charNameMap.length];
            System.arraycopy(this.charNameMap, 0, copy, 0, this.charNameMap.length);
            return copy;
        } else {
            //Note: this is suboptimal but will probably never be used.
            String[] derived = new String[256];
            Arrays.fill(derived, Glyphs.NOTDEF);
            for (int i = 0; i < 256; i++) {
                char c = getUnicodeForIndex(i);
                if (c != CharUtilities.NOT_A_CHARACTER) {
                    String charName = Glyphs.charToGlyphName(c);
                    if (charName.length() > 0) {
                        derived[i] = charName;
                    }
                }
            }
            return derived;
        }
    }

    /** {@inheritDoc} */
    @Override
    public String toString() {
        return getName();
    }
}
