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

import java.awt.Color;
import java.awt.geom.Rectangle2D;

import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.poi.ooxml.util.POIXMLUnits;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.sl.draw.DrawPaint;
import org.apache.poi.sl.draw.geom.CustomGeometry;
import org.apache.poi.sl.draw.geom.Guide;
import org.apache.poi.sl.draw.geom.PresetGeometries;
import org.apache.poi.sl.usermodel.FillStyle;
import org.apache.poi.sl.usermodel.LineDecoration;
import org.apache.poi.sl.usermodel.LineDecoration.DecorationShape;
import org.apache.poi.sl.usermodel.LineDecoration.DecorationSize;
import org.apache.poi.sl.usermodel.PaintStyle;
import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;
import org.apache.poi.sl.usermodel.ShapeType;
import org.apache.poi.sl.usermodel.SimpleShape;
import org.apache.poi.sl.usermodel.StrokeStyle;
import org.apache.poi.sl.usermodel.StrokeStyle.LineCap;
import org.apache.poi.sl.usermodel.StrokeStyle.LineCompound;
import org.apache.poi.sl.usermodel.StrokeStyle.LineDash;
import org.apache.poi.util.Beta;
import org.apache.poi.util.Units;
import org.apache.poi.xslf.model.PropertyFetcher;
import org.apache.poi.xslf.usermodel.XSLFPropertiesDelegate.XSLFEffectProperties;
import org.apache.poi.xslf.usermodel.XSLFPropertiesDelegate.XSLFFillProperties;
import org.apache.poi.xslf.usermodel.XSLFPropertiesDelegate.XSLFGeometryProperties;
import org.apache.xmlbeans.XmlObject;
import org.openxmlformats.schemas.drawingml.x2006.main.*;

/**
 * Represents a single (non-group) shape in a .pptx slide show
 */
