/* ====================================================================
   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.poi.common.usermodel.fonts;

import static org.apache.poi.util.GenericRecordUtil.getBitsAsString;
import static org.apache.poi.util.GenericRecordUtil.safeEnum;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.function.Supplier;

import org.apache.poi.common.usermodel.GenericRecord;
import org.apache.poi.util.IOUtils;
import org.apache.poi.util.LittleEndianByteArrayInputStream;
import org.apache.poi.util.LittleEndianInput;
import org.apache.poi.util.LittleEndianInputStream;


/**
 * The header data of an EOT font.<p>
 *
 * Currently only version 1 fields are read to identify a stream to be embedded.
 *
 * @see <a href="http://www.w3.org/Submission/EOT">Embedded OpenType (EOT) File Format</a>
 */
@SuppressWarnings({"FieldCanBeLocal", "unused", "Duplicates", "WeakerAccess"})
public class FontHeader implements FontInfo, GenericRecord {

    public enum PanoseFamily {
        ANY, NO_FIT, TEXT_DISPLAY, SCRIPT, DECORATIVE, PICTORIAL
    }

    public enum PanoseSerif {
        ANY, NO_FIT, COVE, OBTUSE_COVE, SQUARE_COVE, OBTUSE_SQUARE_COVE, SQUARE, THIN, BONE,
        EXAGGERATED, TRIANGLE, NORMAL_SANS, OBTUSE_SANS, PERP_SANS, FLARED, ROUNDED
    }

    public enum PanoseWeight {
        ANY, NO_FIT, VERY_LIGHT, LIGHT, THIN, BOOK, MEDIUM, DEMI, BOLD, HEAVY, BLACK, NORD
    }

    public enum PanoseProportion {
        ANY, NO_FIT, OLD_STYLE, MODERN, EVEN_WIDTH, EXPANDED, CONDENSED, VERY_EXPANDED, VERY_CONDENSED, MONOSPACED
    }

    public enum PanoseContrast {
        ANY, NO_FIT, NONE, VERY_LOW, LOW, MEDIUM_LOW, MEDIUM, MEDIUM_HIGH, HIGH, VERY_HIGH
    }

    public enum PanoseStroke {
        ANY, NO_FIT, GRADUAL_DIAG, GRADUAL_TRAN, GRADUAL_VERT, GRADUAL_HORZ, RAPID_VERT, RAPID_HORZ, INSTANT_VERT
    }

    public enum PanoseArmStyle {
        ANY, NO_FIT, STRAIGHT_ARMS_HORZ, STRAIGHT_ARMS_WEDGE, STRAIGHT_ARMS_VERT, STRAIGHT_ARMS_SINGLE_SERIF,
        STRAIGHT_ARMS_DOUBLE_SERIF, BENT_ARMS_HORZ, BENT_ARMS_WEDGE, BENT_ARMS_VERT, BENT_ARMS_SINGLE_SERIF,
        BENT_ARMS_DOUBLE_SERIF,
    }

    public enum PanoseLetterForm {
        ANY, NO_FIT, NORMAL_CONTACT, NORMAL_WEIGHTED, NORMAL_BOXED, NORMAL_FLATTENED, NORMAL_ROUNDED,
        NORMAL_OFF_CENTER, NORMAL_SQUARE, OBLIQUE_CONTACT, OBLIQUE_WEIGHTED, OBLIQUE_BOXED, OBLIQUE_FLATTENED,
        OBLIQUE_ROUNDED, OBLIQUE_OFF_CENTER, OBLIQUE_SQUARE
    }

    public enum PanoseMidLine {
        ANY, NO_FIT, STANDARD_TRIMMED, STANDARD_POINTED, STANDARD_SERIFED, HIGH_TRIMMED, HIGH_POINTED, HIGH_SERIFED,
        CONSTANT_TRIMMED, CONSTANT_POINTED, CONSTANT_SERIFED, LOW_TRIMMED, LOW_POINTED, LOW_SERIFED
    }

    public enum PanoseXHeight {
        ANY, NO_FIT, CONSTANT_SMALL, CONSTANT_STD, CONSTANT_LARGE, DUCKING_SMALL, DUCKING_STD, DUCKING_LARGE
    }

    private static final int[] FLAGS_MASKS = {
        0x00000001, 0x00000004, 0x00000010, 0x00000020, 0x00000040, 0x00000080, 0x10000000
    };

