/*
 * Copyright 2003-2006 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.font;

import java.awt.Font;
import java.awt.FontFormatException;
import java.awt.GraphicsEnvironment;
import java.awt.font.FontRenderContext;
import java.awt.geom.GeneralPath;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.io.UnsupportedEncodingException;
import java.lang.ref.WeakReference;
import java.util.Locale;

/*
 * Ideally there would be no native fonts used, and this class would be
 * unneeded and removed. Presently it is still needed until such time
 * as font configuration files (or the implementation equivalent) can have
 * all references to fonts that are not handled via Java 2D removed.
 * Currently there are two cases where this class is needed, both on
 * Unix, primarily Solaris, but useful on Linux too if fonts have moved.
 * 1. Some legacy F3 fonts are still referenced so that AWT "X/Motif"
 * can get dingbats and symbols from them. This can be dispensed with when
 * either AWT is based on 2D, or when the X font path is known to always
 * contain a Type1 or TrueType font that can be used in font configuration
 * files to replace the F3 fonts.
 * 2. When location of font files by 2D fails, because of some system
 * configuration problem, it is desirable to have a fall back to some
 * functionality that lessens the immediate impact on users. Being able
 * to perform limited operations by using bitmaps from X11 helps here.
 */

public class NativeFont extends PhysicalFont {

    String encoding;

    private int numGlyphs = -1;
    boolean isBitmapDelegate;
    PhysicalFont delegateFont;

    /**
     * Verifies native font is accessible.
     * @throws FontFormatException - if the font can't be located.
     */
    public NativeFont(String platName, boolean bitmapDelegate)
        throws FontFormatException {
        super(platName, null);

        /* This is set true if this is an instance of a NativeFont
         * created by some other font, to get native bitmaps.
         * The delegating font will call this font only for "basic"
         * cases - ie non-rotated, uniform scale, monochrome bitmaps.
         * If this is false, then this instance may need to itself
         * delegate to another font for non-basic cases. Since
         * NativeFonts are used in that way only for symbol and dingbats
         * we know its safe to delegate these to the JRE's default
         * physical font (Lucida Sans Regular).
         */
        isBitmapDelegate = bitmapDelegate;

        if (GraphicsEnvironment.isHeadless()) {
            throw new FontFormatException("Native font in headless toolkit");
        }
        fontRank = Font2D.NATIVE_RANK;
        initNames();
        if (getNumGlyphs() == 0) {
          throw new FontFormatException("Couldn't locate font" + platName);
        }
    }

    private void initNames() throws FontFormatException {
        /* Valid XLFD has exactly 14 "-" chars.
         * First run over the string to verify have at least this many
         * At the same time record the locations of the hyphens
         * so we can just pick the right substring later on
         */
        int[] hPos = new int[14];
        int hyphenCnt = 1;
        int pos = 1;

        String xlfd = platName.toLowerCase(Locale.ENGLISH);
        if (xlfd.startsWith("-")) {
            while (pos != -1 && hyphenCnt < 14) {
                pos = xlfd.indexOf('-', pos);
                if (pos != -1) {
                    hPos[hyphenCnt++] = pos;
                    pos++;
                }
            }
        }

        if (hyphenCnt == 14 && pos != -1) {

            /* Capitalise words in the Family name */
            String tmpFamily = xlfd.substring(hPos[1]+1, hPos[2]);
            StringBuilder sBuffer = new StringBuilder(tmpFamily);
            char ch = Character.toUpperCase(sBuffer.charAt(0));
            sBuffer.replace(0, 1, String.valueOf(ch));
            for (int i=1;i<sBuffer.length()-1; i++) {
                if (sBuffer.charAt(i) == ' ') {
                    ch = Character.toUpperCase(sBuffer.charAt(i+1));
                    sBuffer.replace(i+1, i+2, String.valueOf(ch));
                }
            }
            familyName = sBuffer.toString();

            String tmpWeight = xlfd.substring(hPos[2]+1, hPos[3]);
            String tmpSlant = xlfd.substring(hPos[3]+1, hPos[4]);

            String styleStr = null;

            if (tmpWeight.indexOf("bold") >= 0 ||
                tmpWeight.indexOf("demi") >= 0) {
                style |= Font.BOLD;
                styleStr = "Bold";
            }

            if (tmpSlant.equals("i") ||
                tmpSlant.indexOf("italic") >= 0) {
                style |= Font.ITALIC;

                if (styleStr == null) {
                    styleStr = "Italic";
                } else {
                    styleStr = styleStr + " Italic";
                }
            }
            else if (tmpSlant.equals("o") ||
                tmpSlant.indexOf("oblique") >= 0) {
                style |= Font.ITALIC;
                if (styleStr == null) {
                    styleStr = "Oblique";
                } else {
                    styleStr = styleStr + " Oblique";
                }
            }

            if (styleStr == null) {
                fullName = familyName;
            } else {
                fullName = familyName + " " + styleStr;
            }

            encoding = xlfd.substring(hPos[12]+1);
            if (encoding.startsWith("-")) {
                encoding = xlfd.substring(hPos[13]+1);
            }
            if (encoding.indexOf("fontspecific") >= 0) {
                if (tmpFamily.indexOf("dingbats") >= 0) {
                    encoding = "dingbats";
                } else if (tmpFamily.indexOf("symbol") >= 0) {
                    encoding = "symbol";
                } else {
                    encoding = "iso8859-1";
                }
            }
        } else {
            throw new FontFormatException("Bad native name " + platName);
//             familyName = "Unknown";
//             fullName = "Unknown";
//             style = Font.PLAIN;
//             encoding = "iso8859-1";
        }
    }