@Beta
public abstract class XSLFSimpleShape extends XSLFShape
    implements SimpleShape<XSLFShape,XSLFTextParagraph> {
    private static final CTOuterShadowEffect NO_SHADOW = CTOuterShadowEffect.Factory.newInstance();
    private static final Logger LOG = LogManager.getLogger(XSLFSimpleShape.class);

    /* package */XSLFSimpleShape(XmlObject shape, XSLFSheet sheet) {
        super(shape,sheet);
    }

    @Override
    public void setShapeType(ShapeType type) {
        XSLFGeometryProperties gp = XSLFPropertiesDelegate.getGeometryDelegate(getShapeProperties());
        if (gp == null) {
            return;
        }
        if (gp.isSetCustGeom()) {
            gp.unsetCustGeom();
        }
        CTPresetGeometry2D prst = (gp.isSetPrstGeom()) ? gp.getPrstGeom() : gp.addNewPrstGeom();
        prst.setPrst(STShapeType.Enum.forInt(type.ooxmlId));
    }

    @Override
    public ShapeType getShapeType(){
        XSLFGeometryProperties gp = XSLFPropertiesDelegate.getGeometryDelegate(getShapeProperties());
        if (gp != null && gp.isSetPrstGeom()) {
            STShapeType.Enum geom = gp.getPrstGeom().getPrst();
            if (geom != null) {
                return ShapeType.forId(geom.intValue(), true);
            }
        }
        return null;
    }

    protected CTTransform2D getXfrm(boolean create) {
        PropertyFetcher<CTTransform2D> fetcher = new PropertyFetcher<CTTransform2D>() {
            @Override
            public boolean fetch(XSLFShape shape) {
                XmlObject xo = shape.getShapeProperties();
                if (xo instanceof CTShapeProperties && ((CTShapeProperties)xo).isSetXfrm()) {
                    setValue(((CTShapeProperties)xo).getXfrm());
                    return true;
                }
                return false;
            }
        };
        fetchShapeProperty(fetcher);

        CTTransform2D xfrm = fetcher.getValue();
        if (!create || xfrm != null) {
            return xfrm;
        } else {
            XmlObject xo = getShapeProperties();
            if (xo instanceof CTShapeProperties) {
                return ((CTShapeProperties)xo).addNewXfrm();
            } else {
                // ... group shapes have their own getXfrm()
                LOG.atWarn().log("{} doesn't have xfrm element.", getClass());
                return null;
            }
        }
    }

    @Override
    public Rectangle2D getAnchor() {

        CTTransform2D xfrm = getXfrm(false);
        if (xfrm == null || !xfrm.isSetOff()) {
            return null;
        }

        CTPoint2D off = xfrm.getOff();
        double x = Units.toPoints(POIXMLUnits.parseLength(off.xgetX()));
        double y = Units.toPoints(POIXMLUnits.parseLength(off.xgetY()));
        CTPositiveSize2D ext = xfrm.getExt();
        double cx = Units.toPoints(ext.getCx());
        double cy = Units.toPoints(ext.getCy());
        return new Rectangle2D.Double(x, y, cx, cy);
    }

    @Override
    public void setAnchor(Rectangle2D anchor) {
        CTTransform2D xfrm = getXfrm(true);
        if (xfrm == null) {
            return;
        }
        CTPoint2D off = xfrm.isSetOff() ? xfrm.getOff() : xfrm.addNewOff();
        long x = Units.toEMU(anchor.getX());
        long y = Units.toEMU(anchor.getY());
        off.setX(x);
        off.setY(y);
        CTPositiveSize2D ext = xfrm.isSetExt() ? xfrm.getExt() : xfrm
                .addNewExt();
        long cx = Units.toEMU(anchor.getWidth());
        long cy = Units.toEMU(anchor.getHeight());
        ext.setCx(cx);
        ext.setCy(cy);
    }

    @Override
    public void setRotation(double theta) {
        CTTransform2D xfrm = getXfrm(true);
        if (xfrm != null) {
            xfrm.setRot((int) (theta * 60000));
        }
    }

    @Override
    public double getRotation() {
        CTTransform2D xfrm = getXfrm(false);
        return (xfrm == null || !xfrm.isSetRot()) ? 0 : (xfrm.getRot() / 60000.d);
    }

    @Override
    public void setFlipHorizontal(boolean flip) {
        CTTransform2D xfrm = getXfrm(true);
        if (xfrm != null) {
            xfrm.setFlipH(flip);
        }
    }

    @Override
    public void setFlipVertical(boolean flip) {
        CTTransform2D xfrm = getXfrm(true);
        if (xfrm != null) {
            xfrm.setFlipV(flip);
        }
    }

    @Override
    public boolean getFlipHorizontal() {
        CTTransform2D xfrm = getXfrm(false);
        return (xfrm != null && xfrm.isSetFlipH()) && xfrm.getFlipH();
    }

    @Override
    public boolean getFlipVertical() {
        CTTransform2D xfrm = getXfrm(false);
        return (xfrm != null && xfrm.isSetFlipV()) && xfrm.getFlipV();
    }


    /**
     * Get default line properties defined in the theme (if any).
     * Used internally to resolve shape properties.
     *
     * @return line properties from the theme of null
     */
    private CTLineProperties getDefaultLineProperties() {
        CTShapeStyle style = getSpStyle();
        if (style == null) {
            return null;
        }
        CTStyleMatrixReference lnRef = style.getLnRef();
        if (lnRef == null) {
            return null;
        }
        // 1-based index of a line style within the style matrix
        int idx = Math.toIntExact(lnRef.getIdx());

        XSLFTheme theme = getSheet().getTheme();
        if (theme == null) {
            return null;
        }
        CTBaseStyles styles = theme.getXmlObject().getThemeElements();
        if (styles == null) {
            return null;
        }
        CTStyleMatrix styleMatrix = styles.getFmtScheme();
        if (styleMatrix == null) {
            return null;
        }
        CTLineStyleList lineStyles = styleMatrix.getLnStyleLst();
        if (lineStyles == null || lineStyles.sizeOfLnArray() < idx) {
            return null;
        }

        return lineStyles.getLnArray(idx - 1);
    }

    /**
    * @param color  the color to paint the shape outline.
     * A <code>null</code> value turns off the shape outline.
     */
    public void setLineColor(Color color) {
        CTLineProperties ln = getLn(this, true);
        if (ln == null) {
            return;
        }

        if (ln.isSetSolidFill()) {
            ln.unsetSolidFill();
        }
        if (ln.isSetGradFill()) {
            ln.unsetGradFill();
        }
        if (ln.isSetPattFill()) {
            ln.unsetPattFill();
        }
        if (ln.isSetNoFill()) {
            ln.unsetNoFill();
        }


        if (color == null) {
            ln.addNewNoFill();
        } else {
            CTSolidColorFillProperties fill = ln.addNewSolidFill();
            XSLFColor col = new XSLFColor(fill, getSheet().getTheme(), fill.getSchemeClr(), getSheet());
            col.setColor(color);
        }
    }

    /**
     *
     * @return the color of the shape outline or <code>null</code>
     * if outline is turned off
     */
    @SuppressWarnings("WeakerAccess")
    public Color getLineColor() {
        PaintStyle ps = getLinePaint();
        if (ps instanceof SolidPaint) {
            return ((SolidPaint)ps).getSolidColor().getColor();
        }
        return null;
    }

    @SuppressWarnings("WeakerAccess")
    protected PaintStyle getLinePaint() {
        XSLFSheet sheet = getSheet();
        final XSLFTheme theme = sheet.getTheme();
        final boolean hasPlaceholder = getPlaceholder() != null;
        PropertyFetcher<PaintStyle> fetcher = new PropertyFetcher<PaintStyle>() {
            @Override
            public boolean fetch(XSLFShape shape) {
                CTLineProperties spPr = getLn(shape, false);
                XSLFFillProperties fp = XSLFPropertiesDelegate.getFillDelegate(spPr);

                if (fp != null && fp.isSetNoFill()) {
                    setValue(null);
                    return true;
                }

                PackagePart pp = shape.getSheet().getPackagePart();
                PaintStyle paint = selectPaint(fp, null, pp, theme, hasPlaceholder);
                if (paint != null) {
                    setValue(paint);
                    return true;
                }

                CTShapeStyle style = shape.getSpStyle();
                if (style != null) {
                    fp = XSLFPropertiesDelegate.getFillDelegate(style.getLnRef());
                    paint = selectPaint(fp, null, pp, theme, hasPlaceholder);

                    // line color was not found, check if it is defined in the theme
                    if (paint == null) {
                        paint = getThemePaint(style, pp);
                    }
                }

                if (paint != null) {
                    setValue(paint);
                    return true;
                }

                return false;
            }

            PaintStyle getThemePaint(CTShapeStyle style, PackagePart pp) {
                // get a reference to a line style within the style matrix.
                CTStyleMatrixReference lnRef = style.getLnRef();
                if (lnRef == null) {
                    return null;
                }
                int idx = Math.toIntExact(lnRef.getIdx());
                CTSchemeColor phClr = lnRef.getSchemeClr();
                if(idx <= 0){
                    return null;
                }

                CTLineProperties props = theme.getXmlObject().getThemeElements().getFmtScheme().getLnStyleLst().getLnArray(idx - 1);
                XSLFFillProperties fp = XSLFPropertiesDelegate.getFillDelegate(props);
                return selectPaint(fp, phClr, pp, theme, hasPlaceholder);
            }
        };
        fetchShapeProperty(fetcher);

        return fetcher.getValue();
    }

    /**
     *
     * @param width line width in points. <code>0</code> means no line
     */
    @SuppressWarnings("WeakerAccess")
    public void setLineWidth(double width) {
        CTLineProperties lnPr = getLn(this, true);
        if (lnPr == null) {
            return;
        }

        if (width == 0.) {
            if (lnPr.isSetW()) {
                lnPr.unsetW();
            }
            if (!lnPr.isSetNoFill()) {
                lnPr.addNewNoFill();
            }
            if (lnPr.isSetSolidFill()) {
                lnPr.unsetSolidFill();
            }
            if (lnPr.isSetGradFill()) {
                lnPr.unsetGradFill();
            }
            if (lnPr.isSetPattFill()) {
                lnPr.unsetPattFill();
            }
        } else {
            if (lnPr.isSetNoFill()) {
                lnPr.unsetNoFill();
            }

            lnPr.setW(Units.toEMU(width));
        }
    }

    /**
     * @return line width in points. <code>0</code> means no line.
     */
    @SuppressWarnings("WeakerAccess")
    public double getLineWidth() {
        PropertyFetcher<Double> fetcher = new PropertyFetcher<Double>() {
            @Override
            public boolean fetch(XSLFShape shape) {
                CTLineProperties ln = getLn(shape, false);
                if (ln != null) {
                    if (ln.isSetNoFill()) {
                        setValue(0.);
                        return true;
                    }

                    if (ln.isSetW()) {
                        setValue(Units.toPoints(ln.getW()));
                        return true;
                    }
                }
                return false;
            }
        };
        fetchShapeProperty(fetcher);

        double lineWidth = 0;
        if (fetcher.getValue() == null) {
            CTLineProperties defaultLn = getDefaultLineProperties();
            if (defaultLn != null) {
                if (defaultLn.isSetW()) {
                    lineWidth = Units.toPoints(defaultLn.getW());
                }
            }
        } else {
            lineWidth = fetcher.getValue();
        }

        return lineWidth;
    }


    /**
     * @param compound set the line compound style
     */
    @SuppressWarnings("WeakerAccess")
    public void setLineCompound(LineCompound compound) {
        CTLineProperties ln = getLn(this, true);
        if (ln == null) {
            return;
        }
        if (compound == null) {
            if (ln.isSetCmpd()) {
                ln.unsetCmpd();
            }
        } else {
            STCompoundLine.Enum xCmpd;
            switch (compound) {
                default:
                case SINGLE:
                    xCmpd = STCompoundLine.SNG;
                    break;
                case DOUBLE:
                    xCmpd = STCompoundLine.DBL;
                    break;
                case THICK_THIN:
                    xCmpd = STCompoundLine.THICK_THIN;
                    break;
                case THIN_THICK:
                    xCmpd = STCompoundLine.THIN_THICK;
                    break;
                case TRIPLE:
                    xCmpd = STCompoundLine.TRI;
                    break;
            }
            ln.setCmpd(xCmpd);
        }
    }

    /**
     * @return the line compound
     */
    @SuppressWarnings("WeakerAccess")
    public LineCompound getLineCompound() {
        PropertyFetcher<Integer> fetcher = new PropertyFetcher<Integer>() {
            @Override
            public boolean fetch(XSLFShape shape) {
                CTLineProperties ln = getLn(shape, false);
                if (ln != null) {
                    STCompoundLine.Enum stCmpd = ln.getCmpd();
                    if (stCmpd != null) {
                        setValue(stCmpd.intValue());
                        return true;
                    }
                }
                return false;
            }
        };
        fetchShapeProperty(fetcher);

        Integer cmpd = fetcher.getValue();
        if (cmpd == null) {
            CTLineProperties defaultLn = getDefaultLineProperties();
            if (defaultLn != null && defaultLn.isSetCmpd()) {
                switch (defaultLn.getCmpd().intValue()) {
                default:
                case STCompoundLine.INT_SNG:
                    return LineCompound.SINGLE;
                case STCompoundLine.INT_DBL:
                    return LineCompound.DOUBLE;
                case STCompoundLine.INT_THICK_THIN:
                    return LineCompound.THICK_THIN;
                case STCompoundLine.INT_THIN_THICK:
                    return LineCompound.THIN_THICK;
                case STCompoundLine.INT_TRI:
                    return LineCompound.TRIPLE;
                }
            }
        }

        return null;
    }

    /**
     *
     * @param dash a preset line dashing scheme to stroke thr shape outline
     */
    @SuppressWarnings("WeakerAccess")
    public void setLineDash(LineDash dash) {
        CTLineProperties ln = getLn(this, true);
        if (ln == null) {
            return;
        }
        if (dash == null) {
            if (ln.isSetPrstDash()) {
                ln.unsetPrstDash();
            }
        } else {
            CTPresetLineDashProperties ldp = ln.isSetPrstDash() ? ln.getPrstDash() : ln.addNewPrstDash();
            ldp.setVal(STPresetLineDashVal.Enum.forInt(dash.ooxmlId));
        }
    }

    /**
     * @return  a preset line dashing scheme to stroke the shape outline
     */
    @SuppressWarnings("WeakerAccess")
    public LineDash getLineDash() {

        PropertyFetcher<LineDash> fetcher = new PropertyFetcher<LineDash>() {
            @Override
            public boolean fetch(XSLFShape shape) {
                CTLineProperties ln = getLn(shape, false);
                if (ln == null || !ln.isSetPrstDash()) {
                    return false;
                }

                setValue(LineDash.fromOoxmlId(ln.getPrstDash().getVal().intValue()));
                return true;
            }
        };
        fetchShapeProperty(fetcher);

        LineDash dash = fetcher.getValue();
        if (dash == null) {
            CTLineProperties defaultLn = getDefaultLineProperties();
            if (defaultLn != null && defaultLn.isSetPrstDash()) {
                dash = LineDash.fromOoxmlId(defaultLn.getPrstDash().getVal().intValue());
            }
        }
        return dash;
    }

    /**
     *
     * @param cap the line end cap style
     */
    @SuppressWarnings("WeakerAccess")
    public void setLineCap(LineCap cap) {
        CTLineProperties ln = getLn(this, true);
        if (ln == null) {
            return;
        }

        if (cap == null) {
            if (ln.isSetCap()) {
                ln.unsetCap();
            }
        } else {
            ln.setCap(STLineCap.Enum.forInt(cap.ooxmlId));
        }
    }

    /**
     *
     * @return the line end cap style
     */
    @SuppressWarnings("WeakerAccess")
    public LineCap getLineCap() {
        PropertyFetcher<LineCap> fetcher = new PropertyFetcher<LineCap>() {
            @Override
            public boolean fetch(XSLFShape shape) {
                CTLineProperties ln = getLn(shape, false);
                if (ln != null && ln.isSetCap()) {
                    setValue(LineCap.fromOoxmlId(ln.getCap().intValue()));
                    return true;
                }
                return false;
            }
        };
        fetchShapeProperty(fetcher);

        LineCap cap = fetcher.getValue();
        if (cap == null) {
            CTLineProperties defaultLn = getDefaultLineProperties();
            if (defaultLn != null && defaultLn.isSetCap()) {
                cap = LineCap.fromOoxmlId(defaultLn.getCap().intValue());
            }
        }
        return cap;
    }

    @Override
    public void setFillColor(Color color) {
        XSLFFillProperties fp = XSLFPropertiesDelegate.getFillDelegate(getShapeProperties());
        if (fp == null) {
            return;
        }
        if (color == null) {
            if (fp.isSetSolidFill()) {
                fp.unsetSolidFill();
            }

            if (fp.isSetGradFill()) {
                fp.unsetGradFill();
            }

            if (fp.isSetPattFill()) {
                fp.unsetGradFill();
            }

            if (fp.isSetBlipFill()) {
                fp.unsetBlipFill();
            }

            if (!fp.isSetNoFill()) {
                fp.addNewNoFill();
            }
        } else {
            if (fp.isSetNoFill()) {
                fp.unsetNoFill();
            }

            CTSolidColorFillProperties fill = fp.isSetSolidFill() ? fp.getSolidFill() : fp.addNewSolidFill();

            XSLFColor col = new XSLFColor(fill, getSheet().getTheme(), fill.getSchemeClr(), getSheet());
            col.setColor(color);
        }
    }

    @Override
    public Color getFillColor() {
        PaintStyle ps = getFillPaint();
        if (ps instanceof SolidPaint) {
            return DrawPaint.applyColorTransform(((SolidPaint)ps).getSolidColor());
        }
        return null;
    }

    /**
     * @return shadow of this shape or null if shadow is disabled
     */
    @Override
    public XSLFShadow getShadow() {
        PropertyFetcher<CTOuterShadowEffect> fetcher = new PropertyFetcher<CTOuterShadowEffect>() {
            @Override
            public boolean fetch(XSLFShape shape) {
                XSLFEffectProperties ep = XSLFPropertiesDelegate.getEffectDelegate(shape.getShapeProperties());
                if (ep != null && ep.isSetEffectLst()) {
                    CTOuterShadowEffect obj = ep.getEffectLst().getOuterShdw();
                    setValue(obj == null ? NO_SHADOW : obj);
                    return true;
                }
                return false;
            }
        };
        fetchShapeProperty(fetcher);

        CTOuterShadowEffect obj = fetcher.getValue();
        if (obj == null) {
            // fill color was not found, check if it is defined in the theme
            CTShapeStyle style = getSpStyle();
            if (style != null && style.getEffectRef() != null) {
                // 1-based index of a shadow style within the style matrix
                int idx = (int) style.getEffectRef().getIdx();
                if(idx != 0) {
                    CTStyleMatrix styleMatrix = getSheet().getTheme().getXmlObject().getThemeElements().getFmtScheme();
                    CTEffectStyleItem ef = styleMatrix.getEffectStyleLst().getEffectStyleArray(idx - 1);
                    obj = ef.getEffectLst().getOuterShdw();
                }
            }
        }
        return (obj == null || obj == NO_SHADOW) ? null : new XSLFShadow(obj, this);
    }

    /**
     * @return definition of the shape geometry
     */
    @Override
    public CustomGeometry getGeometry() {
        XSLFGeometryProperties gp = XSLFPropertiesDelegate.getGeometryDelegate(getShapeProperties());

        if (gp == null) {
            return null;
        }

        CustomGeometry geom;
        PresetGeometries dict = PresetGeometries.getInstance();
        if(gp.isSetPrstGeom()){
            String name = gp.getPrstGeom().getPrst().toString();
            geom = dict.get(name);
            if(geom == null) {
                throw new IllegalStateException("Unknown shape geometry: " + name + ", available geometries are: " + dict.keySet());
            }
        } else if (gp.isSetCustGeom()){
            XMLStreamReader staxReader = gp.getCustGeom().newXMLStreamReader();
            geom = PresetGeometries.convertCustomGeometry(staxReader);
            try {
                staxReader.close();
            }
            catch (XMLStreamException e) {
                LOG.atWarn().log("An error occurred while closing a Custom Geometry XML Stream Reader: {}", e.getMessage());
            }
        } else {
            geom = dict.get("rect");
        }
        return geom;
    }

    @Override
    void copy(XSLFShape sh){
        super.copy(sh);

        XSLFSimpleShape s = (XSLFSimpleShape)sh;

        Color srsSolidFill = s.getFillColor();
        Color tgtSoliFill = getFillColor();
        if(srsSolidFill != null && !srsSolidFill.equals(tgtSoliFill)){
            setFillColor(srsSolidFill);
        }

        XSLFFillProperties fp = XSLFPropertiesDelegate.getFillDelegate(getShapeProperties());
        if(fp != null && fp.isSetBlipFill()){
            CTBlip blip = fp.getBlipFill().getBlip();
            String blipId = blip.getEmbed();

            String relId = getSheet().importBlip(blipId, s.getSheet());
            blip.setEmbed(relId);
        }

        Color srcLineColor = s.getLineColor();
        Color tgtLineColor = getLineColor();
        if(srcLineColor != null && !srcLineColor.equals(tgtLineColor)) {
            setLineColor(srcLineColor);
        }

        double srcLineWidth = s.getLineWidth();
        double tgtLineWidth = getLineWidth();
        if(srcLineWidth != tgtLineWidth) {
            setLineWidth(srcLineWidth);
        }

        LineDash srcLineDash = s.getLineDash();
        LineDash tgtLineDash = getLineDash();
        if(srcLineDash != null && srcLineDash != tgtLineDash) {
            setLineDash(srcLineDash);
        }

        LineCap srcLineCap = s.getLineCap();
        LineCap tgtLineCap = getLineCap();
        if(srcLineCap != null && srcLineCap != tgtLineCap) {
            setLineCap(srcLineCap);
        }

    }

    /**
     * Specifies the line end decoration, such as a triangle or arrowhead.
     *
     * @param style the line end docoration style
     */
    @SuppressWarnings("WeakerAccess")
    public void setLineHeadDecoration(DecorationShape style) {
        CTLineProperties ln = getLn(this, true);
        if (ln == null) {
            return;
        }
        CTLineEndProperties lnEnd = ln.isSetHeadEnd() ? ln.getHeadEnd() : ln.addNewHeadEnd();
        if (style == null) {
            if (lnEnd.isSetType()) {
                lnEnd.unsetType();
            }
        } else {
            lnEnd.setType(STLineEndType.Enum.forInt(style.ooxmlId));
        }
    }

    /**
     * @return the line end decoration shape
     */
    @SuppressWarnings("WeakerAccess")
    public DecorationShape getLineHeadDecoration() {
        CTLineProperties ln = getLn(this, false);
        DecorationShape ds = DecorationShape.NONE;
        if (ln != null && ln.isSetHeadEnd() && ln.getHeadEnd().isSetType()) {
            ds = DecorationShape.fromOoxmlId(ln.getHeadEnd().getType().intValue());
        }
        return ds;
    }

    /**
     * specifies decoration width of the head of a line.
     *
     * @param style the decoration width
     */
    @SuppressWarnings("WeakerAccess")
    public void setLineHeadWidth(DecorationSize style) {
        CTLineProperties ln = getLn(this, true);
        if (ln == null) {
            return;
        }
        CTLineEndProperties lnEnd = ln.isSetHeadEnd() ? ln.getHeadEnd() : ln.addNewHeadEnd();
        if (style == null) {
            if (lnEnd.isSetW()) {
                lnEnd.unsetW();
            }
        } else {
            lnEnd.setW(STLineEndWidth.Enum.forInt(style.ooxmlId));
        }
    }

    /**
     * @return the line end decoration width
     */
    @SuppressWarnings("WeakerAccess")
    public DecorationSize getLineHeadWidth() {
        CTLineProperties ln = getLn(this, false);
        DecorationSize ds = DecorationSize.MEDIUM;
        if (ln != null && ln.isSetHeadEnd() && ln.getHeadEnd().isSetW()) {
            ds = DecorationSize.fromOoxmlId(ln.getHeadEnd().getW().intValue());
        }
        return ds;
    }

    /**
     * Specifies the line end width in relation to the line width.
     */
    @SuppressWarnings("WeakerAccess")
    public void setLineHeadLength(DecorationSize style) {
        CTLineProperties ln = getLn(this, true);
        if (ln == null) {
            return;
        }

        CTLineEndProperties lnEnd = ln.isSetHeadEnd() ? ln.getHeadEnd() : ln.addNewHeadEnd();
        if (style == null) {
            if (lnEnd.isSetLen()) {
                lnEnd.unsetLen();
            }
        } else {
            lnEnd.setLen(STLineEndLength.Enum.forInt(style.ooxmlId));
        }
    }

    /**
     * @return the line end decoration length
     */
    @SuppressWarnings("WeakerAccess")
    public DecorationSize getLineHeadLength() {
        CTLineProperties ln = getLn(this, false);

        DecorationSize ds = DecorationSize.MEDIUM;
        if (ln != null && ln.isSetHeadEnd() && ln.getHeadEnd().isSetLen()) {
            ds = DecorationSize.fromOoxmlId(ln.getHeadEnd().getLen().intValue());
        }
        return ds;
    }

    /**
     * Specifies the line end decoration, such as a triangle or arrowhead.
     */
    @SuppressWarnings("WeakerAccess")
    public void setLineTailDecoration(DecorationShape style) {
        CTLineProperties ln = getLn(this, true);
        if (ln == null) {
            return;
        }

        CTLineEndProperties lnEnd = ln.isSetTailEnd() ? ln.getTailEnd() : ln.addNewTailEnd();
        if (style == null) {
            if (lnEnd.isSetType()) {
                lnEnd.unsetType();
            }
        } else {
            lnEnd.setType(STLineEndType.Enum.forInt(style.ooxmlId));
        }
    }

    /**
     * @return the line end decoration shape
     */
    @SuppressWarnings("WeakerAccess")
    public DecorationShape getLineTailDecoration() {
        CTLineProperties ln = getLn(this, false);

        DecorationShape ds = DecorationShape.NONE;
        if (ln != null && ln.isSetTailEnd() && ln.getTailEnd().isSetType()) {
            ds = DecorationShape.fromOoxmlId(ln.getTailEnd().getType().intValue());
        }
        return ds;
    }

    /**
     * specifies decorations which can be added to the tail of a line.
     */
    @SuppressWarnings("WeakerAccess")
    public void setLineTailWidth(DecorationSize style) {
        CTLineProperties ln = getLn(this, true);
        if (ln == null) {
            return;
        }

        CTLineEndProperties lnEnd = ln.isSetTailEnd() ? ln.getTailEnd() : ln.addNewTailEnd();
        if (style == null) {
            if (lnEnd.isSetW()) {
                lnEnd.unsetW();
            }
        } else {
            lnEnd.setW(STLineEndWidth.Enum.forInt(style.ooxmlId));
        }
    }

    /**
     * @return the line end decoration width
     */
    @SuppressWarnings("WeakerAccess")
    public DecorationSize getLineTailWidth() {
        CTLineProperties ln = getLn(this, false);
        DecorationSize ds = DecorationSize.MEDIUM;
        if (ln != null && ln.isSetTailEnd() && ln.getTailEnd().isSetW()) {
            ds = DecorationSize.fromOoxmlId(ln.getTailEnd().getW().intValue());
        }
        return ds;
    }

    /**
     * Specifies the line end width in relation to the line width.
     */
    @SuppressWarnings("WeakerAccess")
    public void setLineTailLength(DecorationSize style) {
        CTLineProperties ln = getLn(this, true);
        if (ln == null) {
            return;
        }

        CTLineEndProperties lnEnd = ln.isSetTailEnd() ? ln.getTailEnd() : ln.addNewTailEnd();
        if (style == null) {
            if (lnEnd.isSetLen()) {
                lnEnd.unsetLen();
            }
        } else {
            lnEnd.setLen(STLineEndLength.Enum.forInt(style.ooxmlId));
        }
    }

    /**
     * @return the line end decoration length
     */
    @SuppressWarnings("WeakerAccess")
    public DecorationSize getLineTailLength() {
        CTLineProperties ln = getLn(this, false);

        DecorationSize ds = DecorationSize.MEDIUM;
        if (ln != null && ln.isSetTailEnd() && ln.getTailEnd().isSetLen()) {
            ds = DecorationSize.fromOoxmlId(ln.getTailEnd().getLen().intValue());
        }
        return ds;
    }

    @Override
    public Guide getAdjustValue(String name) {
        XSLFGeometryProperties gp = XSLFPropertiesDelegate.getGeometryDelegate(getShapeProperties());

        if (gp != null && gp.isSetPrstGeom() && gp.getPrstGeom().isSetAvLst()) {
            for (CTGeomGuide g : gp.getPrstGeom().getAvLst().getGdArray()) {
                if (g.getName().equals(name)) {
                    Guide gd = new Guide();
                    gd.setName(g.getName());
                    gd.setFmla(g.getFmla());
                    return gd;
                }
            }
        }

        return null;
    }

    @Override
    public LineDecoration getLineDecoration() {
        return new LineDecoration() {
            @Override
            public DecorationShape getHeadShape() {
                return getLineHeadDecoration();
            }

            @Override
            public DecorationSize getHeadWidth() {
                return getLineHeadWidth();
            }

            @Override
            public DecorationSize getHeadLength() {
                return getLineHeadLength();
            }

            @Override
            public DecorationShape getTailShape() {
                return getLineTailDecoration();
            }

            @Override
            public DecorationSize getTailWidth() {
                return getLineTailWidth();
            }

            @Override
            public DecorationSize getTailLength() {
                return getLineTailLength();
            }
        };
    }

    /**
     * fetch shape fill as a java.awt.Paint
     *
     * @return either Color or GradientPaint or TexturePaint or null
     */
    @Override
    public FillStyle getFillStyle() {
        return XSLFSimpleShape.this::getFillPaint;
    }

    @Override
    public StrokeStyle getStrokeStyle() {
        return new StrokeStyle() {
            @Override
            public PaintStyle getPaint() {
                return XSLFSimpleShape.this.getLinePaint();
            }

            @Override
            public LineCap getLineCap() {
                return XSLFSimpleShape.this.getLineCap();
            }

            @Override
            public LineDash getLineDash() {
                return XSLFSimpleShape.this.getLineDash();
            }

            @Override
            public double getLineWidth() {
                return XSLFSimpleShape.this.getLineWidth();
            }

            @Override
            public LineCompound getLineCompound() {
                return XSLFSimpleShape.this.getLineCompound();
            }

        };
    }

    @Override
    public void setStrokeStyle(Object... styles) {
        if (styles.length == 0) {
            // remove stroke
            setLineColor(null);
            return;
        }

        // TODO: handle PaintStyle
        for (Object st : styles) {
            if (st instanceof Number) {
                setLineWidth(((Number)st).doubleValue());
            } else if (st instanceof LineCap) {
                setLineCap((LineCap)st);
            } else if (st instanceof LineDash) {
                setLineDash((LineDash)st);
            } else if (st instanceof LineCompound) {
                setLineCompound((LineCompound)st);
            } else if (st instanceof Color) {
                setLineColor((Color)st);
            }
        }
    }

    @Override
    public XSLFHyperlink getHyperlink() {
        CTNonVisualDrawingProps cNvPr = getCNvPr();
        if (!cNvPr.isSetHlinkClick()) {
            return null;
        }
        return new XSLFHyperlink(cNvPr.getHlinkClick(), getSheet());
    }

    @Override
    public XSLFHyperlink createHyperlink() {
        XSLFHyperlink hl = getHyperlink();
        if (hl == null) {
            CTNonVisualDrawingProps cNvPr = getCNvPr();
            hl = new XSLFHyperlink(cNvPr.addNewHlinkClick(), getSheet());
        }
        return hl;
    }

    private static CTLineProperties getLn(XSLFShape shape, boolean create) {
        XmlObject pr = shape.getShapeProperties();
        if (!(pr instanceof CTShapeProperties)) {
            LOG.atWarn().log("{} doesn't have line properties", shape.getClass());
            return null;
        }

        CTShapeProperties spr = (CTShapeProperties)pr;
        return (spr.isSetLn() || !create) ? spr.getLn() : spr.addNewLn();
    }
}
