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

import java.awt.Color;
import java.util.List;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.poi.common.usermodel.fonts.FontGroup;
import org.apache.poi.common.usermodel.fonts.FontInfo;
import org.apache.poi.hslf.exceptions.HSLFException;
import org.apache.poi.hslf.model.textproperties.BitMaskTextProp;
import org.apache.poi.hslf.model.textproperties.CharFlagsTextProp;
import org.apache.poi.hslf.model.textproperties.TextProp;
import org.apache.poi.hslf.model.textproperties.TextPropCollection;
import org.apache.poi.hslf.model.textproperties.TextPropCollection.TextPropType;
import org.apache.poi.sl.draw.DrawPaint;
import org.apache.poi.sl.usermodel.MasterSheet;
import org.apache.poi.sl.usermodel.PaintStyle;
import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;
import org.apache.poi.sl.usermodel.Placeholder;
import org.apache.poi.sl.usermodel.TextParagraph;
import org.apache.poi.sl.usermodel.TextRun;
import org.apache.poi.sl.usermodel.TextShape;


/**
 * Represents a run of text, all with the same style
 *
 */
@SuppressWarnings({"WeakerAccess", "Duplicates", "unused"})
public final class HSLFTextRun implements TextRun {
	private static final Logger LOG = LogManager.getLogger(HSLFTextRun.class);

	/** The TextRun we belong to */
	private HSLFTextParagraph parentParagraph;
	private String _runText = "";
	/** Caches the font info objects until the text runs are attached to the container */
	private HSLFFontInfo[] cachedFontInfo;
	private HSLFHyperlink link;

	/**
	 * Our paragraph and character style.
	 * Note - we may share these styles with other RichTextRuns
	 */
	private TextPropCollection characterStyle = new TextPropCollection(1, TextPropType.character);

	/**
	 * Create a new wrapper around a rich text string
	 * @param parentParagraph the parent paragraph
	 */
	public HSLFTextRun(HSLFTextParagraph parentParagraph) {
		this.parentParagraph = parentParagraph;
	}

	public TextPropCollection getCharacterStyle() {
	    return characterStyle;
	}

	public void setCharacterStyle(TextPropCollection characterStyle) {
	    this.characterStyle = characterStyle.copy();
	    this.characterStyle.updateTextSize(_runText.length());
	}

	/**
	 * Supply the SlideShow we belong to
	 */
	public void updateSheet() {
		if (cachedFontInfo != null) {
		    for (FontGroup tt : FontGroup.values()) {
		        setFontInfo(cachedFontInfo[tt.ordinal()], tt);
		    }
		    cachedFontInfo = null;
		}
	}

	/**
	 * Get the length of the text
	 */
	public int getLength() {
		return _runText.length();
	}

	/**
	 * Fetch the text, in raw storage form
	 */
	@Override
    public String getRawText() {
		return _runText;
	}

	/**
	 * Change the text
	 */
	@Override
    public void setText(String text) {
	    if (text == null) {
	        throw new HSLFException("text must not be null");
	    }
	    String newText = HSLFTextParagraph.toInternalString(text);
	    if (!newText.equals(_runText)) {
	        _runText = newText;
	        if (HSLFSlideShow.getLoadSavePhase() == HSLFSlideShow.LoadSavePhase.LOADED) {
	            parentParagraph.setDirty();
	        }
	    }
	}

	// --------------- Internal helpers on rich text properties -------

	/**
	 * Fetch the value of the given flag in the CharFlagsTextProp.
	 * Returns false if the CharFlagsTextProp isn't present, since the
	 *  text property won't be set if there's no CharFlagsTextProp.
	 */
	private boolean isCharFlagsTextPropVal(int index) {
		return getFlag(index);
	}

