/* ====================================================================
   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.xssf.usermodel;

import java.util.Objects;

import org.apache.poi.common.usermodel.fonts.FontCharset;
import org.apache.poi.ooxml.POIXMLException;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.FontFamily;
import org.apache.poi.ss.usermodel.FontScheme;
import org.apache.poi.ss.usermodel.FontUnderline;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.util.Internal;
import org.apache.poi.util.Removal;
import org.apache.poi.xssf.model.StylesTable;
import org.apache.poi.xssf.model.ThemesTable;
import org.openxmlformats.schemas.officeDocument.x2006.sharedTypes.STVerticalAlignRun;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBooleanProperty;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTColor;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFont;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFontFamily;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFontName;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFontScheme;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFontSize;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTIntProperty;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTUnderlineProperty;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTVerticalAlignFontProperty;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STFontScheme;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STUnderlineValues;

/**
 * Represents a font used in a workbook.
 *
 * @author Gisella Bronzetti
 */
public class XSSFFont implements Font {

    /**
     * By default, Microsoft Office Excel 2007 uses the Calibri font in font size 11
     */
    public static final String DEFAULT_FONT_NAME = "Calibri";
    /**
     * By default, Microsoft Office Excel 2007 uses the Calibri font in font size 11
     */
    public static final short DEFAULT_FONT_SIZE = 11;
    /**
     * Default font color is black
     * @see org.apache.poi.ss.usermodel.IndexedColors#BLACK
     */
    public static final short DEFAULT_FONT_COLOR = IndexedColors.BLACK.getIndex();

    private IndexedColorMap _indexedColorMap;
    private ThemesTable _themes;
    private CTFont _ctFont;
    private int _index;

    /**
     * Create a new XSSFFont
     *
     * @param font the underlying CTFont bean
     */
    @Internal
    public XSSFFont(CTFont font) {
        _ctFont = font;
        _index = 0;
    }

    /**
     * Called from parsing styles.xml
     * @param font CTFont
     * @param index font index
     * @param colorMap for default or custom indexed colors
     */
    @Internal
    public XSSFFont(CTFont font, int index, IndexedColorMap colorMap) {
        _ctFont = font;
        _index = (short)index;
        _indexedColorMap = colorMap;
    }

    /**
     * Create a new XSSFont. This method is protected to be used only by XSSFWorkbook
     */
    public XSSFFont() {
        this._ctFont = CTFont.Factory.newInstance();
        setFontName(DEFAULT_FONT_NAME);
        setFontHeight((double)DEFAULT_FONT_SIZE);
    }

    /**
     * get the underlying CTFont font
     */
    @Internal
    public CTFont getCTFont() {
        return _ctFont;
    }

    /**
     * get a boolean value for the boldness to use.
     *
     * @return boolean - bold
     */
    public boolean getBold() {
        CTBooleanProperty bold = _ctFont.sizeOfBArray() == 0 ? null : _ctFont.getBArray(0);
        return (bold != null && bold.getVal());
    }

    /**
     * get character-set to use.
     *
     * @return int - character-set (0-255)
     * @see FontCharset
     */
    public int getCharSet() {
        CTIntProperty charset = _ctFont.sizeOfCharsetArray() == 0 ? null : _ctFont.getCharsetArray(0);
        return charset == null ? FontCharset.ANSI.getNativeId() : FontCharset.valueOf(charset.getVal()).getNativeId();
    }


    /**
     * get the indexed color value for the font
     * References a color defined in IndexedColors.
     *
     * @return short - indexed color to use
     * @see IndexedColors
     */
    public short getColor() {
        CTColor color = _ctFont.sizeOfColorArray() == 0 ? null : _ctFont.getColorArray(0);
        if (color == null) return IndexedColors.BLACK.getIndex();

        long index = color.getIndexed();
        if (index == XSSFFont.DEFAULT_FONT_COLOR) {
            return IndexedColors.BLACK.getIndex();
        } else if (index == IndexedColors.RED.getIndex()) {
            return IndexedColors.RED.getIndex();
        } else {
            return (short)index;
        }
    }


