
/* ====================================================================
   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.hssf.record.cf;

import java.util.Locale;

import org.apache.poi.hssf.record.RecordInputStream;
import org.apache.poi.util.BitField;
import org.apache.poi.util.BitFieldFactory;
import org.apache.poi.util.LittleEndian;

/**
 * Font Formatting Block of the Conditional Formatting Rule Record.
 */
public final class FontFormatting implements Cloneable {
    private final byte[] _rawData = new byte[RAW_DATA_SIZE];

    private static final int OFFSET_FONT_NAME = 0;
    private static final int OFFSET_FONT_HEIGHT = 64;
    private static final int OFFSET_FONT_OPTIONS = 68;
    private static final int OFFSET_FONT_WEIGHT = 72;
    private static final int OFFSET_ESCAPEMENT_TYPE = 74;
    private static final int OFFSET_UNDERLINE_TYPE = 76;
    private static final int OFFSET_FONT_COLOR_INDEX = 80;
    private static final int OFFSET_OPTION_FLAGS = 88;
    private static final int OFFSET_ESCAPEMENT_TYPE_MODIFIED = 92;
    private static final int OFFSET_UNDERLINE_TYPE_MODIFIED = 96;
    private static final int OFFSET_FONT_WEIGHT_MODIFIED = 100;
    private static final int OFFSET_NOT_USED1 = 104;
    private static final int OFFSET_NOT_USED2 = 108;
    private static final int OFFSET_NOT_USED3 = 112; // for some reason Excel always writes  0x7FFFFFFF at this offset
    private static final int OFFSET_FONT_FORMATING_END = 116;
    private static final int RAW_DATA_SIZE = 118;


    public final static int  FONT_CELL_HEIGHT_PRESERVED   = 0xFFFFFFFF;

    // FONT OPTIONS MASKS
    private static final BitField posture       = BitFieldFactory.getInstance(0x00000002);
    private static final BitField outline       = BitFieldFactory.getInstance(0x00000008);
    private static final BitField shadow        = BitFieldFactory.getInstance(0x00000010);
    private static final BitField cancellation	= BitFieldFactory.getInstance(0x00000080);

    // OPTION FLAGS MASKS

    private static final BitField styleModified        = BitFieldFactory.getInstance(0x00000002);
    private static final BitField outlineModified      = BitFieldFactory.getInstance(0x00000008);
    private static final BitField shadowModified       = BitFieldFactory.getInstance(0x00000010);
    private static final BitField cancellationModified = BitFieldFactory.getInstance(0x00000080);

    /** Escapement type - None */
    public static final short SS_NONE  = 0;
    /** Escapement type - Superscript */
    public static final short SS_SUPER = 1;
    /** Escapement type - Subscript */
    public static final short SS_SUB   = 2;
    /** Underline type - None */
    public static final byte U_NONE               = 0;
    /** Underline type - Single */
    public static final byte U_SINGLE             = 1;
    /** Underline type - Double */
    public static final byte U_DOUBLE             = 2;
    /** Underline type - Single Accounting */
    public static final byte U_SINGLE_ACCOUNTING  = 0x21;
    /** Underline type - Double Accounting */
    public static final byte U_DOUBLE_ACCOUNTING  = 0x22;
    /** Normal boldness (not bold) */
    private static final short FONT_WEIGHT_NORMAL = 0x190;

    /**
     * Bold boldness (bold)
     */
    private static final short FONT_WEIGHT_BOLD	 = 0x2bc;

    public FontFormatting() {
        setFontHeight(-1);
        setItalic(false);
        setFontWieghtModified(false);
        setOutline(false);
        setShadow(false);
        setStrikeout(false);
        setEscapementType((short)0);
        setUnderlineType((byte)0);
        setFontColorIndex((short)-1);

        setFontStyleModified(false);
        setFontOutlineModified(false);
        setFontShadowModified(false);
        setFontCancellationModified(false);

        setEscapementTypeModified(false);
        setUnderlineTypeModified(false);

        setShort(OFFSET_FONT_NAME, 0);
        setInt(OFFSET_NOT_USED1, 0x00000001);
        setInt(OFFSET_NOT_USED2, 0x00000000);
        setInt(OFFSET_NOT_USED3, 0x7FFFFFFF);// for some reason Excel always writes  0x7FFFFFFF at this offset
        setShort(OFFSET_FONT_FORMATING_END, 0x0001);
    }

    /** Creates new FontFormatting */
    public FontFormatting(RecordInputStream in) {
        for (int i = 0; i < _rawData.length; i++) {
            _rawData[i] = in.readByte();
        }
    }

    private short getShort(int offset) {
        return LittleEndian.getShort( _rawData, offset);
    }
    private void setShort(int offset, int value) {
        LittleEndian.putShort( _rawData, offset, (short)value);
    }
    private int getInt(int offset) {
        return LittleEndian.getInt( _rawData, offset);
    }
    private void setInt(int offset, int value) {
        LittleEndian.putInt( _rawData, offset, value);
    }

    public byte[] getRawRecord()
    {
        return _rawData;
    }