	boolean getFlag(int index) {
		BitMaskTextProp prop = (characterStyle == null) ? null : characterStyle.findByName(CharFlagsTextProp.NAME);

		if (prop == null || !prop.getSubPropMatches()[index]) {
		    prop = getMasterProp();
		}

		return prop != null && prop.getSubValue(index);
	}

	private <T extends TextProp> T getMasterProp() {
        final int txtype = parentParagraph.getRunType();
        final HSLFSheet sheet = parentParagraph.getSheet();
        if (sheet == null) {
            LOG.atError().log("Sheet is not available");
            return null;
        }

        final HSLFMasterSheet master = sheet.getMasterSheet();
        if (master == null) {
            LOG.atWarn().log("MasterSheet is not available");
            return null;
        }

        String name = CharFlagsTextProp.NAME;
        final TextPropCollection col = master.getPropCollection(txtype, parentParagraph.getIndentLevel(), name, true);
        return (col == null) ? null : col.findByName(name);
	}


	/**
	 * Set the value of the given flag in the CharFlagsTextProp, adding
	 *  it if required.
	 */
	private void setCharFlagsTextPropVal(int index, boolean value) {
	    // TODO: check if paragraph/chars can be handled the same ...
		if (getFlag(index) != value) {
		    setFlag(index, value);
		    parentParagraph.setDirty();
		}
	}

	/**
	 * Sets the value of the given Paragraph TextProp, add if required
	 * @param propName The name of the Paragraph TextProp
	 * @param val The value to set for the TextProp
	 */
	public void setCharTextPropVal(String propName, Integer val) {
	    getTextParagraph().setPropVal(characterStyle, propName, val);
	}


	// --------------- Friendly getters / setters on rich text properties -------

	@Override
	public boolean isBold() {
		return isCharFlagsTextPropVal(CharFlagsTextProp.BOLD_IDX);
	}

	@Override
	public void setBold(boolean bold) {
		setCharFlagsTextPropVal(CharFlagsTextProp.BOLD_IDX, bold);
	}

	@Override
	public boolean isItalic() {
		return isCharFlagsTextPropVal(CharFlagsTextProp.ITALIC_IDX);
	}

	@Override
	public void setItalic(boolean italic) {
		setCharFlagsTextPropVal(CharFlagsTextProp.ITALIC_IDX, italic);
	}

	@Override
	public boolean isUnderlined() {
		return isCharFlagsTextPropVal(CharFlagsTextProp.UNDERLINE_IDX);
	}

	@Override
	public void setUnderlined(boolean underlined) {
		setCharFlagsTextPropVal(CharFlagsTextProp.UNDERLINE_IDX, underlined);
	}

	/**
	 * Does the text have a shadow?
	 */
	public boolean isShadowed() {
		return isCharFlagsTextPropVal(CharFlagsTextProp.SHADOW_IDX);
	}

	/**
	 * Does the text have a shadow?
	 */
	public void setShadowed(boolean flag) {
		setCharFlagsTextPropVal(CharFlagsTextProp.SHADOW_IDX, flag);
	}

	/**
	 * Is this text embossed?
	 */
	 public boolean isEmbossed() {
		return isCharFlagsTextPropVal(CharFlagsTextProp.RELIEF_IDX);
	}

	/**
	 * Is this text embossed?
	 */
	 public void setEmbossed(boolean flag) {
		setCharFlagsTextPropVal(CharFlagsTextProp.RELIEF_IDX, flag);
	}

	@Override
	public boolean isStrikethrough() {
		return isCharFlagsTextPropVal(CharFlagsTextProp.STRIKETHROUGH_IDX);
	}

	@Override
	public void setStrikethrough(boolean flag) {
		setCharFlagsTextPropVal(CharFlagsTextProp.STRIKETHROUGH_IDX, flag);
	}

	/**
	 * Gets the subscript/superscript option
	 *
	 * @return the percentage of the font size. If the value is positive, it is superscript, otherwise it is subscript
	 */
	public int getSuperscript() {
		TextProp tp = getTextParagraph().getPropVal(characterStyle, "superscript");
		return tp == null ? 0 : tp.getValue();
	}