    /* Wildcard all the size fields in the XLFD and retrieve a list of
     * XLFD's that match.
     * We only look for scaleable fonts, so we can just replace the 0's
     * with *'s and see what we get back
     * No matches means even the scaleable version wasn't found. This is
     * means the X font path isn't set up for this font at all.
     * One match means only the scaleable version we started with was found
     * -monotype-arial-bold-i-normal--0-0-0-0-p-0-iso8859-1
     * Two matches apparently means as well as the above, a scaleable
     * specified for 72 dpi is found, not that there are bitmaps : eg
     * -monotype-arial-bold-i-normal--0-0-72-72-p-0-iso8859-1
     * So require at least 3 matches (no need to parse) to determine that
     * there are external bitmaps.
     */
    static boolean hasExternalBitmaps(String platName) {
        /* Turn -monotype-arial-bold-i-normal--0-0-0-0-p-0-iso8859-1
         * into -monotype-arial-bold-i-normal--*-*-*-*-p-*-iso8859-1
         * by replacing all -0- substrings with -*-
         */
        StringBuilder sb = new StringBuilder(platName);
        int pos = sb.indexOf("-0-");
        while (pos >=0) {
            sb.replace(pos+1, pos+2, "*");
            pos = sb.indexOf("-0-", pos);
        };
        String xlfd = sb.toString();
        byte[] bytes = null;
        try {
            bytes = xlfd.getBytes("UTF-8");
        } catch (UnsupportedEncodingException e) {
            bytes = xlfd.getBytes();
        }
        return haveBitmapFonts(bytes);
    }

    public static boolean fontExists(String xlfd) {
        byte[] bytes = null;
        try {
            bytes = xlfd.getBytes("UTF-8");
        } catch (UnsupportedEncodingException e) {
            bytes = xlfd.getBytes();
        }
        return fontExists(bytes);
    }

    private static native boolean haveBitmapFonts(byte[] xlfd);
    private static native boolean fontExists(byte[] xlfd);

    public CharToGlyphMapper getMapper() {
        if (mapper == null) {
            if (isBitmapDelegate) {
                /* we are a delegate */
                mapper = new NativeGlyphMapper(this);
            } else {
                /* we need to delegate */
                delegateFont = FontManager.getDefaultPhysicalFont();
                mapper = delegateFont.getMapper();
            }
        }
        return mapper;
    }

    FontStrike createStrike(FontStrikeDesc desc) {
        if (isBitmapDelegate) {
            return new NativeStrike(this, desc);
        } else {
            if (delegateFont == null) {
                delegateFont = FontManager.getDefaultPhysicalFont();
            }
            /* If no FileFont's are found, delegate font may be
             * a NativeFont, so we need to avoid recursing here.
             */
            if (delegateFont instanceof NativeFont) {
                return new NativeStrike((NativeFont)delegateFont, desc);
            }
            FontStrike delegate = delegateFont.createStrike(desc);
            return new DelegateStrike(this, desc, delegate);
        }
    }