    /**
     * get the color value for the font
     * References a color defined as  Standard Alpha Red Green Blue color value (ARGB).
     *
     * @return XSSFColor - rgb color to use
     */
    public XSSFColor getXSSFColor() {
        CTColor ctColor = _ctFont.sizeOfColorArray() == 0 ? null : _ctFont.getColorArray(0);
        if(ctColor != null) {
           XSSFColor color = XSSFColor.from(ctColor, _indexedColorMap);
           if(_themes != null) {
              _themes.inheritFromThemeAsRequired(color);
           }
           return color;
        } else {
           return null;
        }
    }


    /**
     * get the color value for the font
     * References a color defined in theme.
     *
     * @return short - theme defined to use
     */
    public short getThemeColor() {
        CTColor color = _ctFont.sizeOfColorArray() == 0 ? null : _ctFont.getColorArray(0);
        long index = color == null ? 0 : color.getTheme();
        return (short) index;
    }

    /**
     * Get the font height in unit's of 1/20th of a point.
     * <p>
     * For many users, the related {@link #getFontHeightInPoints()}
     *  will be more helpful, as that returns font heights in the
     *  more familiar points units, eg 10, 12, 14.

     * @return short - height in 1/20ths of a point
     * @see #getFontHeightInPoints()
     */
    public short getFontHeight() {
        return (short)(getFontHeightRaw()*Font.TWIPS_PER_POINT);
    }

    /**
     * Get the font height in points.
     * <p>
     * This will return the same font height that is shown in Excel,
     *  such as 10 or 14 or 28.
     * @return short - height in the familiar unit of measure - points
     * @see #getFontHeight()
     */
    public short getFontHeightInPoints() {
        return (short)getFontHeightRaw();
    }

    /**
     * Return the raw font height, in points, but also
     *  including fractions.
     */
    private double getFontHeightRaw() {
        CTFontSize size = _ctFont.sizeOfSzArray() == 0 ? null : _ctFont.getSzArray(0);
        if (size != null) {
            return size.getVal();
        }
        return DEFAULT_FONT_SIZE;
    }

    /**
     * get the name of the font (i.e. Arial)
     *
     * @return String - a string representing the name of the font to use
     */
    public String getFontName() {
        CTFontName name = _ctFont.sizeOfNameArray() == 0 ? null : _ctFont.getNameArray(0);
        return name == null ? DEFAULT_FONT_NAME : name.getVal();
    }

    /**
     * get a boolean value that specify whether to use italics or not
     *
     * @return boolean - value for italic
     */
    public boolean getItalic() {
        CTBooleanProperty italic = _ctFont.sizeOfIArray() == 0 ? null : _ctFont.getIArray(0);
        return italic != null && italic.getVal();
    }

    /**
     * get a boolean value that specify whether to use a strikeout horizontal line through the text or not
     *
     * @return boolean - value for strikeout
     */
    public boolean getStrikeout() {
        CTBooleanProperty strike = _ctFont.sizeOfStrikeArray() == 0 ? null : _ctFont.getStrikeArray(0);
        return strike != null && strike.getVal();
    }

    /**
     * get normal,super or subscript.
     *
     * @return short - offset type to use (none,super,sub)
     * @see Font#SS_NONE
     * @see Font#SS_SUPER
     * @see Font#SS_SUB
     */
    public short getTypeOffset() {
        CTVerticalAlignFontProperty vAlign = _ctFont.sizeOfVertAlignArray() == 0 ? null : _ctFont.getVertAlignArray(0);
        if (vAlign == null) {
            return Font.SS_NONE;
        }
        int val = vAlign.getVal().intValue();
        switch (val) {
            case STVerticalAlignRun.INT_BASELINE:
                return Font.SS_NONE;
            case STVerticalAlignRun.INT_SUBSCRIPT:
                return Font.SS_SUB;
            case STVerticalAlignRun.INT_SUPERSCRIPT:
                return Font.SS_SUPER;
            default:
                throw new POIXMLException("Wrong offset value " + val);
        }
    }

    /**
     * get type of text underlining to use
     *
     * @return byte - underlining type
     * @see org.apache.poi.ss.usermodel.FontUnderline
     */
    public byte getUnderline() {
        CTUnderlineProperty underline = _ctFont.sizeOfUArray() == 0 ? null : _ctFont.getUArray(0);
        if (underline != null) {
            FontUnderline val = FontUnderline.valueOf(underline.getVal().intValue());
            return val.getByteValue();
        }
        return Font.U_NONE;
    }

