/*
 * 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 org.apache.fontbox.ttf;

import java.awt.geom.GeneralPath;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;

import org.apache.fontbox.FontBoxFont;
import org.apache.fontbox.ttf.model.GsubData;
import org.apache.fontbox.util.BoundingBox;

/**
 * A TrueType font file.
 * 
 * @author Ben Litchfield
 */
public class TrueTypeFont implements FontBoxFont, Closeable
{

    private static final Logger LOG = LogManager.getLogger(TrueTypeFont.class);

    private float version;
    private int numberOfGlyphs = -1;
    private int unitsPerEm = -1;
    private boolean enableGsub = true;
    protected final Map<String,TTFTable> tables = new HashMap<>();
    private final TTFDataStream data;
    private volatile Map<String, Integer> postScriptNames;
    
    private final Object lockReadtable = new Object();
    private final Object lockPSNames = new Object();
    private final List<String> enabledGsubFeatures = new ArrayList<>();

    /**
     * Constructor.  Clients should use the TTFParser to create a new TrueTypeFont object.
     * 
     * @param fontData The font data.
     */
    TrueTypeFont(TTFDataStream fontData)
    {
        data = fontData;
    }
    
    @Override
    public void close() throws IOException
    {
        data.close();
    }

    /**
     * @return Returns the version.
     */
    public float getVersion()
    {
        return version;
    }

    /**
     * Set the version. Package-private, used by TTFParser only.
     * @param versionValue The version to set.
     */
    void setVersion(float versionValue)
    {
        version = versionValue;
    }

    /**
     * @return Returns true if the GSUB table can be used for this font
     */
    public boolean isEnableGsub()
    {
        return enableGsub;
    }

    /**
     * Enable or disable the GSUB table for this font.
     * GSUB table is enabled by default.
     */
    public void setEnableGsub(boolean enableGsub)
    {
        this.enableGsub = enableGsub;
    }

    /**
     * Add a table definition. Package-private, used by TTFParser only.
     * 
     * @param table The table to add.
     */
    void addTable( TTFTable table )
    {
        tables.put( table.getTag(), table );
    }
    
    /**
     * Get all of the tables.
     * 
     * @return All of the tables.
     */
    public Collection<TTFTable> getTables()
    {
        return tables.values();
    }

    /**
     * Get all of the tables.
     *
     * @return All of the tables.
     */
    public Map<String, TTFTable> getTableMap()
    {
        return tables;
    }

    /**
     * Returns the raw bytes of the given table.
     * 
     * @param table the table to read.
     * @return the raw bytes of the given table
     * 
     * @throws IOException if there was an error accessing the table.
     */
    public byte[] getTableBytes(TTFTable table) throws IOException
    {
        synchronized (lockReadtable)
        {
            // save current position
            long currentPosition = data.getCurrentPosition();
            data.seek(table.getOffset());

            // read all data
            byte[] bytes = data.read((int) table.getLength());

            // restore current position
            data.seek(currentPosition);
            return bytes;
        }
    }

    /**
     * This will get the table for the given tag.
     * 
     * @param tag the name of the table to be returned
     * @return The table with the given tag.
     * @throws IOException if there was an error reading the table.
     */
    protected TTFTable getTable(String tag) throws IOException
    {
        TTFTable table = tables.get(tag);
        if (table != null && !table.getInitialized())
        {
            readTable(table);
        }
        return table;
    }

    /**
     * This will get the naming table for the true type font.
     * 
     * @return The naming table or null if it doesn't exist.
     * @throws IOException if there was an error reading the table.
     */
    public NamingTable getNaming() throws IOException
    {
        return (NamingTable) getTable(NamingTable.TAG);
    }
    
    /**
     * Get the postscript table for this TTF.
     * 
     * @return The postscript table or null if it doesn't exist.
     * @throws IOException if there was an error reading the table.
     */
    public PostScriptTable getPostScript() throws IOException
    {
        return (PostScriptTable) getTable(PostScriptTable.TAG);
    }
    
