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

import java.io.IOException;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.NumberFormat;
import java.util.Collection;
import java.util.Locale;
import java.util.Map;

import org.apache.fontbox.cff.CFFCIDFont;
import org.apache.fontbox.cff.CFFFont;
import org.apache.fontbox.cff.CFFType1Font;
import org.apache.fontbox.cff.DataOutput;
import org.apache.fontbox.cff.Type1FontUtil;

/**
 * This class represents a formatter for a given Type1 font.
 * author Villu Ruusmann
 * @version $Revision: 1.0 $
 */
public final class Type1FontFormatter {
    private Map<Integer, Integer> gids;

    public Type1FontFormatter(Map<Integer, Integer> gids) {
        this.gids = gids;
    }

    /**
     * Read and convert a given CFFFont.
     * @param font the given CFFFont
     * @param i
     * @return the Type1 font
     * @throws IOException if an error occurs during reading the given font
     */
    public byte[] format(CFFFont font, String i) throws IOException {
        DataOutput output = new DataOutput();
        printFont(font, output, i);
        return output.getBytes();
    }

    private void printFont(CFFFont font, DataOutput output, String iStr)
            throws IOException {
        output.println("%!FontType1-1.0 " + font.getName() + iStr + " "
                + font.getTopDict().get("version"));

        printFontDictionary(font, output, iStr);

        for (int i = 0; i < 8; i++) {
            StringBuilder sb = new StringBuilder();

            for (int j = 0; j < 64; j++) {
                sb.append("0");
            }

            output.println(sb.toString());
        }

        output.println("cleartomark");
    }

    private void printFontDictionary(CFFFont font, DataOutput output, String iStr)
            throws IOException {
        output.println("10 dict begin");
        output.println("/FontInfo 10 dict dup begin");
        output.println("/version (" + font.getTopDict().get("version")
                + ") readonly def");
        output.println("/Notice (" + font.getTopDict().get("Notice")
                + ") readonly def");
        output.println("/FullName (" + font.getTopDict().get("FullName")
                + ") readonly def");
        output.println("/FamilyName (" + font.getTopDict().get("FamilyName")
                + ") readonly def");
        output.println("/Weight (" + font.getTopDict().get("Weight")
                + ") readonly def");
        output.println("/ItalicAngle " + font.getTopDict().get("ItalicAngle")
                + " def");
        output.println("/isFixedPitch " + font.getTopDict().get("isFixedPitch")
                + " def");
        output.println("/UnderlinePosition "
                + font.getTopDict().get("UnderlinePosition") + " def");
        output.println("/UnderlineThickness "
                + font.getTopDict().get("UnderlineThickness") + " def");
        output.println("end readonly def");
        output.println("/FontName /" + font.getName() + iStr + " def");
        output.println("/PaintType " + font.getTopDict().get("PaintType") + " def");
        output.println("/FontType 1 def");
        NumberFormat matrixFormat = new DecimalFormat("0.########", new DecimalFormatSymbols(Locale.US));
        output.println("/FontMatrix "
                + formatArray(font.getTopDict().get("FontMatrix"), matrixFormat, false)
                + " readonly def");
        output.println("/FontBBox "
                + formatArray(font.getTopDict().get("FontBBox"), false)
                + " readonly def");
        output.println("/StrokeWidth " + font.getTopDict().get("StrokeWidth")
                + " def");

        int max = 0;
        StringBuilder sb = new StringBuilder();
        for (Map.Entry<Integer, Integer> gid : gids.entrySet()) {
            String name = "gid_" + gid.getKey();
            if (gid.getKey() == 0) {
                name = ".notdef";
            }
            if (font instanceof CFFType1Font) {
                name = font.getCharset().getNameForGID(gid.getKey());
            }
            sb.append(String.format("dup %d /%s put", gid.getValue(), name)).append('\n');
            max = Math.max(max, gid.getValue());
        }
        output.println("/Encoding " + (max + 1) + " array");
        output.println("0 1 " + max + " {1 index exch /.notdef put} for");
        output.print(sb.toString());
        output.println("readonly def");

        output.println("currentdict end");

        DataOutput eexecOutput = new DataOutput();

        printEexecFontDictionary(font, eexecOutput);

        output.println("currentfile eexec");

        byte[] eexecBytes = Type1FontUtil.eexecEncrypt(eexecOutput.getBytes());
        output.write(eexecBytes);
    }

