/*
 * Copyright (c) 2003, 2012, Oracle and/or its affiliates. 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.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package sun.font;

import java.lang.ref.Reference;
import java.awt.FontFormatException;
import java.awt.geom.GeneralPath;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.io.File;
import java.nio.ByteBuffer;
import sun.java2d.Disposer;
import sun.java2d.DisposerRecord;

import java.io.IOException;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;

public abstract class FileFont extends PhysicalFont {

    protected boolean useJavaRasterizer = true;

    /* I/O and file operations are always synchronized on the font
     * object. Two threads can be accessing the font and retrieving
     * information, and synchronized only to the extent that filesystem
     * operations require.
     * A limited number of files can be open at a time, to limit the
     * absorption of file descriptors. If a file needs to be opened
     * when there are none free, then the synchronization of all I/O
     * ensures that any in progress operation will complete before some
     * other thread closes the descriptor in order to allocate another one.
     */
    // NB consider using a RAF. FIS has finalize method so may take a
    // little longer to be GC'd. We don't use this stream at all anyway.
    // In fact why increase the size of a FileFont object if the stream
    // isn't needed ..
    //protected FileInputStream stream;
    //protected FileChannel channel;
    protected int fileSize;

    protected FontScaler scaler;

    /* The following variables are used, (and in the case of the arrays,
     * only initialised) for select fonts where a native scaler may be
     * used to get glyph images and metrics.
     * glyphToCharMap is filled in on the fly and used to do a reverse
     * lookup when a FileFont needs to get the charcode back from a glyph
     * code so it can re-map via a NativeGlyphMapper to get a native glyph.
     * This isn't a big hit in time, since a boolean test is sufficient
     * to choose the usual default path, nor in memory for fonts which take
     * the native path, since fonts have contiguous zero-based glyph indexes,
     * and these obviously do all exist in the font.
     */
    protected boolean checkedNatives;
    protected boolean useNatives;
    protected NativeFont[] nativeFonts;
    protected char[] glyphToCharMap;
    /*
     * @throws FontFormatException - if the font can't be opened
     */
    FileFont(String platname, Object nativeNames)
        throws FontFormatException {

        super(platname, nativeNames);
    }

    FontStrike createStrike(FontStrikeDesc desc) {
        if (!checkedNatives) {
           checkUseNatives();
        }
        return new FileFontStrike(this, desc);
    }

    protected boolean checkUseNatives() {
        checkedNatives = true;
        return useNatives;
    }

    /* This method needs to be accessible to FontManager if there is
     * file pool management. It may be a no-op.
     */
    protected abstract void close();


    /*
     * This is the public interface. The subclasses need to implement
     * this. The returned block may be longer than the requested length.
     */
    abstract ByteBuffer readBlock(int offset, int length);

    public boolean canDoStyle(int style) {
        return true;
    }

    void setFileToRemove(File file, CreatedFontTracker tracker) {
        Disposer.addObjectRecord(this,
                         new CreatedFontFileDisposerRecord(file, tracker));
    }

    // MACOSX begin -- Make this static so that we can pass in CFont
    static void setFileToRemove(Object font, File file, CreatedFontTracker tracker) {
        Disposer.addObjectRecord(font,
                         new CreatedFontFileDisposerRecord(file, tracker));
    }
    // MACOSX - end

    /* This is called when a font scaler is determined to
     * be unusable (ie bad).
     * We want to replace current scaler with NullFontScaler, so
     * we never try to use same font scaler again.
     * Scaler native resources could have already been disposed
     * or they will be eventually by Java2D disposer.
     * However, it should be safe to call dispose() explicitly here.
     *
     * For safety we also invalidate all strike's scaler context.
     * So, in case they cache pointer to native scaler
     * it will not ever be used.
     *
     * It also appears desirable to remove all the entries from the
     * cache so no other code will pick them up. But we can't just
     * 'delete' them as code may be using them. And simply dropping
     * the reference to the cache will make the reference objects
     * unreachable and so they will not get disposed.
     * Since a strike may hold (via java arrays) native pointers to many
     * rasterised glyphs, this would be a memory leak.
     * The solution is :
     * - to move all the entries to another map where they
     *   are no longer locatable
     * - update FontStrikeDisposer to be able to distinguish which
     * map they are held in via a boolean flag
     * Since this isn't expected to be anything other than an extremely
     * rare maybe it is not worth doing this last part.
     */
    synchronized void deregisterFontAndClearStrikeCache() {
        SunFontManager fm = SunFontManager.getInstance();
        fm.deRegisterBadFont(this);

        for (Reference strikeRef : strikeCache.values()) {
            if (strikeRef != null) {
                /* NB we know these are all FileFontStrike instances
                 * because the cache is on this FileFont
                 */
                FileFontStrike strike = (FileFontStrike)strikeRef.get();
                if (strike != null && strike.pScalerContext != 0L) {
                    scaler.invalidateScalerContext(strike.pScalerContext);
                }
            }
        }
        if (scaler != null) {
            scaler.dispose();
        }
        scaler = FontScaler.getNullScaler();
    }

    StrikeMetrics getFontMetrics(long pScalerContext) {
        try {
            return getScaler().getFontMetrics(pScalerContext);
        } catch (FontScalerException fe) {
            scaler = FontScaler.getNullScaler();
            return getFontMetrics(pScalerContext);
        }
    }

    float getGlyphAdvance(long pScalerContext, int glyphCode) {
        try {
            return getScaler().getGlyphAdvance(pScalerContext, glyphCode);
        } catch (FontScalerException fe) {
            scaler = FontScaler.getNullScaler();
            return getGlyphAdvance(pScalerContext, glyphCode);
        }
    }

    void getGlyphMetrics(long pScalerContext, int glyphCode, Point2D.Float metrics) {
        try {
            getScaler().getGlyphMetrics(pScalerContext, glyphCode, metrics);
        } catch (FontScalerException fe) {
            scaler = FontScaler.getNullScaler();
            getGlyphMetrics(pScalerContext, glyphCode, metrics);
        }
    }

    long getGlyphImage(long pScalerContext, int glyphCode) {
        try {
            return getScaler().getGlyphImage(pScalerContext, glyphCode);
        } catch (FontScalerException fe) {
            scaler = FontScaler.getNullScaler();
            return getGlyphImage(pScalerContext, glyphCode);
        }
    }

    Rectangle2D.Float getGlyphOutlineBounds(long pScalerContext, int glyphCode) {
        try {
            return getScaler().getGlyphOutlineBounds(pScalerContext, glyphCode);
        } catch (FontScalerException fe) {
            scaler = FontScaler.getNullScaler();
            return getGlyphOutlineBounds(pScalerContext, glyphCode);
        }
    }

    GeneralPath getGlyphOutline(long pScalerContext, int glyphCode, float x, float y) {
        try {
            return getScaler().getGlyphOutline(pScalerContext, glyphCode, x, y);
        } catch (FontScalerException fe) {
            scaler = FontScaler.getNullScaler();
            return getGlyphOutline(pScalerContext, glyphCode, x, y);
        }
    }

    GeneralPath getGlyphVectorOutline(long pScalerContext, int[] glyphs, int numGlyphs, float x, float y) {
        try {
            return getScaler().getGlyphVectorOutline(pScalerContext, glyphs, numGlyphs, x, y);
        } catch (FontScalerException fe) {
            scaler = FontScaler.getNullScaler();
            return getGlyphVectorOutline(pScalerContext, glyphs, numGlyphs, x, y);
        }
    }

    /* T1 & TT implementation differ so this method is abstract.
       NB: null should not be returned here! */
    protected abstract FontScaler getScaler();

    protected long getUnitsPerEm() {
        return getScaler().getUnitsPerEm();
    }

    private static class CreatedFontFileDisposerRecord
        implements DisposerRecord {

        File fontFile = null;
        CreatedFontTracker tracker;

        private CreatedFontFileDisposerRecord(File file,
                                              CreatedFontTracker tracker) {
            fontFile = file;
            this.tracker = tracker;
        }

        public void dispose() {
            java.security.AccessController.doPrivileged(
                 new java.security.PrivilegedAction() {
                      public Object run() {
                          if (fontFile != null) {
                              try {
                                  if (tracker != null) {
                                      tracker.subBytes((int)fontFile.length());
                                  }
                                  /* REMIND: is it possible that the file is
                                   * still open? It will be closed when the
                                   * font2D is disposed but could this code
                                   * execute first? If so the file would not
                                   * be deleted on MS-windows.
                                   */
                                  fontFile.delete();
                                  /* remove from delete on exit hook list : */
                                  // FIXME: still need to be refactored
                                  SunFontManager.getInstance().tmpFontFiles.remove(fontFile);
                              } catch (Exception e) {
                              }
                          }
                          return null;
                      }
            });
        }
    }

    protected String getPublicFileName() {
        SecurityManager sm = System.getSecurityManager();
        if (sm == null) {
            return platName;
        }
        boolean canReadProperty = true;

        try {
            sm.checkPropertyAccess("java.io.tmpdir");
        } catch (SecurityException e) {
            canReadProperty = false;
        }

        if (canReadProperty) {
            return platName;
        }

        final File f = new File(platName);

        Boolean isTmpFile = Boolean.FALSE;
        try {
            isTmpFile = AccessController.doPrivileged(
                new PrivilegedExceptionAction<Boolean>() {
                    public Boolean run() {
                        File tmp = new File(System.getProperty("java.io.tmpdir"));
                        try {
                            String tpath = tmp.getCanonicalPath();
                            String fpath = f.getCanonicalPath();

                            return (fpath == null) || fpath.startsWith(tpath);
                        } catch (IOException e) {
                            return Boolean.TRUE;
                        }
                    }
                }
            );
        } catch (PrivilegedActionException e) {
            // unable to verify whether value of java.io.tempdir will be
            // exposed, so return only a name of the font file.
            isTmpFile = Boolean.TRUE;
        }

        return  isTmpFile ? "temp file" : platName;
    }
}