    /**
     * Get the OS/2 table for this TTF.
     * 
     * @return The OS/2 table or null if it doesn't exist.
     * @throws IOException if there was an error reading the table.
     */
    public OS2WindowsMetricsTable getOS2Windows() throws IOException
    {
        return (OS2WindowsMetricsTable) getTable(OS2WindowsMetricsTable.TAG);
    }

    /**
     * Get the maxp table for this TTF.
     * 
     * @return The maxp table or null if it doesn't exist.
     * @throws IOException if there was an error reading the table.
     */
    public MaximumProfileTable getMaximumProfile() throws IOException
    {
        return (MaximumProfileTable) getTable(MaximumProfileTable.TAG);
    }
    
    /**
     * Get the head table for this TTF.
     * 
     * @return The head table or null if it doesn't exist.
     * @throws IOException if there was an error reading the table.
     */
    public HeaderTable getHeader() throws IOException
    {
        return (HeaderTable) getTable(HeaderTable.TAG);
    }
    
    /**
     * Get the hhea table for this TTF.
     * 
     * @return The hhea table or null if it doesn't exist.
     * @throws IOException if there was an error reading the table.
     */
    public HorizontalHeaderTable getHorizontalHeader() throws IOException
    {
        return (HorizontalHeaderTable) getTable(HorizontalHeaderTable.TAG);
    }
    
    /**
     * Get the hmtx table for this TTF.
     * 
     * @return The hmtx table or null if it doesn't exist.
     * @throws IOException if there was an error reading the table.
     */
    public HorizontalMetricsTable getHorizontalMetrics() throws IOException
    {
        return (HorizontalMetricsTable) getTable(HorizontalMetricsTable.TAG);
    }
    
    /**
     * Get the loca table for this TTF.
     * 
     * @return The loca table or null if it doesn't exist.
     * @throws IOException if there was an error reading the table.
     */
    public IndexToLocationTable getIndexToLocation() throws IOException
    {
        return (IndexToLocationTable) getTable(IndexToLocationTable.TAG);
    }
    
    /**
     * Get the glyf table for this TTF.
     * 
     * @return The glyf table or null if it doesn't exist.
     * @throws IOException if there was an error reading the table.
     */
    public GlyphTable getGlyph() throws IOException
    {
        return (GlyphTable) getTable(GlyphTable.TAG);
    }
    
    /**
     * Get the "cmap" table for this TTF.
     * 
     * @return The "cmap" table or null if it doesn't exist.
     * @throws IOException if there was an error reading the table.
     */
    public CmapTable getCmap() throws IOException
    {
        return (CmapTable) getTable(CmapTable.TAG);
    }
    
    /**
     * Get the vhea table for this TTF.
     * 
     * @return The vhea table or null if it doesn't exist.
     * @throws IOException if there was an error reading the table.
     */
    public VerticalHeaderTable getVerticalHeader() throws IOException
    {
        return (VerticalHeaderTable) getTable(VerticalHeaderTable.TAG);
    }
    
    /**
     * Get the vmtx table for this TTF.
     * 
     * @return The vmtx table or null if it doesn't exist.
     * @throws IOException if there was an error reading the table.
     */
    public VerticalMetricsTable getVerticalMetrics() throws IOException
    {
        return (VerticalMetricsTable) getTable(VerticalMetricsTable.TAG);
    }
    
    /**
     * Get the VORG table for this TTF.
     * 
     * @return The VORG table or null if it doesn't exist.
     * @throws IOException if there was an error reading the table.
     */
    public VerticalOriginTable getVerticalOrigin() throws IOException
    {
        return (VerticalOriginTable) getTable(VerticalOriginTable.TAG);
    }
    
    /**
     * Get the "kern" table for this TTF.
     * 
     * @return The "kern" table or null if it doesn't exist.
     * @throws IOException if there was an error reading the table.
     */
    public KerningTable getKerning() throws IOException
    {
        return (KerningTable) getTable(KerningTable.TAG);
    }

    /**
     * Get the "gsub" table for this TTF.
     *
     * @return The "gsub" table or null if it doesn't exist.
     * @throws IOException if there was an error reading the table.
     */
    public GlyphSubstitutionTable getGsub() throws IOException
    {
        return (GlyphSubstitutionTable) getTable(GlyphSubstitutionTable.TAG);
    }

