/*
 *
 *  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.
 *
 */

package flash.fonts;

import flash.swf.builder.types.PathIteratorWrapper;
import flash.swf.builder.types.ShapeBuilder;
import flash.swf.types.GlyphEntry;
import flash.swf.types.Shape;
import flash.swf.SwfConstants;
import flash.util.Trace;

import java.awt.font.FontRenderContext;
import java.awt.font.GlyphMetrics;
import java.awt.font.GlyphVector;
import java.awt.font.TextAttribute;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.BufferedInputStream;
import java.net.URL;
import java.util.Locale;
import java.util.Map;
import java.util.ArrayList;
import java.util.HashMap;

/**
 * The <code>JREFontManager</code> attempts to optimize the loading of
 * JDK fonts through caching of <code>FontSet</code>s. A
 * <code>FontSet</code> keeps track of the different styles (faces)
 * for a given font family as <code>FontFace</code> instances. A
 * manager can derive available styles from a single
 * <code>FontFace</code> through its reference to a
 * <code>java.awt.Font</code> object.
 */
@SuppressWarnings("unchecked")
public class JREFontManager extends CachedFontManager
{
    private boolean readLocalFonts;
    private Map<String, LocalFont> localFonts;
    public static String LOCAL_FONTS_SNAPSHOT = "flex.fonts-snapshot";
    private String localFontsFile;

    public void initialize(Map map)
    {
        super.initialize(map);
        if (map != null)
        {
            localFontsFile = (String)map.get(LOCAL_FONTS_SNAPSHOT);
        }
        if (localFontsFile == null)
        {
            localFontsFile = "localFonts.ser";
        }
    }

    protected String createFontFromLocation(Object location, int requestedStyle, boolean useTwips)
    {
        String family = null;
        InputStream is = null;

        try
        {
            if (location != null && location instanceof URL)
            {
                URL url = (URL)location;

                if (url.getProtocol().toLowerCase().indexOf("file") > -1)
                {
                    File f = new File(url.getFile());
                    // Do NOT buffer this stream, Font.createFont() does it for us.
                    is = new FileInputStream(f);
                }
                else
                {
                    is = url.openStream();
                }

                Font font = Font.createFont(Font.TRUETYPE_FONT, is);

                // Get the family and fontName info before we derive a new size as
                // the name might be reset to dialog!
                family = font.getFamily();
                String fontName = font.getFontName(Locale.ENGLISH);

                // Prior to Flex 4 we tried to validate that the requested style
                // matched the style of the font.
                if (majorCompatibilityVersion < 4)
                {
                    // We need to examine the name for the real style as
                    // Font.createFont always sets style to PLAIN and the user
                    // may have given us the wrong style info
                    int guessedStyle = CachedFontFace.guessStyleFromSubFamilyName(fontName);

                    // Only bother deriving a font and storing the work if this
                    // really was the style requested
                    if (requestedStyle != guessedStyle)
                        return null;
                }

                // Now that we've processed the font with the JRE font manager, we now need to get the fsType
                // and copyright info from from Batik.  This is a bit strange, as one of the advantages of the
                // JRE font manager is that it can process some fonts that Batik cannot.  This check is needed,
                // though, anytime we create a font.  So it may mean we don't need the JRE font manager anymore,
                // but since I'm not sure of that, it'll be kept in for awhile.
                String locationStr = BatikFontManager.processLocation(location);
                org.apache.flex.forks.batik.svggen.font.Font batikFont = org.apache.flex.forks.batik.svggen.font.Font.create(locationStr);
                if (batikFont == null)
                {
                    throw new FontFormatException ("Unable to create font." );
                }
                FSType type = FSType.getFSType(batikFont);
                if (! type.usableByFlex)
                {
                    throw new BatikFontManager.UnusableFontLicense(location + "", type.description);
                }
                String copyright = batikFont.getNameTable().getRecord((short)0);
                String trademark = batikFont.getNameTable().getRecord((short)7);

                // Set to a default size so metrics are established
                // getAttributes() returns a Map which is based on a Hashtable of <Obj,Obj>, or <TA,Obj> in practice
                // we need to suppress the cast because getAttributes defines the return type as <TA,?> 
                Map<TextAttribute, Object> attributes = (Map<TextAttribute, Object>) font.getAttributes();

                attributes.put(TextAttribute.FAMILY, family);
                attributes.put(TextAttribute.SIZE, DEFAULT_FONT_SIZE_OBJECT);
                attributes.put(TextAttribute.POSTURE, CachedFontFace.isItalic(requestedStyle) ? TextAttribute.POSTURE_OBLIQUE : TextAttribute.POSTURE_REGULAR);
                attributes.put(TextAttribute.WEIGHT, CachedFontFace.isBold(requestedStyle) ? TextAttribute.WEIGHT_BOLD : TextAttribute.WEIGHT_REGULAR);

                font = font.deriveFont(attributes);

                FontSet fontSet = (FontSet)getFontCache().get(family);
                if (fontSet == null)
                {
                    fontSet = new FontSet(maxFacesPerFont);
                    getFontCache().put(family, fontSet);
                }

                fontSet.put(requestedStyle, new JREFontFace(font, requestedStyle, maxGlyphsPerFace, type, copyright, trademark, useTwips));
            }
        }
        catch (FileNotFoundException ex)
        {
            return null;
        }
        catch (FontFormatException ex)
        {
            return null;
        }
        catch (IOException ex)
        {
            return null;
        }
        finally
        {
            try
            {
                is.close();
            }
            catch (Throwable t)
            {
            }
        }

        return family;
    }