    private static final String[] FLAGS_NAMES = {
        "SUBSET", "TTCOMPRESSED", "FAILIFVARIATIONSIMULATED", "EMBEDEUDC", "VALIDATIONTESTS", "WEBOBJECT", "XORENCRYPTDATA"
    };

    private static final int[] FSTYPE_MASKS = {
        0x0000, 0x0002, 0x0004, 0x0008, 0x0100, 0x0200
    };

    private static final String[] FSTYPE_NAMES = {
        "INSTALLABLE_EMBEDDING",
        "RESTRICTED_LICENSE_EMBEDDING",
        "PREVIEW_PRINT_EMBEDDING",
        "EDITABLE_EMBEDDING",
        "NO_SUBSETTING",
        "BITMAP_EMBEDDING_ONLY"
    };

    /**
     * Fonts with a font weight of 400 are regarded as regular weighted.
     * Higher font weights (up to 1000) are bold - lower weights are thin.
     */
    public static final int REGULAR_WEIGHT = 400;

    private int eotSize;
    private int fontDataSize;
    private int version;
    private int flags;
    private final byte[] panose = new byte[10];
    private byte charset;
    private byte italic;
    private int weight;
    private int fsType;
    private int magic;
    private int unicodeRange1;
    private int unicodeRange2;
    private int unicodeRange3;
    private int unicodeRange4;
    private int codePageRange1;
    private int codePageRange2;
    private int checkSumAdjustment;
    private String familyName;
    private String styleName;
    private String versionName;
    private String fullName;

    public void init(byte[] source, int offset, int length) {
        init(new LittleEndianByteArrayInputStream(source, offset, length));
    }

    public void init(LittleEndianInput leis) {
        eotSize = leis.readInt();
        fontDataSize = leis.readInt();
        version = leis.readInt();
        if (version != 0x00010000 && version != 0x00020001 && version != 0x00020002) {
            throw new RuntimeException("not a EOT font data stream");
        }
        flags = leis.readInt();
        leis.readFully(panose);
        charset = leis.readByte();
        italic = leis.readByte();
        weight = leis.readInt();
        fsType = leis.readUShort();
        magic = leis.readUShort();
        if (magic != 0x504C) {
            throw new RuntimeException("not a EOT font data stream");
        }
        unicodeRange1 = leis.readInt();
        unicodeRange2 = leis.readInt();
        unicodeRange3 = leis.readInt();
        unicodeRange4 = leis.readInt();
        codePageRange1 = leis.readInt();
        codePageRange2 = leis.readInt();
        checkSumAdjustment = leis.readInt();
        int reserved1 = leis.readInt();
        int reserved2 = leis.readInt();
        int reserved3 = leis.readInt();
        int reserved4 = leis.readInt();
        familyName = readName(leis);
        styleName = readName(leis);
        versionName = readName(leis);
        fullName = readName(leis);

    }

    public InputStream bufferInit(InputStream fontStream) throws IOException {
        LittleEndianInputStream is = new LittleEndianInputStream(fontStream);
        is.mark(1000);
        init(is);
        is.reset();
        return is;
    }

    private String readName(LittleEndianInput leis) {
        // padding
        leis.readShort();
        int nameSize = leis.readUShort();
        byte[] nameBuf = IOUtils.safelyAllocate(nameSize, 1000);
        leis.readFully(nameBuf);
        // may be 0-terminated, just trim it away
        return new String(nameBuf, 0, nameSize, StandardCharsets.UTF_16LE).trim();
    }

    public boolean isItalic() {
        return italic != 0;
    }

    public int getWeight() {
        return weight;
    }

    public boolean isBold() {
        return getWeight() > REGULAR_WEIGHT;
    }

    public byte getCharsetByte() {
        return charset;
    }

    public FontCharset getCharset() {
        return FontCharset.valueOf(getCharsetByte());
    }

    public FontPitch getPitch() {
        switch (getPanoseFamily()) {
            default:
            case ANY:
            case NO_FIT:
                return FontPitch.VARIABLE;

            // Latin Text
            case TEXT_DISPLAY:
            // Latin Decorative
            case DECORATIVE:
                return (getPanoseProportion() == PanoseProportion.MONOSPACED) ? FontPitch.FIXED : FontPitch.VARIABLE;

            // Latin Hand Written
            case SCRIPT:
            // Latin Symbol
            case PICTORIAL:
                return (getPanoseProportion() == PanoseProportion.MODERN) ? FontPitch.FIXED : FontPitch.VARIABLE;
        }

    }