    /**
     * set a boolean value for the boldness to use. If omitted, the default value is true.
     *
     * @param bold - boldness to use
     */
    public void setBold(boolean bold) {
        if(bold){
            CTBooleanProperty ctBold = _ctFont.sizeOfBArray() == 0 ? _ctFont.addNewB() : _ctFont.getBArray(0);
            ctBold.setVal(true);
        } else {
            _ctFont.setBArray(null);
        }
    }

    /**
     * set character-set to use.
     *
     * @param charset - charset
     * @see FontCharset
     */
    public void setCharSet(byte charset) {
       int cs = charset & 0xff;
       setCharSet(cs);
    }

    /**
     * set character-set to use.
     *
     * @param charset - charset
     * @see FontCharset
     */
    public void setCharSet(int charset) {
        FontCharset fontCharset = FontCharset.valueOf(charset);
        if(fontCharset != null) {
           setCharSet(fontCharset);
        } else {
           throw new POIXMLException("Attention: an attempt to set a type of unknown charset and charset");
        }
    }

    /**
     * set character-set to use.
     *
     * @param charSet
     * @deprecated use {@link #setCharSet(FontCharset)} instead
     */
    @Deprecated
    @Removal(version = "6.0.0")
    public void setCharSet(org.apache.poi.ss.usermodel.FontCharset charSet) {
       CTIntProperty charsetProperty;
       if(_ctFont.sizeOfCharsetArray() == 0) {
          charsetProperty = _ctFont.addNewCharset();
       } else {
          charsetProperty = _ctFont.getCharsetArray(0);
       }
       // We know that FontCharset only has valid entries in it,
       //  so we can just set the int value from it
       charsetProperty.setVal( charSet.getValue() );
    }

    /**
     * set character-set to use.
     *
     * @param charSet
     * @since 5.0.0
     */
    public void setCharSet(FontCharset charSet) {
        CTIntProperty charsetProperty;
        if(_ctFont.sizeOfCharsetArray() == 0) {
            charsetProperty = _ctFont.addNewCharset();
        } else {
            charsetProperty = _ctFont.getCharsetArray(0);
        }
        // We know that FontCharset only has valid entries in it,
        //  so we can just set the int value from it
        charsetProperty.setVal( charSet.getNativeId() );
    }

    /**
     * set the indexed color for the font
     *
     * @param color - color to use
     * @see #DEFAULT_FONT_COLOR - Note: default font color
     * @see IndexedColors
     */
    public void setColor(short color) {
        CTColor ctColor = _ctFont.sizeOfColorArray() == 0 ? _ctFont.addNewColor() : _ctFont.getColorArray(0);
        switch (color) {
            case Font.COLOR_NORMAL: {
                ctColor.setIndexed(XSSFFont.DEFAULT_FONT_COLOR);
                break;
            }
            case Font.COLOR_RED: {
                ctColor.setIndexed(IndexedColors.RED.getIndex());
                break;
            }
            default:
                ctColor.setIndexed(color);
        }
    }

    /**
     * set the color for the font in Standard Alpha Red Green Blue color value
     *
     * @param color - color to use
     */
    public void setColor(XSSFColor color) {
        if(color == null) _ctFont.setColorArray(null);
        else {
            CTColor ctColor = _ctFont.sizeOfColorArray() == 0 ? _ctFont.addNewColor() : _ctFont.getColorArray(0);
            if (ctColor.isSetIndexed()) {
                ctColor.unsetIndexed();
            }
            ctColor.setRgb(color.getRGB());
        }
    }

    /**
     * set the font height in points.
     *
     * @param height - height in points
     */
    public void setFontHeight(short height) {
        setFontHeight((double) height/Font.TWIPS_PER_POINT);
    }

    /**
     * set the font height in points.
     *
     * @param height - height in points
     */
    public void setFontHeight(double height) {
        CTFontSize fontSize = _ctFont.sizeOfSzArray() == 0 ? _ctFont.addNewSz() : _ctFont.getSzArray(0);
        fontSize.setVal(height);
    }

    /**
     * set the font height in points.
     *
     * @see #setFontHeight
     */
    public void setFontHeightInPoints(short height) {
        setFontHeight((double)height);
    }

