/* ====================================================================
   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.hemf.record.emfplus;

import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;

import org.apache.poi.common.usermodel.fonts.FontHeader;
import org.apache.poi.hemf.draw.HemfDrawProperties;
import org.apache.poi.hemf.draw.HemfGraphics;
import org.apache.poi.hemf.record.emf.HemfFont;
import org.apache.poi.hemf.record.emfplus.HemfPlusDraw.EmfPlusUnitType;
import org.apache.poi.hemf.record.emfplus.HemfPlusHeader.EmfPlusGraphicsVersion;
import org.apache.poi.hemf.record.emfplus.HemfPlusObject.EmfPlusObjectData;
import org.apache.poi.hemf.record.emfplus.HemfPlusObject.EmfPlusObjectType;
import org.apache.poi.util.BitField;
import org.apache.poi.util.BitFieldFactory;
import org.apache.poi.util.GenericRecordJsonWriter;
import org.apache.poi.util.GenericRecordUtil;
import org.apache.poi.util.LittleEndianConsts;
import org.apache.poi.util.LittleEndianInputStream;
import org.apache.poi.util.StringUtil;

public class HemfPlusFont {


    public static class EmfPlusFont implements EmfPlusObjectData {
        /**
         * If set, the font typeface MUST be rendered with a heavier weight or thickness.
         * If clear, the font typeface MUST be rendered with a normal thickness.
         */
        private static final BitField BOLD = BitFieldFactory.getInstance(0x00000001);

        /**
         * If set, the font typeface MUST be rendered with the vertical stems of the characters at an increased angle
         * or slant relative to the baseline.
         *
         * If clear, the font typeface MUST be rendered with the vertical stems of the characters at a normal angle.
         */
        private static final BitField ITALIC = BitFieldFactory.getInstance(0x00000002);

        /**
         * If set, the font typeface MUST be rendered with a line underneath the baseline of the characters.
         * If clear, the font typeface MUST be rendered without a line underneath the baseline.
         */
        private static final BitField UNDERLINE = BitFieldFactory.getInstance(0x00000004);

        /**
         * If set, the font typeface MUST be rendered with a line parallel to the baseline drawn through the middle of
         * the characters.
         * If clear, the font typeface MUST be rendered without a line through the characters.
         */
        private static final BitField STRIKEOUT = BitFieldFactory.getInstance(0x00000008);


        private final EmfPlusGraphicsVersion graphicsVersion = new EmfPlusGraphicsVersion();
        private double emSize;
        private EmfPlusUnitType sizeUnit;
        private int styleFlags;
        private String family;

        @Override
        public long init(LittleEndianInputStream leis, long dataSize, EmfPlusObjectType objectType, int flags) throws IOException {
            // An EmfPlusGraphicsVersion object that specifies the version of operating system graphics that was used
            // to create this object.
            long size = graphicsVersion.init(leis);

            // A 32-bit floating-point value that specifies the em size of the font in units specified by the SizeUnit field.
            emSize = leis.readFloat();

            // A 32-bit unsigned integer that specifies the units used for the EmSize field. These are typically the
            // units that were employed when designing the font. The value MUST be in the UnitType enumeration
            sizeUnit = EmfPlusUnitType.valueOf(leis.readInt());

            // A 32-bit signed integer that specifies attributes of the character glyphs that affect the appearance of
            // the font, such as bold and italic. This value MUST be composed of FontStyle flags
            styleFlags = leis.readInt();

            // A 32-bit unsigned integer that is reserved and MUST be ignored.
            leis.skipFully(LittleEndianConsts.INT_SIZE);

            // A 32-bit unsigned integer that specifies the number of characters in the FamilyName field.
            int len = leis.readInt();
            size += 5*LittleEndianConsts.INT_SIZE;

            // A string of Length Unicode characters that contains the name of the font family.
            family = StringUtil.readUnicodeLE(leis, len);
            size += len*LittleEndianConsts.SHORT_SIZE;

            return size;
        }

        @Override
        public void applyObject(HemfGraphics ctx, List<? extends EmfPlusObjectData> continuedObjectData) {
            HemfDrawProperties prop = ctx.getProperties();
            HemfFont font = new HemfFont();
            font.initDefaults();
            font.setTypeface(family);
            // TODO: check how to calculate the font size
            font.setHeight(emSize);
            font.setStrikeOut(STRIKEOUT.isSet(styleFlags));
            font.setUnderline(UNDERLINE.isSet(styleFlags));
            font.setWeight(BOLD.isSet(styleFlags) ? 700 : FontHeader.REGULAR_WEIGHT);
            font.setItalic(ITALIC.isSet(styleFlags));
            prop.setFont(font);
        }

        @Override
        public EmfPlusGraphicsVersion getGraphicsVersion() {
            return graphicsVersion;
        }

        @Override
        public String toString() {
            return GenericRecordJsonWriter.marshal(this);
        }

        @Override
        public Map<String, Supplier<?>> getGenericProperties() {
            return GenericRecordUtil.getGenericProperties(
                "graphicsVersion", () -> graphicsVersion,
                "emSize", () -> emSize,
                "sizeUnit", () -> sizeUnit,
                "styleFlags", () -> styleFlags,
                "family", () -> family
            );
        }

        @Override
        public EmfPlusObjectType getGenericRecordType() {
            return EmfPlusObjectType.FONT;
        }
    }
}