    private void printEexecFontDictionary(CFFFont font, DataOutput output)
            throws IOException {
        output.println("dup /Private 15 dict dup begin");
        output.println("/RD {string currentfile exch readstring pop} executeonly def");
        output.println("/ND {noaccess def} executeonly def");
        output.println("/NP {noaccess put} executeonly def");
        Map<String, Object> privDict;
        if (font instanceof CFFCIDFont) {
            privDict = ((CFFCIDFont)font).getPrivDicts().get(0);
        } else {
            privDict = ((CFFType1Font)font).getPrivateDict();
        }
        output.println("/BlueValues "
                + formatArray(privDict.get("BlueValues"), true) + " ND");
        output.println("/OtherBlues "
                + formatArray(privDict.get("OtherBlues"), true) + " ND");
        output.println("/BlueScale " + privDict.get("BlueScale") + " def");
        output.println("/BlueShift " + privDict.get("BlueShift") + " def");
        output.println("/BlueFuzz " + privDict.get("BlueFuzz") + " def");
        output.println("/StdHW " + formatArray(privDict.get("StdHW"), true)
                + " ND");
        output.println("/StdVW " + formatArray(privDict.get("StdVW"), true)
                + " ND");
        output.println("/ForceBold " + privDict.get("ForceBold") + " def");
        output.println("/MinFeature {16 16} def");
        output.println("/password 5839 def");

        output.println("2 index /CharStrings " + gids.size() + " dict dup begin");
        Type1CharStringFormatter formatter = new Type1CharStringFormatter();
        for (int gid : gids.keySet()) {
            String mapping = "gid_" + gid;
            if (gid == 0) {
                mapping = ".notdef";
            }
            byte[] type1Bytes;
            if (font instanceof CFFCIDFont) {
                int cid = font.getCharset().getCIDForGID(gid);
                type1Bytes = formatter.format(((CFFCIDFont)font).getType2CharString(cid).getType1Sequence());
            } else {
                mapping = font.getCharset().getNameForGID(gid);
                type1Bytes = formatter.format(((CFFType1Font)font).getType1CharString(mapping).getType1Sequence());
            }
            byte[] charstringBytes = Type1FontUtil.charstringEncrypt(type1Bytes, 4);
            output.print("/" + mapping + " " + charstringBytes.length + " RD ");
            output.write(charstringBytes);
            output.print(" ND");
            output.println();
        }

        output.println("end");
        output.println("end");

        output.println("readonly put");
        output.println("noaccess put");
        output.println("dup /FontName get exch definefont pop");
        output.println("mark currentfile closefile");
    }

    private static String formatArray(Object object, boolean executable) {
        return formatArray(object, null, executable);
    }

    private static String formatArray(Object object, NumberFormat format, boolean executable) {
        StringBuffer sb = new StringBuffer();

        sb.append(executable ? "{" : "[");

        if (object instanceof Collection) {
            String sep = "";

            Collection<?> elements = (Collection<?>) object;
            for (Object element : elements) {
                sb.append(sep).append(formatElement(element, format));

                sep = " ";
            }
        } else if (object instanceof Number) {
            sb.append(formatElement(object, format));
        }

        sb.append(executable ? "}" : "]");

        return sb.toString();
    }

    private static String formatElement(Object object, NumberFormat format) {
        if (format != null) {
            if (object instanceof Double || object instanceof Float) {
                Number number = (Number)object;
                return format.format(number.doubleValue());
            } else if (object instanceof Long || object instanceof Integer) {
                Number number = (Number)object;
                return format.format(number.longValue());
            }
        }
        return String.valueOf(object);
    }
}