    /**
     * set the theme color for the font to use
     *
     * @param theme - theme color to use
     */
    public void setThemeColor(short theme) {
        CTColor ctColor = _ctFont.sizeOfColorArray() == 0 ? _ctFont.addNewColor() : _ctFont.getColorArray(0);
        ctColor.setTheme(theme);
    }

    /**
     * set the name for the font (i.e. Arial).
     * If the font doesn't exist (because it isn't installed on the system),
     * or the charset is invalid for that font, then another font should
     * be substituted.
     * The string length for this attribute shall be 0 to 31 characters.
     * Default font name is Calibri.
     *
     * @param name - value representing the name of the font to use
     * @see #DEFAULT_FONT_NAME
     */
    public void setFontName(String name) {
        CTFontName fontName = _ctFont.sizeOfNameArray() == 0 ? _ctFont.addNewName() : _ctFont.getNameArray(0);
        fontName.setVal(name == null ? DEFAULT_FONT_NAME : name);
    }


    /**
     * set a boolean value for the property specifying whether to use italics or not
     * If omitted, the default value is true.
     *
     * @param italic - value for italics or not
     */
    public void setItalic(boolean italic) {
        if(italic){
            CTBooleanProperty bool = _ctFont.sizeOfIArray() == 0 ? _ctFont.addNewI() : _ctFont.getIArray(0);
            bool.setVal(true);
        } else {
            _ctFont.setIArray(null);
        }
    }


    /**
     * set a boolean value for the property specifying whether to use a strikeout horizontal line through the text or not
     * If omitted, the default value is true.
     *
     * @param strikeout - value for strikeout or not
     */
    public void setStrikeout(boolean strikeout) {
        if(strikeout) {
            CTBooleanProperty strike = _ctFont.sizeOfStrikeArray() == 0 ? _ctFont.addNewStrike() : _ctFont.getStrikeArray(0);
            strike.setVal(true);
        } else {
            _ctFont.setStrikeArray(null);
        }
    }

    /**
     * set normal,super or subscript, that representing the vertical-alignment setting.
     * Setting this to either subscript or superscript shall make the font size smaller if a
     * smaller font size is available.
     *
     * @param offset - offset type to use (none,super,sub)
     * @see #SS_NONE
     * @see #SS_SUPER
     * @see #SS_SUB
     */
    public void setTypeOffset(short offset) {
        if(offset == Font.SS_NONE){
            _ctFont.setVertAlignArray(null);
        } else {
            CTVerticalAlignFontProperty offsetProperty = _ctFont.sizeOfVertAlignArray() == 0 ? _ctFont.addNewVertAlign() : _ctFont.getVertAlignArray(0);
            switch (offset) {
                case Font.SS_NONE:
                    offsetProperty.setVal(STVerticalAlignRun.BASELINE);
                    break;
                case Font.SS_SUB:
                    offsetProperty.setVal(STVerticalAlignRun.SUBSCRIPT);
                    break;
                case Font.SS_SUPER:
                    offsetProperty.setVal(STVerticalAlignRun.SUPERSCRIPT);
                    break;
                default:
                    throw new IllegalStateException("Invalid type offset: " + offset);
            }
        }
    }

    /**
     * set the style of underlining that is used.
     * The none style is equivalent to not using underlining at all.
     *
     * @param underline - underline type to use
     * @see FontUnderline
     */
    public void setUnderline(byte underline) {
        setUnderline(FontUnderline.valueOf(underline));
    }

    /**
     * set an enumeration representing the style of underlining that is used.
     * The none style is equivalent to not using underlining at all.
     * The possible values for this attribute are defined by the FontUnderline
     *
     * @param underline - FontUnderline enum value
     */
    public void setUnderline(FontUnderline underline) {
        if(underline == FontUnderline.NONE && _ctFont.sizeOfUArray() > 0){
            _ctFont.setUArray(null);
        } else {
            CTUnderlineProperty ctUnderline = _ctFont.sizeOfUArray() == 0 ? _ctFont.addNewU() : _ctFont.getUArray(0);
            STUnderlineValues.Enum val = STUnderlineValues.Enum.forInt(underline.getValue());
            ctUnderline.setVal(val);
        }
    }