	/**
	 * Sets the subscript/superscript option
	 *
	 * @param val the percentage of the font size. If the value is positive, it is superscript, otherwise it is subscript
	 */
	public void setSuperscript(int val) {
	    setCharTextPropVal("superscript", val);
	}

    @Override
	public Double getFontSize() {
        TextProp tp = getTextParagraph().getPropVal(characterStyle, "font.size");
        return tp == null ? null : (double)tp.getValue();
	}


	@Override
	public void setFontSize(Double fontSize) {
	    Integer iFontSize = (fontSize == null) ? null : fontSize.intValue();
		setCharTextPropVal("font.size", iFontSize);
	}

	/**
	 * Gets the font index
	 */
	public int getFontIndex() {
        TextProp tp = getTextParagraph().getPropVal(characterStyle, "font.index");
        return tp == null ? -1 : tp.getValue();
	}

	/**
	 * Sets the font index
	 */
	public void setFontIndex(int idx) {
		setCharTextPropVal("font.index", idx);
	}

	@Override
	public void setFontFamily(String typeface) {
		setFontFamily(typeface, FontGroup.LATIN);
	}

    @Override
    public void setFontFamily(String typeface, FontGroup fontGroup) {
        setFontInfo(new HSLFFontInfo(typeface), fontGroup);
    }

    @Override
	public void setFontInfo(FontInfo fontInfo, FontGroup fontGroup) {
        FontGroup fg = safeFontGroup(fontGroup);

        HSLFSheet sheet = parentParagraph.getSheet();
        @SuppressWarnings("resource")
        HSLFSlideShow slideShow = (sheet == null) ? null : sheet.getSlideShow();
        if (sheet == null || slideShow == null) {
            // we can't set font since slideshow is not assigned yet
            if (cachedFontInfo == null) {
                cachedFontInfo = new HSLFFontInfo[FontGroup.values().length];
            }
            cachedFontInfo[fg.ordinal()] = (fontInfo != null) ? new HSLFFontInfo(fontInfo) : null;
            return;
        }

        String propName;
        switch (fg) {
        default:
        case LATIN:
            propName = "ansi.font.index";
            break;
        case COMPLEX_SCRIPT:
            // TODO: implement TextCFException10 structure
        case EAST_ASIAN:
            propName = "asian.font.index";
            break;
        case SYMBOL:
            propName = "symbol.font.index";
            break;
        }


        // Get the index for this font, if it is not to be removed (typeface == null)
        Integer fontIdx = null;
        if (fontInfo != null) {
            fontIdx = slideShow.addFont(fontInfo).getIndex();
        }


		setCharTextPropVal("font.index", fontIdx);
        setCharTextPropVal(propName, fontIdx);
    }

    @Override
	public String getFontFamily() {
        return getFontFamily(null);
	}

    @Override
    public String getFontFamily(FontGroup fontGroup) {
        HSLFFontInfo fi = getFontInfo(fontGroup);
        return (fi != null) ? fi.getTypeface() : null;
    }

	@Override
	public HSLFFontInfo getFontInfo(final FontGroup fontGroup) {
        FontGroup fg = safeFontGroup(fontGroup);

	    HSLFSheet sheet = parentParagraph.getSheet();
        @SuppressWarnings("resource")
        HSLFSlideShow slideShow = (sheet == null) ? null : sheet.getSlideShow();
		if (sheet == null || slideShow == null) {
			return (cachedFontInfo != null) ? cachedFontInfo[fg.ordinal()] : null;
		}

		String propName;
	    switch (fg) {
	    default:
	    case LATIN:
	        propName = "font.index,ansi.font.index";
	        break;
        case COMPLEX_SCRIPT:
	    case EAST_ASIAN:
	        propName = "asian.font.index";
	        break;
        case SYMBOL:
	        propName = "symbol.font.index";
	        break;
		}

        TextProp tp = getTextParagraph().getPropVal(characterStyle, propName);
		return (tp != null) ? slideShow.getFont(tp.getValue()) : null;
	}