    public FontFamily getFamily() {
        switch (getPanoseFamily()) {
            case ANY:
            case NO_FIT:
                return FontFamily.FF_DONTCARE;
            // Latin Text
            case TEXT_DISPLAY:
                switch (getPanoseSerif()) {
                    case TRIANGLE:
                    case NORMAL_SANS:
                    case OBTUSE_SANS:
                    case PERP_SANS:
                    case FLARED:
                    case ROUNDED:
                        return FontFamily.FF_SWISS;
                    default:
                        return FontFamily.FF_ROMAN;
                }
            // Latin Hand Written
            case SCRIPT:
                return FontFamily.FF_SCRIPT;
            // Latin Decorative
            default:
            case DECORATIVE:
                return FontFamily.FF_DECORATIVE;
            // Latin Symbol
            case PICTORIAL:
                return FontFamily.FF_MODERN;
        }
    }

    public String getFamilyName() {
        return familyName;
    }

    public String getStyleName() {
        return styleName;
    }

    public String getVersionName() {
        return versionName;
    }

    public String getFullName() {
        return fullName;
    }

    public byte[] getPanose() {
        return panose;
    }

    @Override
    public String getTypeface() {
        return getFamilyName();
    }

    public int getFlags() {
        return flags;
    }

    @Override
    public Map<String, Supplier<?>> getGenericProperties() {
        final Map<String,Supplier<?>> m = new LinkedHashMap<>();
        m.put("eotSize", () -> eotSize);
        m.put("fontDataSize", () -> fontDataSize);
        m.put("version", () -> version);
        m.put("flags", getBitsAsString(this::getFlags, FLAGS_MASKS, FLAGS_NAMES));
        m.put("panose.familyType", this::getPanoseFamily);
        m.put("panose.serifType", this::getPanoseSerif);
        m.put("panose.weight", this::getPanoseWeight);
        m.put("panose.proportion", this::getPanoseProportion);
        m.put("panose.contrast", this::getPanoseContrast);
        m.put("panose.stroke", this::getPanoseStroke);
        m.put("panose.armStyle", this::getPanoseArmStyle);
        m.put("panose.letterForm", this::getPanoseLetterForm);
        m.put("panose.midLine", this::getPanoseMidLine);
        m.put("panose.xHeight", this::getPanoseXHeight);
        m.put("charset", this::getCharset);
        m.put("italic", this::isItalic);
        m.put("weight", this::getWeight);
        m.put("fsType", getBitsAsString(() -> fsType, FSTYPE_MASKS, FSTYPE_NAMES));
        m.put("unicodeRange1", () -> unicodeRange1);
        m.put("unicodeRange2", () -> unicodeRange2);
        m.put("unicodeRange3", () -> unicodeRange3);
        m.put("unicodeRange4", () -> unicodeRange4);
        m.put("codePageRange1", () -> codePageRange1);
        m.put("codePageRange2", () -> codePageRange2);
        m.put("checkSumAdjustment", () -> checkSumAdjustment);
        m.put("familyName", this::getFamilyName);
        m.put("styleName", this::getStyleName);
        m.put("versionName", this::getVersionName);
        m.put("fullName", this::getFullName);
        return Collections.unmodifiableMap(m);
    }

    public PanoseFamily getPanoseFamily() {
        return safeEnum(PanoseFamily.values(), () -> panose[0]).get();
    }

    public PanoseSerif getPanoseSerif() {
        return safeEnum(PanoseSerif.values(), () -> panose[1]).get();
    }

    public PanoseWeight getPanoseWeight() {
        return safeEnum(PanoseWeight.values(), () -> panose[2]).get();
    }

    public PanoseProportion getPanoseProportion() {
        return safeEnum(PanoseProportion.values(), () -> panose[3]).get();
    }

    public PanoseContrast getPanoseContrast() {
        return safeEnum(PanoseContrast.values(), () -> panose[4]).get();
    }

    public PanoseStroke getPanoseStroke() {
        return safeEnum(PanoseStroke.values(), () -> panose[5]).get();
    }

    public PanoseArmStyle getPanoseArmStyle() {
        return safeEnum(PanoseArmStyle.values(), () -> panose[6]).get();
    }

    public PanoseLetterForm getPanoseLetterForm() {
        return safeEnum(PanoseLetterForm.values(), () -> panose[7]).get();
    }

    public PanoseMidLine getPanoseMidLine() {
        return safeEnum(PanoseMidLine.values(), () -> panose[8]).get();
    }

    public PanoseXHeight getPanoseXHeight() {
        return safeEnum(PanoseXHeight.values(), () -> panose[9]).get();
    }
}