    public Rectangle2D getMaxCharBounds(FontRenderContext frc) {
            return null;
    }

    native StrikeMetrics getFontMetrics(long pScalerContext);

    native float getGlyphAdvance(long pContext, int glyphCode);

    Rectangle2D.Float getGlyphOutlineBounds(long pScalerContext,
                                            int glyphCode) {
        return new Rectangle2D.Float(0f, 0f, 0f, 0f);
    }

    public GeneralPath getGlyphOutline(long pScalerContext,
                                       int glyphCode,
                                       float x,
                                       float y) {
        return null;
    }

    native long getGlyphImage(long pScalerContext, int glyphCode);

    native long getGlyphImageNoDefault(long pScalerContext, int glyphCode);

    void getGlyphMetrics(long pScalerContext, int glyphCode,
                        Point2D.Float metrics) {
        throw new RuntimeException("this should be called on the strike");
    }

    public  GeneralPath getGlyphVectorOutline(long pScalerContext,
                                              int[] glyphs, int numGlyphs,
                                              float x,  float y) {
        return null;
    }

    private native int countGlyphs(byte[] platformNameBytes, int ptSize);

    public int getNumGlyphs() {
        if (numGlyphs == -1) {
            byte[] bytes = getPlatformNameBytes(8);
            numGlyphs = countGlyphs(bytes, 8);
        }
        return numGlyphs;
    }

    PhysicalFont getDelegateFont() {
        if (delegateFont == null) {
            delegateFont = FontManager.getDefaultPhysicalFont();
        }
        return delegateFont;
    }

    /* Specify that the dpi is 72x72, as this corresponds to JDK's
     * default user space. These are the 10th and 11th fields in the XLFD.
     * ptSize in XLFD is in 10th's of a point so multiply by 10,
     * Replace the 9th field in the XLFD (ie after the 8th hyphen)
     * with this pt size (this corresponds to the field that's "%d" in the
     * font configuration files). Wild card the other numeric fields.
     * ie to request 12 pt Times New Roman italic font, use an XLFD like :
     * -monotype-times new roman-regular-i---*-120-72-72-p-*-iso8859-1
     */
    byte[] getPlatformNameBytes(int ptSize) {
        int[] hPos = new int[14];
        int hyphenCnt = 1;
        int pos = 1;

        while (pos != -1 && hyphenCnt < 14) {
            pos = platName.indexOf('-', pos);
            if (pos != -1) {
                hPos[hyphenCnt++] = pos;
                    pos++;
            }
        }
        String sizeStr = Integer.toString((int)Math.abs(ptSize)*10);
        StringBuilder sb = new StringBuilder(platName);
        /* work backwards so as to not invalidate the positions. */
        sb.replace(hPos[11]+1, hPos[12], "*");

        sb.replace(hPos[9]+1, hPos[10], "72");

        sb.replace(hPos[8]+1, hPos[9], "72");

        /* replace the 3 lines above with the next 3 lines to get the 1.4.2
         * behaviour
         */
//      sb.replace(hPos[11]+1, hPos[12], "0");
//      sb.replace(hPos[9]+1, hPos[10], "0");
//      sb.replace(hPos[8]+1, hPos[9], "0");

        sb.replace(hPos[7]+1, hPos[8], sizeStr);

        sb.replace(hPos[6]+1, hPos[7], "*");

        /* replace the 1 line above with the next line to get the 1.4.2
         * behaviour
         */
//      sb.replace(hPos[6]+1, hPos[7], "0");

        /* comment out this block to the the 1.4.2 behaviour */
        if (hPos[0] == 0 && hPos[1] == 1) {
            /* null foundry name : some linux font configuration files have
             * symbol font entries like this and its just plain wrong.
             * Replace with a wild card. (Although those fonts should be
             * located via disk access rather than X11).
             */
           sb.replace(hPos[0]+1, hPos[1], "*");
        }

        String xlfd = sb.toString();
        byte[] bytes = null;
        try {
            bytes = xlfd.getBytes("UTF-8");
        } catch (UnsupportedEncodingException e) {
            bytes = xlfd.getBytes();
        }
        return bytes;
    }

    public String toString() {
        return " ** Native Font: Family="+familyName+ " Name="+fullName+
            " style="+style+" nativeName="+platName;
    }
}
