/*
 * 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.font.FontRenderContext;
import java.awt.geom.AffineTransform;
import java.lang.ref.Reference;
import java.lang.ref.SoftReference;
import java.util.concurrent.ConcurrentHashMap;
import java.util.Locale;

public abstract class Font2D {

    /* Note: JRE and FONT_CONFIG ranks are identical. I don't know of a reason
     * to distingish these. Possibly if a user adds fonts to the JRE font
     * directory that are the same font as the ones specified in the font
     * configuration but that is more likely to be the legitimate intention
     * than a problem. One reason why these should be the same is that on
     * Linux the JRE fonts ARE the font configuration fonts, and although I
     * believe all are assigned FONT_CONFIG rank, it is conceivable that if
     * this were not so, that some JRE font would not be allowed to joint the
     * family of its siblings which were assigned FONT_CONFIG rank. Giving
     * them the same rank is the easy solution for now at least.
     */
    public static final int FONT_CONFIG_RANK   = 2;
    public static final int JRE_RANK     = 2;
    public static final int TTF_RANK     = 3;
    public static final int TYPE1_RANK   = 4;
    public static final int NATIVE_RANK  = 5;
    public static final int UNKNOWN_RANK = 6;
    public static final int DEFAULT_RANK = 4;

    private static final String[] boldNames = {
        "bold", "demibold", "demi-bold", "demi bold", "negreta", "demi", };

    private static final String[] italicNames = {
        "italic", "cursiva", "oblique", "inclined", };

    private static final String[] boldItalicNames = {
          "bolditalic", "bold-italic", "bold italic",
          "boldoblique", "bold-oblique", "bold oblique",
          "demibold italic", "negreta cursiva","demi oblique", };

    private static final FontRenderContext DEFAULT_FRC =
        new FontRenderContext(null, false, false);

    public Font2DHandle handle;
    protected String familyName;           /* Family font name (english) */
    protected String fullName;             /* Full font name (english)   */
    protected int style = Font.PLAIN;
    protected FontFamily family;
    protected int fontRank = DEFAULT_RANK;

    /*
     * A mapper can be independent of the strike.
     * Perhaps the reference to the mapper ought to be held on the
     * scaler, as it may be implemented via scaler functionality anyway
     * and so the mapper would be useless if its native portion was
     * freed when the scaler was GC'd.
     */
    protected CharToGlyphMapper mapper;

    /*
     * The strike cache is maintained per "Font2D" as that is the
     * principal object by which you look up fonts.
     * It means more Hashmaps, but look ups can be quicker because
     * the map will have fewer entries, and there's no need to try to
     * make the Font2D part of the key.
     */
    protected ConcurrentHashMap<FontStrikeDesc, Reference>
        strikeCache = new ConcurrentHashMap<FontStrikeDesc, Reference>();

    /* Store the last Strike in a Reference object.
     * Similarly to the strike that was stored on a C++ font object,
     * this is an optimisation which helps if multiple clients (ie
     * typically SunGraphics2D instances) are using the same font, then
     * as may be typical of many UIs, they are probably using it in the
     * same style, so it can be a win to first quickly check if the last
     * strike obtained from this Font2D satifies the needs of the next
     * client too.
     * This pre-supposes that a FontStrike is a shareable object, which
     * it should.
     */
    protected Reference lastFontStrike = new SoftReference(null);

    /*
     * POSSIBLE OPTIMISATION:
     * Array of length 1024 elements of 64 bits indicating if a font
     * contains these. This kind of information can be shared between
     * all point sizes.
     * if corresponding bit in knownBitmaskMap is set then canDisplayBitmaskMap
     * is valid. This is 16Kbytes of data per composite font style.
     * What about UTF-32 and surrogates?
     * REMIND: This is too much storage. Probably can only cache this
     * information for latin range, although possibly OK to store all
     * for just the "logical" fonts.
     * Or instead store arrays of subranges of 1024 bits (128 bytes) in
     * the range below surrogate pairs.
     */
