/*
 *  ====================================================================
 *    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.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.Placeholder;
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.POILogFactory;
import org.apache.poi.util.POILogger;
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.CTBaseStyles;
import org.openxmlformats.schemas.drawingml.x2006.main.CTBlip;
import org.openxmlformats.schemas.drawingml.x2006.main.CTEffectStyleItem;
import org.openxmlformats.schemas.drawingml.x2006.main.CTGeomGuide;
import org.openxmlformats.schemas.drawingml.x2006.main.CTLineEndProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTLineProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTLineStyleList;
import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
import org.openxmlformats.schemas.drawingml.x2006.main.CTOuterShadowEffect;
import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D;
import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetGeometry2D;
import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetLineDashProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor;
import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeStyle;
import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTStyleMatrix;
import org.openxmlformats.schemas.drawingml.x2006.main.CTStyleMatrixReference;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D;
import org.openxmlformats.schemas.drawingml.x2006.main.STCompoundLine;
import org.openxmlformats.schemas.drawingml.x2006.main.STLineCap;
import org.openxmlformats.schemas.drawingml.x2006.main.STLineEndLength;
import org.openxmlformats.schemas.drawingml.x2006.main.STLineEndType;
import org.openxmlformats.schemas.drawingml.x2006.main.STLineEndWidth;
import org.openxmlformats.schemas.drawingml.x2006.main.STPresetLineDashVal;
import org.openxmlformats.schemas.drawingml.x2006.main.STShapeType;
import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder;

/**
 * Represents a single (non-group) shape in a .pptx slide show
 */
@Beta
public abstract class XSLFSimpleShape extends XSLFShape
    implements SimpleShape<XSLFShape,XSLFTextParagraph> {
    private static CTOuterShadowEffect NO_SHADOW = CTOuterShadowEffect.Factory.newInstance();
    private static final POILogger LOG = POILogFactory.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>() {
            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.log(POILogger.WARN, getClass().toString()+" doesn't have xfrm element.");
                return null;
            }
        }
    }

    @Override
    public Rectangle2D getAnchor() {

        CTTransform2D xfrm = getXfrm(false);
        if (xfrm == null) {
            return null;
        }

        CTPoint2D off = xfrm.getOff();
        double x = Units.toPoints(off.getX());
        double y = Units.toPoints(off.getY());
        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()) ? false : xfrm.getFlipH();
    }

    @Override
    public boolean getFlipVertical() {
        CTTransform2D xfrm = getXfrm(false);
        return (xfrm == null || !xfrm.isSetFlipV()) ? false : 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
     */
    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 = (int)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());
            col.setColor(color);
        }
    }

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

    protected PaintStyle getLinePaint() {
        XSLFSheet sheet = getSheet();
        final XSLFTheme theme = sheet.getTheme();
        PropertyFetcher<PaintStyle> fetcher = new PropertyFetcher<PaintStyle>() {
            public boolean fetch(XSLFShape shape) {
                CTLineProperties spPr = getLn(shape, false);
                XSLFFillProperties fp = XSLFPropertiesDelegate.getFillDelegate(spPr);
                PackagePart pp = shape.getSheet().getPackagePart();
                PaintStyle paint = selectPaint(fp, null, pp, theme);
                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);
                }
                if (paint != null) {
                    setValue(paint);
                    return true;
                }
                return false;
            }
        };
        fetchShapeProperty(fetcher);

        PaintStyle paint = fetcher.getValue();
        if (paint != null) return paint;

        // line color was not found, check if it is defined in the theme
        CTShapeStyle style = getSpStyle();
        if (style == null) return null;

        // get a reference to a line style within the style matrix.
        CTStyleMatrixReference lnRef = style.getLnRef();
        int idx = (int)lnRef.getIdx();
        CTSchemeColor phClr = lnRef.getSchemeClr();
        if(idx > 0){
            CTLineProperties props = theme.getXmlObject().getThemeElements().getFmtScheme().getLnStyleLst().getLnArray(idx - 1);
            XSLFFillProperties fp = XSLFPropertiesDelegate.getFillDelegate(props);
            PackagePart pp = sheet.getPackagePart();
            paint = selectPaint(fp, phClr, pp, theme);
        }

        return paint;
    }

    /**
     *
     * @param width line width in points. <code>0</code> means no line
     */
    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.
     */
    public double getLineWidth() {
        PropertyFetcher<Double> fetcher = new PropertyFetcher<Double>() {
            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
     */
    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
     */
    public LineCompound getLineCompound() {
        PropertyFetcher<Integer> fetcher = new PropertyFetcher<Integer>() {
            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
     */
    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
     */
    public LineDash getLineDash() {

        PropertyFetcher<LineDash> fetcher = new PropertyFetcher<LineDash>() {
            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
     */
    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
     */
    public LineCap getLineCap() {
        PropertyFetcher<LineCap> fetcher = new PropertyFetcher<LineCap>() {
            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());
            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
     */
    public XSLFShadow getShadow() {
        PropertyFetcher<CTOuterShadowEffect> fetcher = new PropertyFetcher<CTOuterShadowEffect>() {
            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
     */
    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.log(POILogger.WARN,
                        "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().getPackagePart());
            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
     */
    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
     */
    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 
     */
    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
     */
    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.
     */
    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
     */
    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.
     */
    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
     */
    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.
     */
    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
     */
    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.
     */
    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
     */
    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; 
    }

    public boolean isPlaceholder() {
        CTPlaceholder ph = getCTPlaceholder();
        return ph != null;
    }

    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)) {
                    return new Guide(g.getName(), g.getFmla());
                }
            }
        }

        return null;
    }

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

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

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

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

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

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

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

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

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

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

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

            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 void setPlaceholder(Placeholder placeholder) {
        super.setPlaceholder(placeholder);
    }
    
    @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.log(POILogger.WARN, shape.getClass().toString()+" doesn't have line properties");
            return null;
        }
        
        CTShapeProperties spr = (CTShapeProperties)pr;
        return (spr.isSetLn() || !create) ? spr.getLn() : spr.addNewLn();
    }
}