    public int getDataLength() {
        return RAW_DATA_SIZE;
    }

    /**
     * sets the height of the font in 1/20th point units
     *
     *
     * @param height  fontheight (in points/20); or -1 to preserve the cell font height
     */

    public void setFontHeight(int height)
    {
        setInt(OFFSET_FONT_HEIGHT, height);
    }

    /**
     * gets the height of the font in 1/20th point units
     *
     * @return fontheight (in points/20); or -1 if not modified
     */
    public int getFontHeight()
    {
        return getInt(OFFSET_FONT_HEIGHT);
    }

    private void setFontOption(boolean option, BitField field)
    {
        int options = getInt(OFFSET_FONT_OPTIONS);
        options = field.setBoolean(options, option);
        setInt(OFFSET_FONT_OPTIONS, options);
    }

    private boolean getFontOption(BitField field)
    {
        int options = getInt(OFFSET_FONT_OPTIONS);
        return field.isSet(options);
    }

    /**
     * set the font to be italics or not
     *
     * @param italic - whether the font is italics or not
     * @see #setFontOption(boolean, org.apache.poi.util.BitField)
     */

    public void setItalic(boolean italic)
    {
        setFontOption(italic, posture);
    }

    /**
     * get whether the font is to be italics or not
     *
     * @return italics - whether the font is italics or not
     * @see #getFontOption(org.apache.poi.util.BitField)
     */

    public boolean isItalic()
    {
        return getFontOption(posture);
    }

    public void setOutline(boolean on)
    {
        setFontOption(on, outline);
    }

    public boolean isOutlineOn()
    {
        return getFontOption(outline);
    }

    public void setShadow(boolean on)
    {
        setFontOption(on, shadow);
    }

    public boolean isShadowOn()
    {
        return getFontOption(shadow);
    }

    /**
     * set the font to be stricken out or not
     *
     * @param strike - whether the font is stricken out or not
     */
    public void setStrikeout(boolean strike)
    {
        setFontOption(strike, cancellation);
    }

    /**
     * get whether the font is to be stricken out or not
     *
     * @return strike - whether the font is stricken out or not
     * @see #getFontOption(org.apache.poi.util.BitField)
     */
    public boolean isStruckout()
    {
        return getFontOption(cancellation);
    }

    /**
     * set the font weight (100-1000dec or 0x64-0x3e8).  Default is
     * 0x190 for normal and 0x2bc for bold
     *
     * @param bw - a number between 100-1000 for the fonts "boldness"
     */

    private void setFontWeight(short pbw)
    {
        short bw = pbw;
        if( bw<100) { bw=100; }
        if( bw>1000){ bw=1000; }
        setShort(OFFSET_FONT_WEIGHT, bw);
    }

    /**
     * set the font weight to bold (weight=700) or to normal(weight=400) boldness.
     *
     * @param bold - set font weight to bold if true; to normal otherwise
     */
    public void setBold(boolean bold)
    {
        setFontWeight(bold?FONT_WEIGHT_BOLD:FONT_WEIGHT_NORMAL);
    }

    /**
     * get the font weight for this font (100-1000dec or 0x64-0x3e8).  Default is
     * 0x190 for normal and 0x2bc for bold
     *
     * @return bw - a number between 100-1000 for the fonts "boldness"
     */

    public short getFontWeight()
    {
        return getShort(OFFSET_FONT_WEIGHT);
    }

    /**
     * get whether the font weight is set to bold or not
     *
     * @return bold - whether the font is bold or not
     */

    public boolean isBold()
    {
        return getFontWeight()==FONT_WEIGHT_BOLD;
    }

    /**
     * get the type of super or subscript for the font
     *
     * @return super or subscript option
     * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#SS_NONE
     * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#SS_SUPER
     * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#SS_SUB
     */
    public short getEscapementType()
    {
        return getShort(OFFSET_ESCAPEMENT_TYPE);
    }

    /**
     * set the escapement type for the font
     *
     * @param escapementType  super or subscript option
     * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#SS_NONE
     * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#SS_SUPER
     * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#SS_SUB
     */
    public void setEscapementType( short escapementType)
    {
        setShort(OFFSET_ESCAPEMENT_TYPE, escapementType);
    }

    /**
     * get the type of underlining for the font
     *
     * @return font underlining type
     *
     * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_NONE
     * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_SINGLE
     * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_DOUBLE
     * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_SINGLE_ACCOUNTING
     * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_DOUBLE_ACCOUNTING
     */
    public short getUnderlineType()
    {
        return getShort(OFFSET_UNDERLINE_TYPE);
    }

    /**
     * set the type of underlining type for the font
     *
     * @param underlineType underline option
     *
     * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_NONE
     * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_SINGLE
     * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_DOUBLE
     * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_SINGLE_ACCOUNTING
     * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_DOUBLE_ACCOUNTING
     */
    public void setUnderlineType( short underlineType)
    {
        setShort(OFFSET_UNDERLINE_TYPE, underlineType);
    }


    public short getFontColorIndex()
    {
        return (short)getInt(OFFSET_FONT_COLOR_INDEX);
    }