    /**
     * Attempts to load a font from the cache by location or from disk if it is the first
     * request at this address. The location is bound to a font family name after the initial
     * loading, and the relationship exists for the lifetime of the cache.
     *
     * @param location
     * @param style
     * @return FontSet.FontFace
     */
    public FontFace getEntryFromLocation(URL location, int style, boolean useTwips)
    {
        FontFace entry = null;
        Object fam = getFontFileCache().get(location);

        if (fam == null)
        {
            fam = createFontFromLocation(location, style, useTwips);
        }

        if (fam != null)
        {
            String family = fam.toString();

            FontSet fontSet = (FontSet)getFontCache().get(family);

            // The font file cache should still have this family
            // from the location fetch above...
            if (fontSet != null)
            {
                entry = fontSet.get(style);
            }
        }

        return entry;
    }

    private static ArrayList<String> systemFontNames = null;

    protected FontSet createSetForSystemFont(String family, int style, boolean useTwips)
    {
        FontSet fontSet = null;
        if (family != null)
        {
            if (systemFontNames == null)
                initializeSystemFonts();

            if (systemFontNames != null && !systemFontNames.contains(family.trim().toLowerCase()))
            {
                if (Trace.font)
                    Trace.trace("Font family '" + family + "' not known to JRE.");

                return null;
            }

            //Load a font by family and style, set size to 240 for greater granularity
            Font font = Font.decode(family + "-" + getStyleAsString(style) + "-" + DEFAULT_FONT_SIZE_STRING);

            fontSet = new FontSet(maxFacesPerFont);
            fontSet.put(font.getStyle(), new JREFontFace(font, font.getStyle(), maxGlyphsPerFace, null, null, null, useTwips));
        }
        return fontSet;
    }

    /**
     * Attempts to locate a font by family name and style from the JRE's list of
     * fonts, which are primarily system registered fonts.
     *
     * @param familyName
     * @param style      - either Font.PLAIN, Font.BOLD, Font.ITALIC or Font.BOLD+Font.ITALIC
     * @return FontSet.FontFace
     */
    public FontFace getEntryFromSystem(String familyName, int style, boolean useTwips)
    {
        if (! readLocalFonts)
          {
              readLocalFonts();
          }

        FontFace entry = null;

        FontSet fontSet = (FontSet)getFontCache().get(familyName);

        // This is likely to be the first time looking for this family
        if (fontSet == null)
        {
            fontSet = createSetForSystemFont(familyName, style, useTwips);
        }

        // If the family was invalid on the OS there's nothing more we can do here
        if (fontSet != null)
        {
            entry = fontSet.get(style);
        }

        if (entry != null)
        {
            LocalFont font = localFonts.get(entry.getPostscriptName());
            if (font == null)
            {
                // silent failure
                if (Trace.font)
                {
                    Trace.trace("Information on font " + familyName + " could not be found.  Run FontSnapshot to get a list of the current local fonts.");
                }
            }
            else
            {
                entry.setCopyright(font.copyright);
                entry.setTrademark(font.trademark);
                entry.setFSType(FSType.getFSType(font.fsType));
            }
        }

        return entry;
    }

	private void readLocalFonts()
    {
        readLocalFonts = true;

        localFonts = new HashMap<String, LocalFont>();
//		initDefaultLocalFonts();
        try
        {
            InputStream buffStream = new BufferedInputStream(new FileInputStream(localFontsFile));
            ObjectInputStream in = new ObjectInputStream(buffStream);
            
            // there's no way around suppressing the cast warning from Object, the types get erased anyway
            Map<String, LocalFont> customLocalFonts = (Map<String, LocalFont>)in.readObject();
            
            localFonts.putAll(customLocalFonts);
        }
        catch(FileNotFoundException fnfe)
        {
            // ignore... a message will be printed out later if needed
            if (Trace.font)
            {
                fnfe.printStackTrace();
            }
        }
        catch(Exception fnfe)
        {
            if (Trace.font)
            {
                Trace.trace("Could not read localFonts.ser: " + fnfe);
            }
        }
    }

    private String getStyleAsString(int style)
    {
        String styleName;

        switch (style)
        {
            case 1:
                styleName = "bold";
                break;
            case 2:
                styleName = "italic";
                break;
            case 3:
                styleName = "bolditalic";
                break;
            default:
                styleName = "plain";
        }

        return styleName;
    }

    private static void initializeSystemFonts()
    {
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        String[] fnts = ge.getAvailableFontFamilyNames();

        if (fnts != null)
        {
            systemFontNames = new ArrayList<String>(fnts.length);
            for (int i = 0; i < fnts.length; i++)
            {
                systemFontNames.add(fnts[i].trim().toLowerCase());
            }
        }
    }

