/*
 * Copyright 1996-2007 Sun Microsystems, Inc.  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.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package sun.awt;

import java.awt.GraphicsEnvironment;
import java.awt.peer.FontPeer;
import java.util.Locale;
import java.util.Vector;
import sun.java2d.FontSupport;
import java.nio.CharBuffer;
import java.nio.ByteBuffer;

public abstract class PlatformFont implements FontPeer {

    static {
        NativeLibLoader.loadLibraries();
        initIDs();
    }

    protected FontDescriptor[] componentFonts;
    protected char defaultChar;
    protected FontConfiguration fontConfig;

    protected FontDescriptor defaultFont;

    protected String familyName;

    private Object[] fontCache;

    // Maybe this should be a property that is set based
    // on the locale?
    protected static int FONTCACHESIZE = 256;
    protected static int FONTCACHEMASK = PlatformFont.FONTCACHESIZE - 1;
    protected static String osVersion;

    public PlatformFont(String name, int style){
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        if (ge instanceof FontSupport) {
            fontConfig = ((FontSupport)ge).getFontConfiguration();
        }
        if (fontConfig == null) {
            return;
        }

        // map given font name to a valid logical font family name
        familyName = name.toLowerCase(Locale.ENGLISH);
        if (!FontConfiguration.isLogicalFontFamilyName(familyName)) {
            familyName = fontConfig.getFallbackFamilyName(familyName, "sansserif");
        }

        componentFonts = fontConfig.getFontDescriptors(familyName, style);

        // search default character
        //
        char missingGlyphCharacter = getMissingGlyphCharacter();

        defaultChar = '?';
        if (componentFonts.length > 0)
            defaultFont = componentFonts[0];

        for (int i = 0; i < componentFonts.length; i++){
            if (componentFonts[i].isExcluded(missingGlyphCharacter)) {
                continue;
            }

            if (componentFonts[i].encoder.canEncode(missingGlyphCharacter)) {
                defaultFont = componentFonts[i];
                defaultChar = missingGlyphCharacter;
                break;
            }
        }
    }

    /**
     * Returns the character that should be rendered when a glyph
     * is missing.
     */
    protected abstract char getMissingGlyphCharacter();

    /**
     * make a array of CharsetString with given String.
     */
    public CharsetString[] makeMultiCharsetString(String str){
        return makeMultiCharsetString(str.toCharArray(), 0, str.length(), true);
    }

    /**
     * make a array of CharsetString with given String.
     */
    public CharsetString[] makeMultiCharsetString(String str, boolean allowdefault){
        return makeMultiCharsetString(str.toCharArray(), 0, str.length(), allowdefault);
    }

    /**
     * make a array of CharsetString with given char array.
     * @param str The char array to convert.
     * @param offset offset of first character of interest
     * @param len number of characters to convert
     */
    public CharsetString[] makeMultiCharsetString(char str[], int offset, int len) {
        return makeMultiCharsetString(str, offset, len, true);
    }

    /**
     * make a array of CharsetString with given char array.
     * @param str The char array to convert.
     * @param offset offset of first character of interest
     * @param len number of characters to convert
     * @param allowDefault whether to allow the default char.
     * Setting this to true overloads the meaning of this method to
     * return non-null only if all chars can be converted.
     * @return array of CharsetString or if allowDefault is false and any
     * of the returned chars would have been converted to a default char,
     * then return null.
     * This is used to choose alternative means of displaying the text.
     */
    public CharsetString[] makeMultiCharsetString(char str[], int offset, int len,
                                                  boolean allowDefault) {

        if (len < 1) {
            return new CharsetString[0];
        }
        Vector mcs = null;
        char[] tmpStr = new char[len];
        char tmpChar = defaultChar;
        boolean encoded = false;

        FontDescriptor currentFont = defaultFont;


        for (int i = 0; i < componentFonts.length; i++) {
            if (componentFonts[i].isExcluded(str[offset])){
                continue;
            }

            /* Need "encoded" variable to distinguish the case when
             * the default char is the same as the encoded char.
             * The defaultChar on Linux is '?' so it is needed there.
             */
            if (componentFonts[i].encoder.canEncode(str[offset])){
                currentFont = componentFonts[i];
                tmpChar = str[offset];
                encoded = true;
                break;
            }
        }
        if (!allowDefault && !encoded) {
            return null;
        } else {
            tmpStr[0] = tmpChar;
        }

        int lastIndex = 0;
        for (int i = 1; i < len; i++){
            char ch = str[offset + i];
            FontDescriptor fd = defaultFont;
            tmpChar = defaultChar;
            encoded = false;
            for (int j = 0; j < componentFonts.length; j++){
                if (componentFonts[j].isExcluded(ch)){
                    continue;
                }

                if (componentFonts[j].encoder.canEncode(ch)){
                    fd = componentFonts[j];
                    tmpChar = ch;
                    encoded = true;
                    break;
                }
            }
            if (!allowDefault && !encoded) {
                return null;
            } else {
                tmpStr[i] = tmpChar;
            }
            if (currentFont != fd){
                if (mcs == null) {
                    mcs = new Vector(3);
                }
                mcs.addElement(new CharsetString(tmpStr, lastIndex,
                                                 i-lastIndex, currentFont));
                currentFont = fd;
                fd = defaultFont;
                lastIndex = i;
            }
        }
        CharsetString[] result;
        CharsetString cs = new CharsetString(tmpStr, lastIndex,
                                            len-lastIndex, currentFont);
        if (mcs == null) {
            result = new CharsetString[1];
            result[0] = cs;
        } else {
            mcs.addElement(cs);
            result = new CharsetString[mcs.size()];
            for (int i = 0; i < mcs.size(); i++){
                result[i] = (CharsetString)mcs.elementAt(i);
            }
        }
        return result;
    }

    /**
     * Is it possible that this font's metrics require the multi-font calls?
     * This might be true, for example, if the font supports kerning.
    **/
    public boolean mightHaveMultiFontMetrics() {
        return fontConfig != null;
    }

    /**
     * Specialized fast path string conversion for AWT.
     */
    public Object[] makeConvertedMultiFontString(String str)
    {
        return makeConvertedMultiFontChars(str.toCharArray(),0,str.length());
    }

    public Object[] makeConvertedMultiFontChars(char[] data,
                                                int start, int len)
    {
        Object[] result = new Object[2];
        Object[] workingCache;
        byte[] convertedData = null;
        int stringIndex = start;
        int convertedDataIndex = 0;
        int resultIndex = 0;
        int cacheIndex;
        FontDescriptor currentFontDescriptor = null;
        FontDescriptor lastFontDescriptor = null;
        char currentDefaultChar;
        PlatformFontCache theChar;

        // Simple bounds check
        int end = start + len;
        if (start < 0 || end > data.length) {
            throw new ArrayIndexOutOfBoundsException();
        }

        if(stringIndex >= end) {
            return null;
        }

        // coversion loop
        while(stringIndex < end)
        {
            currentDefaultChar = data[stringIndex];

            // Note that cache sizes must be a power of two!
            cacheIndex = (int)(currentDefaultChar & this.FONTCACHEMASK);

            theChar = (PlatformFontCache)getFontCache()[cacheIndex];

            // Is the unicode char we want cached?
            if(theChar == null || theChar.uniChar != currentDefaultChar)
            {
                /* find a converter that can convert the current character */
                currentFontDescriptor = defaultFont;
                currentDefaultChar = defaultChar;
                char ch = (char)data[stringIndex];
                int componentCount = componentFonts.length;

                for (int j = 0; j < componentCount; j++) {
                    FontDescriptor fontDescriptor = componentFonts[j];

                    fontDescriptor.encoder.reset();
                    //fontDescriptor.encoder.onUnmappleCharacterAction(...);

                    if (fontDescriptor.isExcluded(ch)) {
                        continue;
                    }
                    if (fontDescriptor.encoder.canEncode(ch)) {
                        currentFontDescriptor = fontDescriptor;
                        currentDefaultChar = ch;
                        break;
                    }
                }
                try {
                    char[] input = new char[1];
                    input[0] = currentDefaultChar;

                    theChar = new PlatformFontCache();
                    if (currentFontDescriptor.useUnicode()) {
                        /*
                        currentFontDescriptor.unicodeEncoder.encode(CharBuffer.wrap(input),
                                                                    theChar.bb,
                                                                    true);
                        */
                        if (currentFontDescriptor.isLE) {
                            theChar.bb.put((byte)(input[0] & 0xff));
                            theChar.bb.put((byte)(input[0] >>8));
                        } else {
                            theChar.bb.put((byte)(input[0] >> 8));
                            theChar.bb.put((byte)(input[0] & 0xff));
                        }
                    }
                    else  {
                        currentFontDescriptor.encoder.encode(CharBuffer.wrap(input),
                                                             theChar.bb,
                                                             true);
                    }
                    theChar.fontDescriptor = currentFontDescriptor;
                    theChar.uniChar = data[stringIndex];
                    getFontCache()[cacheIndex] = theChar;
                } catch(Exception e){
                    // Should never happen!
                    System.err.println(e);
                    e.printStackTrace();
                    return null;
                }
            }

            // Check to see if we've changed fonts.
            if(lastFontDescriptor != theChar.fontDescriptor) {
                if(lastFontDescriptor != null) {
                    result[resultIndex++] = lastFontDescriptor;
                    result[resultIndex++] = convertedData;
                    //  Add the size to the converted data field.
                    if(convertedData != null) {
                        convertedDataIndex -= 4;
                        convertedData[0] = (byte)(convertedDataIndex >> 24);
                        convertedData[1] = (byte)(convertedDataIndex >> 16);
                        convertedData[2] = (byte)(convertedDataIndex >> 8);
                        convertedData[3] = (byte)convertedDataIndex;
                    }

                    if(resultIndex >= result.length) {
                        Object[] newResult = new Object[result.length * 2];

                        System.arraycopy(result, 0, newResult, 0,
                                         result.length);
                        result = newResult;
                    }
                }

                if (theChar.fontDescriptor.useUnicode()) {
                    convertedData = new byte[(end - stringIndex + 1) *
                                        (int)theChar.fontDescriptor.unicodeEncoder.maxBytesPerChar()
                                        + 4];
                }
                else  {
                    convertedData = new byte[(end - stringIndex + 1) *
                                        (int)theChar.fontDescriptor.encoder.maxBytesPerChar()
                                        + 4];
                }

                convertedDataIndex = 4;

                lastFontDescriptor = theChar.fontDescriptor;
            }

            byte[] ba = theChar.bb.array();
            int size = theChar.bb.position();
            if(size == 1) {
                convertedData[convertedDataIndex++] = ba[0];
            }
            else if(size == 2) {
                convertedData[convertedDataIndex++] = ba[0];
                convertedData[convertedDataIndex++] = ba[1];
            } else if(size == 3) {
                convertedData[convertedDataIndex++] = ba[0];
                convertedData[convertedDataIndex++] = ba[1];
                convertedData[convertedDataIndex++] = ba[2];
            } else if(size == 4) {
                convertedData[convertedDataIndex++] = ba[0];
                convertedData[convertedDataIndex++] = ba[1];
                convertedData[convertedDataIndex++] = ba[2];
                convertedData[convertedDataIndex++] = ba[3];
            }
            stringIndex++;
        }

        result[resultIndex++] = lastFontDescriptor;
        result[resultIndex] = convertedData;

        //  Add the size to the converted data field.
        if(convertedData != null) {
            convertedDataIndex -= 4;
            convertedData[0] = (byte)(convertedDataIndex >> 24);
            convertedData[1] = (byte)(convertedDataIndex >> 16);
            convertedData[2] = (byte)(convertedDataIndex >> 8);
            convertedData[3] = (byte)convertedDataIndex;
        }
        return result;
    }

    /*
     * Create fontCache on demand instead of during construction to
     * reduce overall memory consumption.
     *
     * This method is declared final so that its code can be inlined
     * by the compiler.
     */
    protected final Object[] getFontCache() {
        // This method is not MT-safe by design. Since this is just a
        // cache anyways, it's okay if we occasionally allocate the array
        // twice or return an array which will be dereferenced and gced
        // right away.
        if (fontCache == null) {
            fontCache = new Object[this.FONTCACHESIZE];
        }

        return fontCache;
    }

    /**
     * Initialize JNI field and method IDs
     */
    private static native void initIDs();

    class PlatformFontCache
    {
        char uniChar;
        FontDescriptor fontDescriptor;
        ByteBuffer bb = ByteBuffer.allocate(4);
    }
}