    public void setFontColorIndex(short fci )
    {
        setInt(OFFSET_FONT_COLOR_INDEX,fci);
    }

    private boolean getOptionFlag(BitField field) {
        int optionFlags = getInt(OFFSET_OPTION_FLAGS);
        int value = field.getValue(optionFlags);
        return value==0? true : false ;
    }

    private void setOptionFlag(boolean modified, BitField field)
    {
        int value = modified? 0 : 1;
        int optionFlags = getInt(OFFSET_OPTION_FLAGS);
        optionFlags = field.setValue(optionFlags, value);
        setInt(OFFSET_OPTION_FLAGS, optionFlags);
    }


    public boolean isFontStyleModified()
    {
        return getOptionFlag(styleModified);
    }


    public void setFontStyleModified(boolean modified)
    {
        setOptionFlag(modified, styleModified);
    }

    public boolean isFontOutlineModified()
    {
        return getOptionFlag(outlineModified);
    }

    public void setFontOutlineModified(boolean modified)
    {
        setOptionFlag(modified, outlineModified);
    }

    public boolean isFontShadowModified()
    {
        return getOptionFlag(shadowModified);
    }

    public void setFontShadowModified(boolean modified)
    {
        setOptionFlag(modified, shadowModified);
    }
    public void setFontCancellationModified(boolean modified)
    {
        setOptionFlag(modified, cancellationModified);
    }

    public boolean isFontCancellationModified()
    {
        return getOptionFlag(cancellationModified);
    }

    public void setEscapementTypeModified(boolean modified)
    {
        int value = modified? 0 : 1;
        setInt(OFFSET_ESCAPEMENT_TYPE_MODIFIED, value);
    }
    public boolean isEscapementTypeModified()
    {
        int escapementModified = getInt(OFFSET_ESCAPEMENT_TYPE_MODIFIED);
        return escapementModified == 0;
    }

    public void setUnderlineTypeModified(boolean modified)
    {
        int value = modified? 0 : 1;
        setInt(OFFSET_UNDERLINE_TYPE_MODIFIED, value);
    }

    public boolean isUnderlineTypeModified()
    {
        int underlineModified = getInt(OFFSET_UNDERLINE_TYPE_MODIFIED);
        return underlineModified == 0;
    }

    public void setFontWieghtModified(boolean modified)
    {
        int value = modified? 0 : 1;
        setInt(OFFSET_FONT_WEIGHT_MODIFIED, value);
    }

    public boolean isFontWeightModified()
    {
        int fontStyleModified = getInt(OFFSET_FONT_WEIGHT_MODIFIED);
        return fontStyleModified == 0;
    }

    public String toString()
    {
        StringBuffer buffer = new StringBuffer();
        buffer.append("    [Font Formatting]\n");

        buffer.append("	.font height = ").append(getFontHeight()).append(" twips\n");

        if( isFontStyleModified() )
        {
            buffer.append("	.font posture = ").append(isItalic()?"Italic":"Normal").append("\n");
        }
        else
        {
            buffer.append("	.font posture = ]not modified]").append("\n");
        }

        if( isFontOutlineModified() )
        {
            buffer.append("	.font outline = ").append(isOutlineOn()).append("\n");
        }
        else
        {
            buffer.append("	.font outline is not modified\n");
        }

        if( isFontShadowModified() )
        {
            buffer.append("	.font shadow = ").append(isShadowOn()).append("\n");
        }
        else
        {
            buffer.append("	.font shadow is not modified\n");
        }

        if( isFontCancellationModified() )
        {
            buffer.append("	.font strikeout = ").append(isStruckout()).append("\n");
        }
        else
        {
            buffer.append("	.font strikeout is not modified\n");
        }

        if( isFontStyleModified() )
        {
            buffer.append("	.font weight = ").
            append(getFontWeight()).
            append(
                    getFontWeight() == FONT_WEIGHT_NORMAL ? "(Normal)"
                    : getFontWeight() == FONT_WEIGHT_BOLD ? "(Bold)" 
                    : "0x"+Integer.toHexString(getFontWeight())).
            append("\n");
        }
        else
        {
            buffer.append("	.font weight = ]not modified]").append("\n");
        }

        if( isEscapementTypeModified() )
        {
            buffer.append("	.escapement type = ").append(getEscapementType()).append("\n");
        }
        else
        {
            buffer.append("	.escapement type is not modified\n");
        }

        if( isUnderlineTypeModified() )
        {
            buffer.append("	.underline type = ").append(getUnderlineType()).append("\n");
        }
        else
        {
            buffer.append("	.underline type is not modified\n");
        }
        buffer.append("	.color index = ").append("0x"+Integer.toHexString(getFontColorIndex()).toUpperCase(Locale.ROOT)).append("\n");

        buffer.append("    [/Font Formatting]\n");
        return buffer.toString();
    }

    @Override
    public FontFormatting clone() {
        FontFormatting other = new FontFormatting();
        System.arraycopy(_rawData, 0, other._rawData, 0, _rawData.length);
        return other;
    }
}