    public String toString() {
        return _ctFont.toString();
    }


    /**
     * Perform a registration of ourselves
     *  to the style table
     */
    public long registerTo(StylesTable styles) {
        return registerTo(styles, true);
    }

    public long registerTo(StylesTable styles, boolean force) {
        this._themes = styles.getTheme();
        this._index = styles.putFont(this, force);
        return this._index;
    }


    /**
     * Records the Themes Table that is associated with
     *  the current font, used when looking up theme
     *  based colours and properties.
     */
    public void setThemesTable(ThemesTable themes) {
       this._themes = themes;
    }

    /**
     * get the font scheme property.
     * is used only in StylesTable to create the default instance of font
     *
     * @return FontScheme
     * @see org.apache.poi.xssf.model.StylesTable#createDefaultFont()
     */
    @SuppressWarnings("JavadocReference")
    public FontScheme getScheme() {
        CTFontScheme scheme = _ctFont.sizeOfSchemeArray() == 0 ? null : _ctFont.getSchemeArray(0);
        return scheme == null ? FontScheme.NONE : FontScheme.valueOf(scheme.getVal().intValue());
    }

    /**
     * set font scheme property
     *
     * @param scheme - FontScheme enum value
     * @see FontScheme
     */
    public void setScheme(FontScheme scheme) {
        CTFontScheme ctFontScheme = _ctFont.sizeOfSchemeArray() == 0 ? _ctFont.addNewScheme() : _ctFont.getSchemeArray(0);
        STFontScheme.Enum val = STFontScheme.Enum.forInt(scheme.getValue());
        ctFontScheme.setVal(val);
    }

    /**
     * get the font family to use.
     *
     * @return the font family to use
     * @see org.apache.poi.ss.usermodel.FontFamily
     */
    public int getFamily() {
        CTFontFamily family = _ctFont.sizeOfFamilyArray() == 0 ? null : _ctFont.getFamilyArray(0);
        return family == null ? FontFamily.NOT_APPLICABLE.getValue() : FontFamily.valueOf(family.getVal()).getValue();
    }

    /**
     * Set the font family this font belongs to.
     * A font family is a set of fonts having common stroke width and serif characteristics.
     * The font name overrides when there are conflicting values.
     *
     * @param value - font family
     * @see FontFamily
     */
    public void setFamily(int value) {
        CTFontFamily family = _ctFont.sizeOfFamilyArray() == 0 ? _ctFont.addNewFamily() : _ctFont.getFamilyArray(0);
        family.setVal(value);
    }

    /**
     * set an enumeration representing the font family this font belongs to.
     * A font family is a set of fonts having common stroke width and serif characteristics.
     *
     * @param family font family
     * @see #setFamily(int value)
     */
    public void setFamily(FontFamily family) {
        setFamily(family.getValue());
    }

    @Override
    public int getIndex() {
        return _index;
    }

    @Deprecated
    @Removal(version = "6.0.0")
    @Override
    public int getIndexAsInt()
    {
        return _index;
    }

    public int hashCode(){
        return _ctFont.toString().hashCode();
    }

    public boolean equals(Object o){
        if(!(o instanceof XSSFFont)) return false;

        XSSFFont cf = (XSSFFont)o;

        // BUG 60845
        return Objects.equals(this.getItalic(), cf.getItalic())
                        && Objects.equals(this.getBold(), cf.getBold())
                        && Objects.equals(this.getStrikeout(), cf.getStrikeout())
                        && Objects.equals(this.getCharSet(), cf.getCharSet())
                        && Objects.equals(this.getColor(), cf.getColor())
                        && Objects.equals(this.getFamily(), cf.getFamily())
                        && Objects.equals(this.getFontHeight(), cf.getFontHeight())
                        && Objects.equals(this.getFontName(), cf.getFontName())
                        && Objects.equals(this.getScheme(), cf.getScheme())
                        && Objects.equals(this.getThemeColor(), cf.getThemeColor())
                        && Objects.equals(this.getTypeOffset(), cf.getTypeOffset())
                        && Objects.equals(this.getUnderline(), cf.getUnderline())
                        && Objects.equals(this.getXSSFColor(), cf.getXSSFColor());
    }

}