	/**
	 * @return font color as PaintStyle
	 */
	@Override
	public SolidPaint getFontColor() {
		TextProp tp = getTextParagraph().getPropVal(characterStyle, "font.color");
		if (tp == null) {
            return null;
        }
		Color color = HSLFTextParagraph.getColorFromColorIndexStruct(tp.getValue(), parentParagraph.getSheet());
        return DrawPaint.createSolidPaint(color);
	}

	/**
	 * Sets color of the text, as a int bgr.
	 * (PowerPoint stores as BlueGreenRed, not the more
	 *  usual RedGreenBlue)
	 * @see Color
	 */
	public void setFontColor(int bgr) {
		setCharTextPropVal("font.color", bgr);
	}


    @Override
    public void setFontColor(Color color) {
        setFontColor(DrawPaint.createSolidPaint(color));
    }

	@Override
	public void setFontColor(PaintStyle color) {
	    if (!(color instanceof SolidPaint)) {
	        throw new IllegalArgumentException("HSLF only supports solid paint");
	    }
		// In PowerPont RGB bytes are swapped, as BGR
	    SolidPaint sp = (SolidPaint)color;
	    Color c = DrawPaint.applyColorTransform(sp.getSolidColor());
		int rgb = new Color(c.getBlue(), c.getGreen(), c.getRed(), 254).getRGB();
		setFontColor(rgb);
	}

    private void setFlag(int index, boolean value) {
        BitMaskTextProp prop = characterStyle.addWithName(CharFlagsTextProp.NAME);
        prop.setSubValue(value, index);
    }

    public HSLFTextParagraph getTextParagraph() {
        return parentParagraph;
    }

    @Override
    public TextCap getTextCap() {
        return TextCap.NONE;
    }

    @Override
    public boolean isSubscript() {
        return getSuperscript() < 0;
    }

    @Override
    public boolean isSuperscript() {
        return getSuperscript() > 0;
    }

    @Override
    public byte getPitchAndFamily() {
        return 0;
    }

    /**
     * Sets the hyperlink - used when parsing the document
     *
     * @param link the hyperlink
     */
    /* package */ void setHyperlink(HSLFHyperlink link) {
        this.link = link;
    }

    @Override
    public HSLFHyperlink getHyperlink() {
        return link;
    }

    @Override
    public HSLFHyperlink createHyperlink() {
        if (link == null) {
            link = HSLFHyperlink.createHyperlink(this);
            parentParagraph.setDirty();
        }
        return link;
    }

    @Override
    public FieldType getFieldType() {
        HSLFTextShape ts = getTextParagraph().getParentShape();
        Placeholder ph = ts.getPlaceholder();

        if (ph != null) {
            switch (ph) {
            case SLIDE_NUMBER:
                return FieldType.SLIDE_NUMBER;
            case DATETIME:
                return FieldType.DATE_TIME;
            default:
                break;
            }
        }

        if (ts.getSheet() instanceof MasterSheet) {
            TextShape<?,? extends TextParagraph<?,?,? extends TextRun>> ms = ts.getMetroShape();
            if (ms == null || ms.getTextParagraphs().isEmpty()) {
                return null;
            }
            List<? extends TextRun> trList = ms.getTextParagraphs().get(0).getTextRuns();
            if (trList.isEmpty()) {
                return null;
            }
            return trList.get(0).getFieldType();
        }

        return null;
    }

    private FontGroup safeFontGroup(FontGroup fontGroup) {
        return (fontGroup != null) ? fontGroup : FontGroup.getFontGroupFirst(getRawText());
    }

	@Override
	public HSLFTextParagraph getParagraph() {
		return parentParagraph;
	}
}