    /**
     * Get the data of the TrueType Font
     * program representing the stream used to build this 
     * object (normally from the TTFParser object).
     * 
     * @return COSStream TrueType font program stream
     * 
     * @throws IOException If there is an error getting the font data.
     */
    public InputStream getOriginalData() throws IOException 
    {
       return data.getOriginalData(); 
    }

    /**
     * Get the data size of the TrueType Font program representing the stream used to build this
     * object (normally from the TTFParser object).
     *
     * @return the size.
     */
    public long getOriginalDataSize()
    {
        return data.getOriginalDataSize();
    }

    /**
     * Read the given table if necessary. Package-private, used by TTFParser only.
     * 
     * @param table the table to be initialized
     * 
     * @throws IOException if there was an error reading the table.
     */
    void readTable(TTFTable table) throws IOException
    {
        // save current position
        long currentPosition = data.getCurrentPosition();
        data.seek(table.getOffset());
        table.read(this, data);
        // restore current position
        data.seek(currentPosition);
    }

    /**
     * Returns the number of glyphs (MaximumProfile.numGlyphs).
     * 
     * @return the number of glyphs
     * @throws IOException if there was an error reading the table.
     */
    public int getNumberOfGlyphs() throws IOException
    {
        if (numberOfGlyphs == -1)
        {
            MaximumProfileTable maximumProfile = getMaximumProfile();
            if (maximumProfile != null)
            {
                numberOfGlyphs = maximumProfile.getNumGlyphs();
            }
            else
            {
                // this should never happen
                numberOfGlyphs = 0;
            }
        }
        return numberOfGlyphs;
    }

    /**
     * Returns the units per EM (Header.unitsPerEm).
     * 
     * @return units per EM
     * @throws IOException if there was an error reading the table.
     */
    public int getUnitsPerEm() throws IOException
    {
        if (unitsPerEm == -1)
        {
            HeaderTable header = getHeader();
            if (header != null)
            {
                unitsPerEm = header.getUnitsPerEm();
            }
            else
            {
                // this should never happen
                unitsPerEm = 0;
            }
        }
        return unitsPerEm;
    }

    /**
     * Returns the width for the given GID.
     * 
     * @param gid the GID
     * @return the width
     * @throws IOException if there was an error reading the metrics table.
     */
    public int getAdvanceWidth(int gid) throws IOException
    {
        HorizontalMetricsTable hmtx = getHorizontalMetrics();
        if (hmtx != null)
        {
            return hmtx.getAdvanceWidth(gid);
        }
        else
        {
            // this should never happen
            return 250;
        }
    }

    /**
     * Returns the height for the given GID.
     * 
     * @param gid the GID
     * @return the height
     * @throws IOException if there was an error reading the metrics table.
     */
    public int getAdvanceHeight(int gid) throws IOException
    {
        VerticalMetricsTable vmtx = getVerticalMetrics();
        if (vmtx != null)
        {
            return vmtx.getAdvanceHeight(gid);
        }
        else
        {
            // this should never happen
            return 250;
        }
    }

    @Override
    public String getName() throws IOException
    {
        NamingTable namingTable = getNaming();
        if (namingTable != null)
        {
            return namingTable.getPostScriptName();
        }
        else
        {
            return null;
        }
    }

    private void readPostScriptNames() throws IOException
    {
        Map<String, Integer> psnames = postScriptNames;
        if (psnames == null)
        {
            // the getter is already synchronized
            PostScriptTable post = getPostScript();
            synchronized (lockPSNames)
            {
                psnames = postScriptNames;
                if (psnames == null)
                {
                    String[] names = post != null ? post.getGlyphNames() : null;
                    if (names != null)
                    {
                        psnames = new HashMap<>(names.length);
                        for (int i = 0; i < names.length; i++)
                        {
                            psnames.put(names[i], i);
                        }
                    }
                    else
                    {
                        psnames = new HashMap<>();
                    }
                    postScriptNames = psnames;
                }
            }
        }
    }