    public static class JREFontFace extends CachedFontFace
    {
	    // FIXME: need to deal with useTwips differently for caching

        public JREFontFace(Font font, int style, int maxGlyph, FSType fsType, String copyright, String trademark, boolean useTwips)
        {
            super(maxGlyph, style, fsType, copyright, trademark, useTwips);
            this.font = font;
            init();
        }

        private void init()
        {
            //Convert from device to grid co-ordinates, fixed at 72dpi
            emScale = SWF_EM_SQUARE / getPointSize(); //If you want to correct for resolution, multiply this value by 72/resolution

            scaleTransform = new AffineTransform();
            scaleTransform.setToScale(emScale, emScale);

            //We use a BufferedImage to get to the system FontMetrics...
            //Feel free to suggest a better way of getting this object.
            if (graphics == null)
            {
                BufferedImage bi = new BufferedImage(50, 50, BufferedImage.TYPE_INT_RGB);
                graphics = bi.createGraphics();
                graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
                graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            }

            fontMetrics = graphics.getFontMetrics(font);
            frc = new FontRenderContext(null, true, false);

            ascent = (int)Math.rint(fontMetrics.getAscent() * emScale * (useTwips ? SwfConstants.TWIPS_PER_PIXEL : 1));
            descent = (int)Math.rint(fontMetrics.getDescent() * emScale * (useTwips ? SwfConstants.TWIPS_PER_PIXEL : 1));

            //Ignore JDK leading values, they never match Flash MX - using an estimation technique similar to Breeze instead.
            //leading = (int)StrictMath.rint(fontMetrics.getLeading() * emScale);
            //if (leading == 0)
            lineGap = (int)Math.rint(Math.abs((getPointSize() - ascent - descent)));
        }

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

        public String getFamily()
        {
            return font.getName();
        }

        public int getFirstChar()
        {
            return 0;
        }

        public GlyphEntry getGlyphEntry(char c)
        {
            return (GlyphEntry)glyphCache.get(c);
        }

        protected GlyphEntry createGlyphEntry(char c)
        {
            return createGlyphEntry(c, c);
        }

        public GlyphEntry createGlyphEntry(char c, char referenceChar)
        {
            Shape swfShape = null;
            int advance = 0;

            GlyphVector gv = font.createGlyphVector(frc, new char[]{referenceChar});
            java.awt.Shape glyphOutline = gv.getGlyphOutline(0);

            GlyphMetrics metrics = gv.getGlyphMetrics(0);
            advance = (int)Math.rint(metrics.getAdvance()); //Do not scale here, DefineText needs values unscaled

            java.awt.Shape scaledShape = scaleTransform.createTransformedShape(glyphOutline);
            swfShape = createGlyphShape(scaledShape);

            GlyphEntry ge = new GlyphEntry();
            ge = new GlyphEntry(); //Note: we will set the index on building DefineFont2 tag
            ge.advance = (int)(advance * emScale * (useTwips ? SwfConstants.TWIPS_PER_PIXEL : 1));
            ge.shape = swfShape;
	        //Glyph bounds are not used by the Flash Player so no need to calculate
	        //Rectangle2D bs = scaledShape.getBounds2D();
	        //bounds = new Rect((int)StrictMath.rint(bs.getMinX() * (useTwips ? SwfConstants.TWIPS_PER_PIXEL : 1)),
			//        (int)StrictMath.rint(bs.getMaxX() * (useTwips ? SwfConstants.TWIPS_PER_PIXEL : 1)),
			//        (int)StrictMath.rint(bs.getMinY() * (useTwips ? SwfConstants.TWIPS_PER_PIXEL : 1)),
			//        (int)StrictMath.rint(bs.getMaxY()) * (useTwips ? SwfConstants.TWIPS_PER_PIXEL : 1));
            //ge.bounds = bounds;
            ge.character = c;

            return ge;
        }

        private Shape createGlyphShape(java.awt.Shape outline)
        {
            ShapeBuilder shape = new ShapeBuilder(useTwips);
            shape.setCurrentLineStyle(0);
            shape.setCurrentFillStyle1(1);
            shape.setUseFillStyle1(true);
            shape.processShape(new PathIteratorWrapper(outline.getPathIterator(null)));

            return shape.build();
        }

        public int getAdvance(char c)
        {
            return 0;  //To change body of implemented methods use File | Settings | File Templates.
        }

        public Font getFont()
        {
            return font;
        }

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

        public double getPointSize()
        {
            return font.getSize2D();
        }

        public FontRenderContext getFontRenderContext()
        {
            return frc;
        }

        public int getAscent()
        {
            return ascent;
        }

        public int getDescent()
        {
            return descent;
        }

        public int getLineGap()
        {
            return lineGap;
        }

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

        public double getEmScale()
        {
            return emScale;
        }

        public String getPostscriptName()
        {
            return font.getPSName();
        }

        private Font font;
        private static Graphics2D graphics;
        private FontRenderContext frc;
        private FontMetrics fontMetrics;
        private int ascent;
        private int descent;
        private int lineGap;
        private double emScale;
        private AffineTransform scaleTransform;
    }
}