//     protected long[] knownBitmaskMap;
//     protected long[] canDisplayBitmaskMap;

    /* Returns the "real" style of this Font2D. Eg the font face
     * Lucida Sans Bold" has a real style of Font.BOLD, even though
     * it may be able to used to simulate bold italic
     */
    public int getStyle() {
        return style;
    }
    protected void setStyle() {

        String fName = fullName.toLowerCase();

        for (int i=0; i < boldItalicNames.length; i++) {
            if (fName.indexOf(boldItalicNames[i]) != -1) {
                style = Font.BOLD|Font.ITALIC;
                return;
            }
        }

        for (int i=0; i < italicNames.length; i++) {
            if (fName.indexOf(italicNames[i]) != -1) {
                style = Font.ITALIC;
                return;
            }
        }

        for (int i=0; i < boldNames.length; i++) {
            if (fName.indexOf(boldNames[i]) != -1 ) {
                style = Font.BOLD;
                return;
            }
        }
    }


    int getRank() {
        return fontRank;
    }

    void setRank(int rank) {
        fontRank = rank;
    }

    abstract CharToGlyphMapper getMapper();



    /* This isn't very efficient but its infrequently used.
     * StandardGlyphVector uses it when the client assigns the glyph codes.
     * These may not be valid. This validates them substituting the missing
     * glyph elsewhere.
     */
    protected int getValidatedGlyphCode(int glyphCode) {
        if (glyphCode < 0 || glyphCode >= getMapper().getNumGlyphs()) {
            glyphCode = getMapper().getMissingGlyphCode();
        }
        return glyphCode;
    }

    /*
     * Creates an appropriate strike for the Font2D subclass
     */
    abstract FontStrike createStrike(FontStrikeDesc desc);

    /* this may be useful for APIs like canDisplay where the answer
     * is dependent on the font and its scaler, but not the strike.
     * If no strike has ever been returned, then create a one that matches
     * this font with the default FRC. It will become the lastStrike and
     * there's a good chance that the next call will be to get exactly that
     * strike.
     */
    public FontStrike getStrike(Font font) {
        FontStrike strike = (FontStrike)lastFontStrike.get();
        if (strike != null) {
            return strike;
        } else {
            return getStrike(font, DEFAULT_FRC);
        }
    }

    /* SunGraphics2D has font, tx, aa and fm. From this info
     * can get a Strike object from the cache, creating it if necessary.
     * This code is designed for multi-threaded access.
     * For that reason it creates a local FontStrikeDesc rather than filling
     * in a shared one. Up to two AffineTransforms and one FontStrikeDesc will
     * be created by every lookup. This appears to perform more than
     * adequately. But it may make sense to expose FontStrikeDesc
     * as a parameter so a caller can use its own.
     * In such a case if a FontStrikeDesc is stored as a key then
     * we would need to use a private copy.
     *
     * Note that this code doesn't prevent two threads from creating
     * two different FontStrike instances and having one of the threads
     * overwrite the other in the map. This is likely to be a rare
     * occurrence and the only consequence is that these callers will have
     * different instances of the strike, and there'd be some duplication of
     * population of the strikes. However since users of these strikes are
     * transient, then the one that was overwritten would soon be freed.
     * If there is any problem then a small synchronized block would be
     * required with its attendant consequences for MP scaleability.
     */
    public FontStrike getStrike(Font font, AffineTransform devTx,
                                int aa, int fm) {

        /* Create the descriptor which is used to identify a strike
         * in the strike cache/map. A strike is fully described by
         * the attributes of this descriptor.
         */
        /* REMIND: generating garbage and doing computation here in order
         * to include pt size in the tx just for a lookup! Figure out a
         * better way.
         */
        double ptSize = font.getSize2D();
        AffineTransform glyphTx = (AffineTransform)devTx.clone();
        glyphTx.scale(ptSize, ptSize);
        if (font.isTransformed()) {
            glyphTx.concatenate(font.getTransform());
        }
        FontStrikeDesc desc = new FontStrikeDesc(devTx, glyphTx,
                                                 font.getStyle(), aa, fm);
        return getStrike(desc, false);
    }

    public FontStrike getStrike(Font font, AffineTransform devTx,
                                AffineTransform glyphTx,
                                int aa, int fm) {

        /* Create the descriptor which is used to identify a strike
         * in the strike cache/map. A strike is fully described by
         * the attributes of this descriptor.
         */
        FontStrikeDesc desc = new FontStrikeDesc(devTx, glyphTx,
                                                 font.getStyle(), aa, fm);
        return getStrike(desc, false);
    }

    public FontStrike getStrike(Font font, FontRenderContext frc) {

        AffineTransform at = frc.getTransform();
        double ptSize = font.getSize2D();
        at.scale(ptSize, ptSize);
        if (font.isTransformed()) {
            at.concatenate(font.getTransform());
        }
        int aa = FontStrikeDesc.getAAHintIntVal(this, font, frc);
        int fm = FontStrikeDesc.getFMHintIntVal(frc.getFractionalMetricsHint());
        FontStrikeDesc desc = new FontStrikeDesc(frc.getTransform(),
                                                 at, font.getStyle(),
                                                 aa, fm);
        return getStrike(desc, false);
    }

    FontStrike getStrike(FontStrikeDesc desc) {
        return getStrike(desc, true);
    }

    private FontStrike getStrike(FontStrikeDesc desc, boolean copy) {
        /* Before looking in the map, see if the descriptor matches the
         * last strike returned from this Font2D. This should often be a win
         * since its common for the same font, in the same size to be
         * used frequently, for example in many parts of a UI.
         *
         * If its not the same then we use the descriptor to locate a
         * Reference to the strike. If it exists and points to a strike,
         * then we update the last strike to refer to that and return it.
         *
         * If the key isn't in the map, or its reference object has been
         * collected, then we create a new strike, put it in the map and
         * set it to be the last strike.
         */
        FontStrike strike = (FontStrike)lastFontStrike.get();
        if (strike != null && desc.equals(strike.desc)) {
            //strike.lastlookupTime = System.currentTimeMillis();
            return strike;
        } else {
            Reference strikeRef = strikeCache.get(desc);
            if (strikeRef != null) {
                strike = (FontStrike)strikeRef.get();
                if (strike != null) {
                    //strike.lastlookupTime = System.currentTimeMillis();
                    lastFontStrike = new SoftReference(strike);
                    StrikeCache.refStrike(strike);
                    return strike;
                } else {
                    /* We have found a cleared reference that has not yet
                     * been removed by the disposer.
                     * If we make this reference unreachable by removing it
                     * from the map,or overwriting it with a new reference to
                     * a new strike, then it is possible it may never be
                     * enqueued for disposal. That is the implication of
                     * the docs for java.lang.ref. So on finding a cleared
                     * reference, we need to dispose the native resources,
                     * if they haven't already been freed.
                     * The reference object needs to have a reference to
                     * the disposer instance for this to occur.
                     */
                  ((StrikeCache.DisposableStrike)strikeRef)
                      .getDisposer().dispose();
                }
            }
            /* When we create a new FontStrike instance, we *must*
             * ask the StrikeCache for a reference. We must then ensure
             * this reference remains reachable, by storing it in the
             * Font2D's strikeCache map.
             * So long as the Reference is there (reachable) then if the
             * reference is cleared, it will be enqueued for disposal.
             * If for some reason we explicitly remove this reference, it
             * must only be done when holding a strong reference to the
             * referent (the FontStrike), or if the reference is cleared,
             * then we must explicitly "dispose" of the native resources.
             * The only place this currently happens is in this same method,
             * where we find a cleared reference and need to overwrite it
             * here with a new reference.
             * Clearing the whilst holding a strong reference, should only
             * be done if the
             */
            if (copy) {
                desc = new FontStrikeDesc(desc);
            }
            strike = createStrike(desc);
            //StrikeCache.addStrike();
            strikeRef = StrikeCache.getStrikeRef(strike);
            strikeCache.put(desc, strikeRef);
            //strike.lastlookupTime = System.currentTimeMillis();
            lastFontStrike = new SoftReference(strike);
            StrikeCache.refStrike(strike);
            return strike;
        }
    }

    void removeFromCache(FontStrikeDesc desc) {
        Reference ref = strikeCache.get(desc);
        if (ref != null) {
            Object o = ref.get();
            if (o == null) {
                strikeCache.remove(desc);
            }
        }
    }

    /**
     * The length of the metrics array must be >= 8.  This method will
     * store the following elements in that array before returning:
     *    metrics[0]: ascent
     *    metrics[1]: descent
     *    metrics[2]: leading
     *    metrics[3]: max advance
     *    metrics[4]: strikethrough offset
     *    metrics[5]: strikethrough thickness
     *    metrics[6]: underline offset
     *    metrics[7]: underline thickness
     */
    public void getFontMetrics(Font font, AffineTransform at,
                               Object aaHint, Object fmHint,
                               float metrics[]) {
        /* This is called in just one place in Font with "at" == identity.
         * Perhaps this can be eliminated.
         */
        int aa = FontStrikeDesc.getAAHintIntVal(aaHint, this, font.getSize());
        int fm = FontStrikeDesc.getFMHintIntVal(fmHint);
        FontStrike strike = getStrike(font, at, aa, fm);
        StrikeMetrics strikeMetrics = strike.getFontMetrics();
        metrics[0] = strikeMetrics.getAscent();
        metrics[1] = strikeMetrics.getDescent();
        metrics[2] = strikeMetrics.getLeading();
        metrics[3] = strikeMetrics.getMaxAdvance();

        getStyleMetrics(font.getSize2D(), metrics, 4);
    }

    /**
     * The length of the metrics array must be >= offset+4, and offset must be
     * >= 0.  Typically offset is 4.  This method will
     * store the following elements in that array before returning:
     *    metrics[off+0]: strikethrough offset
     *    metrics[off+1]: strikethrough thickness
     *    metrics[off+2]: underline offset
     *    metrics[off+3]: underline thickness
     *
     * Note that this implementation simply returns default values;
     * subclasses can override this method to provide more accurate values.
     */
    public void getStyleMetrics(float pointSize, float[] metrics, int offset) {
        metrics[offset] = -metrics[0] / 2.5f;
        metrics[offset+1] = pointSize / 12;
        metrics[offset+2] = metrics[offset+1] / 1.5f;
        metrics[offset+3] = metrics[offset+1];
    }

    /**
     * The length of the metrics array must be >= 4.  This method will
     * store the following elements in that array before returning:
     *    metrics[0]: ascent
     *    metrics[1]: descent
     *    metrics[2]: leading
     *    metrics[3]: max advance
     */
    public void getFontMetrics(Font font, FontRenderContext frc,
                               float metrics[]) {
        StrikeMetrics strikeMetrics = getStrike(font, frc).getFontMetrics();
        metrics[0] = strikeMetrics.getAscent();
        metrics[1] = strikeMetrics.getDescent();
        metrics[2] = strikeMetrics.getLeading();
        metrics[3] = strikeMetrics.getMaxAdvance();
    }

    /* Currently the layout code calls this. May be better for layout code
     * to check the font class before attempting to run, rather than needing
     * to promote this method up from TrueTypeFont
     */
    byte[] getTableBytes(int tag) {
        return null;
    }

    /* for layout code */
    protected long getUnitsPerEm() {
        return 2048;
    }

    boolean supportsEncoding(String encoding) {
        return false;
    }

    public boolean canDoStyle(int style) {
        return (style == this.style);
    }

    /*
     * All the important subclasses override this which is principally for
     * the TrueType 'gasp' table.
     */
    public boolean useAAForPtSize(int ptsize) {
        return true;
    }

    public boolean hasSupplementaryChars() {
        return false;
    }

    /* The following methods implement public methods on java.awt.Font */
    public String getPostscriptName() {
        return fullName;
    }

    public String getFontName(Locale l) {
        return fullName;
    }

    public String getFamilyName(Locale l) {
        return familyName;
    }

    public int getNumGlyphs() {
        return getMapper().getNumGlyphs();
    }

    public int charToGlyph(int wchar) {
        return getMapper().charToGlyph(wchar);
    }

    public int getMissingGlyphCode() {
        return getMapper().getMissingGlyphCode();
    }

    public boolean canDisplay(char c) {
        return getMapper().canDisplay(c);
    }

    public boolean canDisplay(int cp) {
        return getMapper().canDisplay(cp);
    }

    public byte getBaselineFor(char c) {
        return Font.ROMAN_BASELINE;
    }

    public float getItalicAngle(Font font, AffineTransform at,
                                Object aaHint, Object fmHint) {
        /* hardwire psz=12 as that's typical and AA vs non-AA for 'gasp' mode
         * isn't important for the caret slope of this rarely used API.
         */
        int aa = FontStrikeDesc.getAAHintIntVal(aaHint, this, 12);
        int fm = FontStrikeDesc.getFMHintIntVal(fmHint);
        FontStrike strike = getStrike(font, at, aa, fm);
        StrikeMetrics metrics = strike.getFontMetrics();
        if (metrics.ascentY == 0 || metrics.ascentX == 0) {
            return 0f;
        } else {
            /* ascent is "up" from the baseline so its typically
             * a negative value, so we need to compensate
             */
            return metrics.ascentX/-metrics.ascentY;
        }
    }

}