    /**
     * Returns the best Unicode from the font (the most general). The PDF spec says that "The means by which this is
     * accomplished are implementation-dependent."
     *
     * The returned cmap will perform glyph substitution.
     *
     * @return cmap to perform glyph substitution
     * 
     * @throws IOException if the font could not be read
     */
    public CmapLookup getUnicodeCmapLookup() throws IOException
    {
        return getUnicodeCmapLookup(true);
    }

    /**
     * Returns the best Unicode from the font (the most general). The PDF spec says that "The means by which this is
     * accomplished are implementation-dependent."
     *
     * The returned cmap will perform glyph substitution.
     *
     * @param isStrict False if we allow falling back to any cmap, even if it's not Unicode.
     * @return cmap to perform glyph substitution
     * 
     * @throws IOException if the font could not be read, or there is no Unicode cmap
     */
    public CmapLookup getUnicodeCmapLookup(boolean isStrict) throws IOException
    {
        CmapSubtable cmap = getUnicodeCmapImpl(isStrict);
        if (!enabledGsubFeatures.isEmpty())
        {
            GlyphSubstitutionTable table = getGsub();
            if (table != null)
            {
                return new SubstitutingCmapLookup(cmap, table,
                        Collections.unmodifiableList(enabledGsubFeatures));
            }
        }
        return cmap;
    }

    private CmapSubtable getUnicodeCmapImpl(boolean isStrict) throws IOException
    {
        CmapTable cmapTable = getCmap();
        if (cmapTable == null)
        {
            if (isStrict)
            {
                throw new IOException("The TrueType font " + getName() + " does not contain a 'cmap' table");
            }
            else
            {
                return null;
            }
        }

        CmapSubtable cmap = cmapTable.getSubtable(CmapTable.PLATFORM_UNICODE,
                                                  CmapTable.ENCODING_UNICODE_2_0_FULL);
        if (cmap == null)
        {
            cmap = cmapTable.getSubtable(CmapTable.PLATFORM_WINDOWS,
                                         CmapTable.ENCODING_WIN_UNICODE_FULL);
        }
        if (cmap == null)
        {
            cmap = cmapTable.getSubtable(CmapTable.PLATFORM_UNICODE,
                                         CmapTable.ENCODING_UNICODE_2_0_BMP);
        }
        if (cmap == null)
        {
            cmap = cmapTable.getSubtable(CmapTable.PLATFORM_WINDOWS,
                                         CmapTable.ENCODING_WIN_UNICODE_BMP);
        }
        if (cmap == null)
        {
            // Microsoft's "Recommendations for OpenType Fonts" says that "Symbol" encoding
            // actually means "Unicode, non-standard character set"
            cmap = cmapTable.getSubtable(CmapTable.PLATFORM_WINDOWS,
                                         CmapTable.ENCODING_WIN_SYMBOL);
        }
        if (cmap == null)
        {
            if (isStrict)
            {
                throw new IOException("The TrueType font does not contain a Unicode cmap");
            }
            else if (cmapTable.getCmaps().length > 0)
            {
                // fallback to the first cmap (may not be Unicode, so may produce poor results)
                cmap = cmapTable.getCmaps()[0];
            }
        }
        return cmap;
    }

    /**
     * Returns the GID for the given PostScript name, if the "post" table is present.
     * 
     * @param name the PostScript name.
     * @return the GID for the given PostScript name
     * 
     * @throws IOException if the font data could not be read
     */
    public int nameToGID(String name) throws IOException
    {
        // look up in 'post' table
        readPostScriptNames();
        if (postScriptNames != null)
        {
            Integer gid = postScriptNames.get(name);
            if (gid != null && gid > 0 && gid < getMaximumProfile().getNumGlyphs())
            {
                return gid;
            }
        }

        // look up in 'cmap'
        int uni = parseUniName(name);
        if (uni > -1)
        {
            CmapLookup cmap = getUnicodeCmapLookup(false);
            return cmap.getGlyphId(uni);
        }

        // PDFBOX-5604: assume gnnnnn is a gid
        if (name.matches("g\\d+"))
        {
            return Integer.parseInt(name.substring(1));
        }

        return 0;
    }

