/*
 *  ====================================================================
 *    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.Graphics2D;
import java.awt.geom.Rectangle2D;

import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamReader;

import org.apache.poi.ooxml.util.XPathHelper;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.sl.draw.DrawFactory;
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.PlaceableShape;
import org.apache.poi.sl.usermodel.Placeholder;
import org.apache.poi.sl.usermodel.PlaceholderDetails;
import org.apache.poi.sl.usermodel.Shape;
import org.apache.poi.sl.usermodel.SimpleShape;
import org.apache.poi.util.Beta;
import org.apache.poi.util.Internal;
import org.apache.poi.xslf.model.PropertyFetcher;
import org.apache.poi.xslf.usermodel.XSLFPropertiesDelegate.XSLFFillProperties;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;
import org.openxmlformats.schemas.drawingml.x2006.main.CTBlipFillProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTGradientFillProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTGroupShapeProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
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.STSchemeColorVal;
import org.openxmlformats.schemas.presentationml.x2006.main.CTBackgroundProperties;
import org.openxmlformats.schemas.presentationml.x2006.main.CTPicture;
import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder;
import org.openxmlformats.schemas.presentationml.x2006.main.CTShape;
import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType;

/**
 * Base super-class class for all shapes in PresentationML
 */
@Beta
public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {

    @Internal
    public interface ReparseFactory<T extends XmlObject> {
        T parse(XMLStreamReader reader) throws XmlException;
    }

    static final String DML_NS = "http://schemas.openxmlformats.org/drawingml/2006/main";
    static final String PML_NS = "http://schemas.openxmlformats.org/presentationml/2006/main";

    private static final QName[] NV_CONTAINER = {
        new QName(PML_NS, "nvSpPr"),
        new QName(PML_NS, "nvCxnSpPr"),
        new QName(PML_NS, "nvGrpSpPr"),
        new QName(PML_NS, "nvPicPr"),
        new QName(PML_NS, "nvGraphicFramePr")
    };

    private static final QName[] CNV_PROPS = {
        new QName(PML_NS, "cNvPr")
    };

    private final XmlObject _shape;
    private final XSLFSheet _sheet;
    private XSLFShapeContainer _parent;

    private CTShapeStyle _spStyle;
    private CTNonVisualDrawingProps _nvPr;

    protected XSLFShape(XmlObject shape, XSLFSheet sheet) {
        _shape = shape;
        _sheet = sheet;
    }

    /**
     * @return the xml bean holding this shape's data
     */
    public final XmlObject getXmlObject() {
        // it's final because the xslf inheritance hierarchy is not necessary the same as
        // the (not existing) xmlbeans hierarchy and subclasses shouldn't narrow it's return value
        return _shape;
    }

    @Override
    public XSLFSheet getSheet() {
        return _sheet;
    }

    @Override
    public String getShapeName() {
        CTNonVisualDrawingProps nonVisualDrawingProps = getCNvPr();
        return nonVisualDrawingProps == null ? null : nonVisualDrawingProps.getName();
    }

    @Override
    public int getShapeId() {
        CTNonVisualDrawingProps nonVisualDrawingProps = getCNvPr();
        if (nonVisualDrawingProps == null) {
            throw new IllegalStateException("no underlying shape exists");
        }
        return Math.toIntExact(nonVisualDrawingProps.getId());
    }

    /**
     * Set the contents of this shape to be a copy of the source shape.
     * This method is called recursively for each shape when merging slides
     *
     * @param  sh the source shape
     * @see org.apache.poi.xslf.usermodel.XSLFSlide#importContent(XSLFSheet)
     */
    @Internal
    void copy(XSLFShape sh) {
        if (!getClass().isInstance(sh)) {
            throw new IllegalArgumentException(
                    "Can't copy " + sh.getClass().getSimpleName() + " into " + getClass().getSimpleName());
        }

        if (this instanceof PlaceableShape) {
            PlaceableShape<?,?> ps = (PlaceableShape<?,?>)this;
            Rectangle2D anchor = sh.getAnchor();
            if (anchor != null) {
                ps.setAnchor(anchor);
            }
        }


    }

    public void setParent(XSLFShapeContainer parent) {
        this._parent = parent;
    }

    @Override
    public XSLFShapeContainer getParent() {
        return this._parent;
    }

    protected PaintStyle getFillPaint() {
        final XSLFTheme theme = getSheet().getTheme();
        final boolean hasPlaceholder = getPlaceholder() != null;

        PropertyFetcher<PaintStyle> fetcher = new PropertyFetcher<PaintStyle>() {
            @Override
            public boolean fetch(XSLFShape shape) {
                PackagePart pp = shape.getSheet().getPackagePart();
                if (shape instanceof XSLFPictureShape) {
                    CTPicture pic = (CTPicture)shape.getXmlObject();
                    if (pic.getBlipFill() != null) {
                        setValue(selectPaint(pic.getBlipFill(), pp, null, theme));
                        return true;
                    }
                }

                XSLFFillProperties fp = XSLFPropertiesDelegate.getFillDelegate(shape.getShapeProperties());
                if (fp == null) {
                    return false;
                }

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

                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.getFillRef());
                    paint = selectPaint(fp, null, pp, theme, hasPlaceholder);
                }
                if (paint != null) {
                    setValue(paint);
                    return true;
                }


                return false;
            }
        };
        fetchShapeProperty(fetcher);

        return fetcher.getValue();
    }

    @SuppressWarnings("unused")
    protected CTBackgroundProperties getBgPr() {
        return getChild(CTBackgroundProperties.class, PML_NS, "bgPr");
    }

    @SuppressWarnings("unused")
    protected CTStyleMatrixReference getBgRef() {
        return getChild(CTStyleMatrixReference.class, PML_NS, "bgRef");
    }

    protected CTGroupShapeProperties getGrpSpPr() {
        return getChild(CTGroupShapeProperties.class, PML_NS, "grpSpPr");
    }

    protected CTNonVisualDrawingProps getCNvPr() {
        try {
            if (_nvPr == null) {
                _nvPr = XPathHelper.selectProperty(getXmlObject(), CTNonVisualDrawingProps.class, null, NV_CONTAINER, CNV_PROPS);
            }
            return _nvPr;
        } catch (XmlException e) {
            return null;
        }
    }

    @SuppressWarnings("WeakerAccess")
    protected CTShapeStyle getSpStyle() {
        if (_spStyle == null) {
            _spStyle = getChild(CTShapeStyle.class, PML_NS, "style");
        }
        return _spStyle;
    }

    /**
     * Return direct child objects of this shape
     *
     * @param childClass the class to cast the properties to
     * @param namespace the namespace - usually it is {@code "http://schemas.openxmlformats.org/presentationml/2006/main"}
     * @param nodename the node name, without prefix
     * @return the properties object or null if it can't be found
     */
    @SuppressWarnings({"unchecked", "WeakerAccess", "unused", "SameParameterValue"})
    protected <T extends XmlObject> T getChild(Class<T> childClass, String namespace, String nodename) {
        XmlCursor cur = getXmlObject().newCursor();
        T child = null;
        if (cur.toChild(namespace, nodename)) {
            child = (T)cur.getObject();
        }
        if (cur.toChild(XSLFRelation.NS_DRAWINGML, nodename)) {
            child = (T)cur.getObject();
        }
        cur.dispose();
        return child;
    }

    public boolean isPlaceholder() {
        return getPlaceholderDetails().getCTPlaceholder(false) != null;
    }

    /**
     * @see PlaceholderDetails#getPlaceholder()
     */
    public Placeholder getPlaceholder() {
        return getPlaceholderDetails().getPlaceholder();
    }

    /**
     * @see PlaceholderDetails#setPlaceholder(Placeholder)
     */
    public void setPlaceholder(final Placeholder placeholder) {
        getPlaceholderDetails().setPlaceholder(placeholder);
    }

    /**
     * @see SimpleShape#getPlaceholderDetails()
     */
    @SuppressWarnings("WeakerAccess")
    public XSLFPlaceholderDetails getPlaceholderDetails() {
        return new XSLFPlaceholderDetails(this);
    }

    /**
     * As there's no xmlbeans hierarchy, but XSLF works with subclassing, not all
     * child classes work with a {@link CTShape} object, but often contain the same
     * properties. This method is the generalized form of selecting and casting those
     * properties.
     *
     * @param resultClass the requested result class
     * @param xquery the simple (xmlbean) xpath expression to the property
     * @return the xml object at the xpath location, or null if not found
     */
    @SuppressWarnings({"unchecked", "WeakerAccess"})
    protected <T extends XmlObject> T selectProperty(Class<T> resultClass, String xquery) {
        XmlObject[] rs = getXmlObject().selectPath(xquery);
        if (rs.length == 0) {
            return null;
        }
        return (resultClass.isInstance(rs[0])) ? (T)rs[0] : null;
    }

    /**
     * Walk up the inheritance tree and fetch shape properties.<p>
     *
     * The following order of inheritance is assumed:<p>
     * <ol>
     * <li>slide
     * <li>slideLayout
     * <li>slideMaster
     * </ol>
     *
     * Currently themes and their defaults aren't correctly handled
     *
     * @param visitor the object that collects the desired property
     * @return true if the property was fetched
     */
    @SuppressWarnings("WeakerAccess")
    @Internal
    public boolean fetchShapeProperty(PropertyFetcher<?> visitor) {
        // try shape properties in slide
        if (visitor.fetch(this)) {
            return true;
        }

        final CTPlaceholder ph = getPlaceholderDetails().getCTPlaceholder(false);
        if (ph == null) {
            return false;
        }
        MasterSheet<XSLFShape,XSLFTextParagraph> sm = getSheet().getMasterSheet();

        // try slide layout
        if (sm instanceof XSLFSlideLayout) {
            XSLFSlideLayout slideLayout = (XSLFSlideLayout)sm;
            XSLFSimpleShape placeholderShape = slideLayout.getPlaceholder(ph);
            if (placeholderShape != null && visitor.fetch(placeholderShape)) {
                return true;
            }
            sm = slideLayout.getMasterSheet();
        }

        // try slide master
        if (sm instanceof XSLFSlideMaster) {
            XSLFSlideMaster master = (XSLFSlideMaster)sm;
            int textType = getPlaceholderType(ph);
            XSLFSimpleShape masterShape = master.getPlaceholderByType(textType);
            return masterShape != null && visitor.fetch(masterShape);
        }

        return false;
    }

    private static int getPlaceholderType(CTPlaceholder ph) {
        if ( !ph.isSetType()) {
            return STPlaceholderType.INT_BODY;
        }

        switch (ph.getType().intValue()) {
            case STPlaceholderType.INT_TITLE:
            case STPlaceholderType.INT_CTR_TITLE:
                return STPlaceholderType.INT_TITLE;
            case STPlaceholderType.INT_FTR:
            case STPlaceholderType.INT_SLD_NUM:
            case STPlaceholderType.INT_DT:
                return ph.getType().intValue();
            default:
                return STPlaceholderType.INT_BODY;
        }
    }

    /**
     * Convert shape fill into java.awt.Paint. The result is either Color or
     * TexturePaint or GradientPaint or null
     *
     * @param fp          a properties handler specific to the underlying shape properties
     * @param phClr       context color
     * @param parentPart  the parent package part. Any external references (images, etc.) are resolved relative to it.
     * @param theme       the theme for the shape/sheet
     *
     * @return  the applied Paint or null if none was applied
     */
    @SuppressWarnings("WeakerAccess")
    protected PaintStyle selectPaint(XSLFFillProperties fp, final CTSchemeColor phClr, final PackagePart parentPart, final XSLFTheme theme, boolean hasPlaceholder) {
        if (fp == null || fp.isSetNoFill()) {
            return null;
        } else if (fp.isSetSolidFill()) {
            return selectPaint(fp.getSolidFill(), phClr, theme);
        } else if (fp.isSetBlipFill()) {
            return selectPaint(fp.getBlipFill(), parentPart, phClr, theme);
        } else if (fp.isSetGradFill()) {
            return selectPaint(fp.getGradFill(), phClr, theme);
        } else if (fp.isSetMatrixStyle()) {
            return selectPaint(fp.getMatrixStyle(), theme, fp.isLineStyle(), hasPlaceholder);
        } else if (phClr != null) {
            return selectPaint(phClr, theme);
        } else {
            return null;
        }
    }

    protected PaintStyle selectPaint(CTSchemeColor phClr, final XSLFTheme theme) {
        final XSLFColor c = new XSLFColor(null, theme, phClr, _sheet);
        return DrawPaint.createSolidPaint(c.getColorStyle());
    }

    @SuppressWarnings("WeakerAccess")
    protected PaintStyle selectPaint(CTSolidColorFillProperties solidFill, CTSchemeColor phClr, final XSLFTheme theme) {
        CTSchemeColor nestedPhClr = solidFill.getSchemeClr();
        boolean useNested = nestedPhClr != null && nestedPhClr.getVal() != null && !STSchemeColorVal.PH_CLR.equals(nestedPhClr.getVal());
        final XSLFColor c = new XSLFColor(solidFill, theme, useNested ? nestedPhClr : phClr, _sheet);
        return DrawPaint.createSolidPaint(c.getColorStyle());
    }

    @SuppressWarnings("WeakerAccess")
    protected PaintStyle selectPaint(final CTBlipFillProperties blipFill, final PackagePart parentPart, CTSchemeColor phClr, final XSLFTheme theme) {
        return new XSLFTexturePaint(blipFill, parentPart, phClr, theme, _sheet);
    }

    @SuppressWarnings("WeakerAccess")
    protected PaintStyle selectPaint(final CTGradientFillProperties gradFill, CTSchemeColor phClr, final XSLFTheme theme) {
        return new XSLFGradientPaint(gradFill, phClr, theme, _sheet);
    }

    @SuppressWarnings("WeakerAccess")
    protected PaintStyle selectPaint(CTStyleMatrixReference fillRef, final XSLFTheme theme, boolean isLineStyle, boolean hasPlaceholder) {
        if (fillRef == null) {
            return null;
        }

        // The idx attribute refers to the index of a fill style or
        // background fill style within the presentation's style matrix, defined by the fmtScheme element.
        // value of 0 or 1000 indicates no background,
        // values 1-999 refer to the index of a fill style within the fillStyleLst element
        // values 1001 and above refer to the index of a background fill style within the bgFillStyleLst element.
        long idx = fillRef.getIdx();
        CTStyleMatrix matrix = theme.getXmlObject().getThemeElements().getFmtScheme();
        final XmlObject styleLst;
        long childIdx;
        if (idx >= 1 && idx <= 999) {
            childIdx = idx-1;
            styleLst = (isLineStyle) ? matrix.getLnStyleLst() : matrix.getFillStyleLst();
        } else if (idx >= 1001 ){
            childIdx = idx - 1001;
            styleLst = matrix.getBgFillStyleLst();
        } else {
            return null;
        }
        XmlCursor cur = styleLst.newCursor();
        XSLFFillProperties fp = null;
        if (cur.toChild(Math.toIntExact(childIdx))) {
            fp = XSLFPropertiesDelegate.getFillDelegate(cur.getObject());
        }
        cur.dispose();

        CTSchemeColor phClr = fillRef.getSchemeClr();
        PaintStyle res =  selectPaint(fp, phClr, theme.getPackagePart(), theme, hasPlaceholder);
        // check for empty placeholder value
        // see http://officeopenxml.com/prSlide-color.php - "Color Placeholders within Themes"
        if (res != null || hasPlaceholder) {
            return res;
        }
        XSLFColor col = new XSLFColor(fillRef, theme, phClr, _sheet);
        return DrawPaint.createSolidPaint(col.getColorStyle());
    }

    @Override
    public void draw(Graphics2D graphics, Rectangle2D bounds) {
        DrawFactory.getInstance(graphics).drawShape(graphics, this, bounds);
    }

    /**
     * Return the shape specific (visual) properties
     *
     * @return the shape specific properties
     */
    protected XmlObject getShapeProperties() {
        return getChild(CTShapeProperties.class, PML_NS, "spPr");
    }
}
