/*
 * 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.fop.render.pdf.pdfbox;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

import org.apache.fontbox.cff.CFFType1Font;
import org.apache.fontbox.cmap.CMap;

import org.apache.fontbox.ttf.CmapSubtable;
import org.apache.fontbox.ttf.TrueTypeFont;

import org.apache.pdfbox.cos.COSArray;
import org.apache.pdfbox.cos.COSBase;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.cos.COSNumber;

import org.apache.pdfbox.pdmodel.common.PDStream;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDFontDescriptor;
import org.apache.pdfbox.pdmodel.font.PDTrueTypeFont;
import org.apache.pdfbox.pdmodel.font.PDType1CFont;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.apache.pdfbox.pdmodel.font.encoding.BuiltInEncoding;
import org.apache.pdfbox.pdmodel.font.encoding.Encoding;

import org.apache.fop.fonts.EmbeddingMode;
import org.apache.fop.fonts.FontType;
import org.apache.fop.fonts.SingleByteEncoding;
import org.apache.fop.fonts.SingleByteFont;
import org.apache.fop.pdf.PDFDictionary;

public class FOPPDFSingleByteFont extends SingleByteFont implements FOPPDFFont {
    private int fontCount;
    private FontContainer font;
    protected PDFDictionary ref;
    protected Map<String, Integer> charMapGlobal = new LinkedHashMap<String, Integer>();
    private Map<Integer, Integer> newWidth = new HashMap<Integer, Integer>();
    private Map<String, byte[]> charStringsDict;
    private List<MergeTTFonts.Cmap> newCmap = new ArrayList<MergeTTFonts.Cmap>();
    private Map<Integer, String> encodingMap = new TreeMap<Integer, String>();
    private int encodingSkip;
    private MergeFonts mergeFonts;
    private String shortFontName;
    private final Map<COSDictionary, FontContainer> fontMap = new HashMap<COSDictionary, FontContainer>();

    public FOPPDFSingleByteFont(COSDictionary fontData, String name) throws IOException {
        super(null, EmbeddingMode.FULL);
        if (fontData.getItem(COSName.SUBTYPE) == COSName.TRUE_TYPE) {
            setFontType(FontType.TRUETYPE);
        }
        width = new int[0];
        font = getFont(fontData);
        setFirstChar(font.getFirstChar());
        setLastChar(font.getLastChar());
        shortFontName = MergeFontsPDFWriter.getName(font.font.getName());
        loadFontFile(font);
        float[] bBoxF = font.getBoundingBox();
        int[] bBox = new int[bBoxF.length];
        for (int i = 0; i < bBox.length; i++) {
            bBox[i] = (int)bBoxF[i];
        }
        setFontBBox(bBox);

        setFontName(name);
        Object cmap = getCmap(font);
        for (int i = font.getFirstChar(); i <= font.getLastChar(); i++) {
            String mappedChar = getChar(cmap, i);
            if (mappedChar != null && !charMapGlobal.containsKey(mappedChar)) {
                charMapGlobal.put(mappedChar, i);
            }
        }
        //mark font as used
        notifyMapOperation();
        FOPPDFMultiByteFont.setProperties(this, font.font);
        if (font.getWidths() != null) {
            //if width contains 0 we cant rely on codeToNameMap
            boolean usesZero = font.getWidths().contains(0);
            Set<Integer> codeToName = getCodeToName(font.getEncoding()).keySet();
            for (int i = getFirstChar();
                 i <= Math.min(getLastChar(), getFirstChar() + font.getWidths().size()); i++) {
                if (usesZero || codeToName.contains(i)) {
                    int w = font.getWidths().get(i - getFirstChar());
                    newWidth.put(i, w);
                } else {
                    newWidth.put(i, 0);
                }
            }
        }
        mapping = new FOPPDFEncoding();
        encodingSkip = font.getLastChar() + 1;
        addEncoding(font);
    }

    private Map<Integer, String> getCodeToName(Encoding encoding) {
        Map<Integer, String> codeToName = new HashMap<Integer, String>();
        if (encoding != null) {
            COSBase cos = null;
            if (!(encoding instanceof BuiltInEncoding)) {
                cos = encoding.getCOSObject();
            }
            if (cos instanceof COSDictionary) {
                COSDictionary enc = (COSDictionary) cos;
                COSName baseEncodingName = (COSName) enc.getDictionaryObject(COSName.BASE_ENCODING);
                if (baseEncodingName != null) {
                    Encoding baseEncoding = Encoding.getInstance(baseEncodingName);
                    codeToName.putAll(baseEncoding.getCodeToNameMap());
                }
                COSArray differences = (COSArray)enc.getDictionaryObject(COSName.DIFFERENCES);
                int currentIndex = -1;
                for (int i = 0; differences != null && i < differences.size(); i++) {
                    COSBase next = differences.getObject(i);
                    if (next instanceof COSNumber) {
                        currentIndex = ((COSNumber)next).intValue();
                    } else if (next instanceof COSName) {
                        COSName name = (COSName)next;
                        codeToName.put(currentIndex++, name.getName());
                    }
                }
            } else {
                return encoding.getCodeToNameMap();
            }
        }
        return codeToName;
    }

    private Object getCmap(FontContainer font) throws IOException {
        if (font.getEncoding() != null) {
            return font.getEncoding();
        }
        if (font.getToUnicodeCMap() == null) {
            throw new IOException("No cmap found in " + font.font.getName());
        }
        return font.getToUnicodeCMap();
    }

    private PDStream readFontFile(PDFont font) throws IOException {
        PDFontDescriptor fd = font.getFontDescriptor();
        setFlags(fd.getFlags());
        PDStream ff = fd.getFontFile3();
        if (ff == null) {
            ff = fd.getFontFile2();
            if (ff == null) {
                ff = fd.getFontFile();
            }
        } else {
            setFontType(FontType.TYPE1C);
        }
        if (ff == null) {
            throw new IOException(font.getName() + " no font file");
        }
        return ff;
    }

    private void loadFontFile(FontContainer font) throws IOException {
        PDStream ff = readFontFile(font.font);
        mergeFontFile(ff.createInputStream(), font);
        if (font.font instanceof PDTrueTypeFont) {
            TrueTypeFont ttfont = ((PDTrueTypeFont) font.font).getTrueTypeFont();
            CmapSubtable[] cmapList = ttfont.getCmap().getCmaps();
            for (CmapSubtable c : cmapList) {
                MergeTTFonts.Cmap tempCmap = getNewCmap(c.getPlatformId(), c.getPlatformEncodingId());
                for (int i = 0; i < 256 * 256; i++) {
                    int gid = c.getGlyphId(i);
                    if (gid != 0) {
                        tempCmap.glyphIdToCharacterCode.put(i, gid);
                    }
                }
            }
            FOPPDFMultiByteFont.mergeMaxp(ttfont, ((MergeTTFonts)mergeFonts).maxp);
        }
    }

    private MergeTTFonts.Cmap getNewCmap(int platformID, int platformEncodingID) {
        for (MergeTTFonts.Cmap cmap : newCmap) {
            if (cmap.platformId == platformID && cmap.platformEncodingId == platformEncodingID) {
                return cmap;
            }
        }
        MergeTTFonts.Cmap cmap = new MergeTTFonts.Cmap(platformID, platformEncodingID);
        newCmap.add(cmap);
        return cmap;
    }

    @Override
    public boolean hasChar(char c) {
        return charMapGlobal.containsKey(String.valueOf(c));
    }

    @Override
    public char mapChar(char c) {
        return mapping.mapChar(c);
    }

    public String getEmbedFontName() {
        return shortFontName;
    }

    public int[] getWidths() {
        width = new int[getLastChar() - getFirstChar() + 1];
        for (int i = getFirstChar(); i <= getLastChar(); i++) {
            if (newWidth.containsKey(i)) {
                width[i - getFirstChar()] = newWidth.get(i);
            } else {
                width[i - getFirstChar()] = 0;
            }
        }
        return width.clone();
    }

    public String addFont(COSDictionary fontData) throws IOException {
        FontContainer font = getFont(fontData);
        if ((font.font instanceof PDType1Font || font.font instanceof PDType1CFont) && differentGlyphData(font.font)) {
            return null;
        }
        mergeWidths(font);
        if (font.getFirstChar() < getFirstChar()) {
            setFirstChar(font.getFirstChar());
        }
        for (int w : newWidth.keySet()) {
            if (w > getLastChar()) {
                setLastChar(w);
            }
        }
        loadFontFile(font);
        addEncoding(font);
        return getFontName();
    }

    public int size() {
        return fontCount;
    }

    private Map<String, byte[]> getCharStringsDict(PDFont font) throws IOException {
        if (font instanceof PDType1Font) {
            return ((PDType1Font)font).getType1Font().getCharStringsDict();
        }
        CFFType1Font cffFont = ((PDType1CFont) font).getCFFType1Font();
        List<byte[]> bytes = cffFont.getCharStringBytes();
        Map<String, byte[]> map = new HashMap<String, byte[]>();
        for (int i = 0; i < bytes.size(); i++) {
            map.put(cffFont.getCharset().getNameForGID(i), bytes.get(i));
        }
        return map;
    }

    private boolean differentGlyphData(PDFont otherFont) throws IOException {
        if (charStringsDict == null) {
            charStringsDict = getCharStringsDict(font.font);
        }
        Map<String, byte[]> otherFontMap = getCharStringsDict(otherFont);
        for (Map.Entry<String, byte[]> s : otherFontMap.entrySet()) {
            if (charStringsDict.containsKey(s.getKey())) {
                int numberDiff = 0;
                byte[] b1 = charStringsDict.get(s.getKey());
                byte[] b2 = s.getValue();
                int b1Index = b1.length - 1;
                int b2Index = b2.length - 1;
                while (b1Index >= 0 && b2Index >= 0) {
                    if (b1[b1Index] != b2[b2Index]) {
                        numberDiff++;
                        if (numberDiff > 2) {
                            break;
                        }
                    }
                    b1Index--;
                    b2Index--;
                }
                if (numberDiff > 2) {
//                        log.info(getFontName() + " " + s.getKey() + " not equal " + numberdiff);
                    return true;
                }
            }
        }
        return false;
    }

    private void mergeWidths(FontContainer font) throws IOException {
        int w = 0;
        int skipGlyphIndex = getLastChar() + 1;
        Object cmap = getCmap(font);
        Set<Integer> codeToName = getCodeToName(font.getEncoding()).keySet();
        for (int i = font.getFirstChar(); i <= font.getLastChar(); i++) {
            boolean addedWidth = false;
            int glyphIndexPos = skipGlyphIndex;
            if (font.font instanceof PDTrueTypeFont) {
                glyphIndexPos = i;
            }
            int neww = 0;
            if (font.getWidths() != null) {
                neww = font.getWidths().get(i - font.getFirstChar());
                if (!newWidth.containsKey(i) || newWidth.get(i) == 0) {
                    if (getFontType() == FontType.TYPE1
                            || font.font instanceof PDTrueTypeFont
                            || codeToName.contains(i)) {
                        newWidth.put(i, neww);
                        glyphIndexPos = i;
                    } else {
                        newWidth.put(i, 0);
                    }
                    addedWidth = true;
                }
            }
            String mappedChar = getChar(cmap, i);
            if (mappedChar != null && !charMapGlobal.containsKey(mappedChar)) {
                charMapGlobal.put(mappedChar, glyphIndexPos);
                if (!addedWidth && w < font.getWidths().size()) {
                    newWidth.put(newWidth.size() + getFirstChar(), neww);
                }
                skipGlyphIndex++;
            }
            w++;
        }
    }

    private String getChar(Object cmap, int i) throws IOException {
        if (cmap instanceof CMap) {
            CMap c = (CMap)cmap;
            return c.toUnicode(i);
        }
        Encoding enc = (Encoding)cmap;
        return enc.getName(i);
    }

    public String getEncodingName() {
        return font.getBaseEncodingName();
    }

    private void addEncoding(FontContainer fontForEnc) {
        List<String> added = new ArrayList<String>(encodingMap.values());
        Map<Integer, String> codeToName = getCodeToName(fontForEnc.getEncoding());
        for (int i = fontForEnc.getFirstChar(); i <= fontForEnc.getLastChar(); i++) {
            if (codeToName.keySet().contains(i)) {
                String s = codeToName.get(i);
                if (!added.contains(s) || (added.contains(s) && !encodingMap.containsKey(i))) {
                    if (!encodingMap.containsKey(i)) {
                        encodingMap.put(i, s);
                    } else {
                        encodingMap.put(encodingSkip, s);
                        encodingSkip++;
                    }
                }
            }
        }
    }

    class FOPPDFEncoding implements SingleByteEncoding {
        private boolean cmap;

        public String getName() {
            return "FOPPDFEncoding";
        }

        public char mapChar(char c) {
            if (charMapGlobal.containsKey(String.valueOf(c))) {
                return (char)charMapGlobal.get(String.valueOf(c)).intValue();
            }
            return 0;
        }

        public String[] getCharNameMap() {
            Collection<String> v = encodingMap.values();
            return v.toArray(new String[v.size()]);
        }

        public char[] getUnicodeCharMap() {
            if (cmap) {
                if (font.getToUnicode() == null) {
                    return new char[0];
                }
                List<String> cmapStrings = new ArrayList<String>();
                Map<Integer, String> cm = new HashMap<Integer, String>();
                for (Map.Entry<String, Integer> o : charMapGlobal.entrySet()) {
                    cm.put(o.getValue(), o.getKey());
                }
                for (int i = 0; i < getLastChar() + 1; i++) {
                    if (cm.containsKey(i)) {
                        cmapStrings.add(cm.get(i));
                    } else {
                        cmapStrings.add(" ");
                    }
                }
                return fromStringToCharArray(cmapStrings);
            }
            cmap = true;
            return toCharArray(encodingMap.keySet());
        }

        private char[] fromStringToCharArray(Collection<String> list) {
            char[] ret = new char[list.size()];
            int i = 0;
            for (String e : list) {
                if (e.length() > 0) {
                    ret[i++] = e.charAt(0);
                }
            }
            return ret;
        }

        private char[] toCharArray(Collection<Integer> list) {
            char[] ret = new char[list.size()];
            int i = 0;
            for (int e : list) {
                ret[i++] = (char)e;
            }
            return ret;
        }
    }

    public PDFDictionary getRef() {
        return ref;
    }

    public void setRef(PDFDictionary d) {
        ref = d;
    }

    public boolean isEmbeddable() {
        return true;
    }

    public boolean isSymbolicFont() {
        return false;
    }

    private void mergeFontFile(InputStream ff, FontContainer pdFont) throws IOException {
        if (mergeFonts == null) {
            if (getFontType() == FontType.TRUETYPE) {
                mergeFonts = new MergeTTFonts(newCmap);
            } else if (getFontType() == FontType.TYPE1) {
                mergeFonts = new MergeType1Fonts();
            } else {
                mergeFonts = new MergeCFFFonts();
            }
        }
        Map<Integer, Integer> chars = new HashMap<Integer, Integer>();
        chars.put(0, 0);
        mergeFonts.readFont(ff, shortFontName, pdFont, chars, false);
        fontCount++;
    }

    public InputStream getInputStream() throws IOException {
        return new ByteArrayInputStream(mergeFonts.getMergedFontSubset());
    }

    protected FontContainer getFont(COSDictionary fontData) throws IOException {
        if (!fontMap.containsKey(fontData)) {
            if (fontMap.size() > 10) {
                fontMap.clear();
            }
            fontMap.put(fontData, new FontContainer(fontData));
        }
        return fontMap.get(fontData);
    }
}