    /**
     * Returns the GSubData of the GlyphSubstitutionTable if present.
     * 
     * @return the GSubData of the GlyphSubstitutionTable or {@link GsubData#NO_DATA_FOUND} if no GSUB data is
     * available, its scripts are not supported or it was disabled for that font
     * @throws IOException if the font data could not be read
     */
    public GsubData getGsubData() throws IOException
    {
        if (!enableGsub)
        {
            return GsubData.NO_DATA_FOUND;
        }

        GlyphSubstitutionTable table = getGsub();
        if (table == null)
        {
            return GsubData.NO_DATA_FOUND;
        }

        return table.getGsubData();
    }

    /**
     * Parses a Unicode PostScript name in the format uniXXXX.
     */
    private int parseUniName(String name)
    {
        if (name.startsWith("uni") && name.length() == 7)
        {
            int nameLength = name.length();
            StringBuilder uniStr = new StringBuilder();
            try
            {
                for (int chPos = 3; chPos + 4 <= nameLength; chPos += 4)
                {
                    int codePoint = Integer.parseInt(name.substring(chPos, chPos + 4), 16);
                    if (codePoint <= 0xD7FF || codePoint >= 0xE000) // disallowed code area
                    {
                        uniStr.append((char) codePoint);
                    }
                }
                String unicode = uniStr.toString();
                if (unicode.isEmpty())
                {
                    return -1;
                }
                return unicode.codePointAt(0);
            }
            catch (NumberFormatException e)
            {
                return -1;
            }
        }
        return -1;
    }
    
    @Override
    public GeneralPath getPath(String name) throws IOException
    {
        int gid = nameToGID(name);

        // some glyphs have no outlines (e.g. space, table, newline)
        GlyphData glyph = getGlyph().getGlyph(gid);
        if (glyph == null)
        {
            return new GeneralPath();
        }
        else
        {
            // must scaled by caller using FontMatrix
            return glyph.getPath();
        }
    }

    @Override
    public float getWidth(String name) throws IOException
    {
        int gid = nameToGID(name);
        return getAdvanceWidth(gid);
    }

    @Override
    public boolean hasGlyph(String name) throws IOException
    {
        return nameToGID(name) != 0;
    }

    @Override
    public BoundingBox getFontBBox() throws IOException
    {
        HeaderTable headerTable = getHeader();
        short xMin = headerTable.getXMin();
        short xMax = headerTable.getXMax();
        short yMin = headerTable.getYMin();
        short yMax = headerTable.getYMax();
        float scale = 1000f / getUnitsPerEm();
        return new BoundingBox(xMin * scale, yMin * scale, xMax * scale, yMax * scale);
    }

    @Override
    public List<Number> getFontMatrix() throws IOException
    {
        float scale = 1000f / getUnitsPerEm();
        return List.of(0.001f * scale, 0, 0, 0.001f * scale, 0, 0);
    }

    /**
     * Enable a particular glyph substitution feature. This feature might not be supported by the
     * font, or might not be implemented in PDFBox yet.
     *
     * @param featureTag The GSUB feature to enable
     */
    public void enableGsubFeature(String featureTag)
    {
        enabledGsubFeatures.add(featureTag);
    }

    /**
     * Disable a particular glyph substitution feature.
     *
     * @param featureTag The GSUB feature to disable
     */
    public void disableGsubFeature(String featureTag)
    {
        enabledGsubFeatures.remove(featureTag);
    }

    /**
     * Enable glyph substitutions for vertical writing.
     */
    public void enableVerticalSubstitutions()
    {
        enableGsubFeature("vrt2");
        enableGsubFeature("vert");
    }

    @Override
    public String toString()
    {
        try
        {
            NamingTable namingTable = getNaming();
            if (namingTable != null)
            {
                return namingTable.getPostScriptName();
            }
            else
            {
                return "(null)";
            }
        }
        catch (IOException e)
        {
            LOG.debug("Error getting the NamingTable for the font", e);
            return "(null - " + e.getMessage() + ")";
        }
    }
}
