/*
 *  ====================================================================
 *    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 java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Comparator;

import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.sl.draw.DrawFactory;
import org.apache.poi.sl.draw.DrawPaint;
import org.apache.poi.sl.usermodel.ColorStyle;
import org.apache.poi.sl.usermodel.PaintStyle;
import org.apache.poi.sl.usermodel.PaintStyle.GradientPaint;
import org.apache.poi.sl.usermodel.PaintStyle.TexturePaint;
import org.apache.poi.sl.usermodel.PlaceableShape;
import org.apache.poi.sl.usermodel.Placeholder;
import org.apache.poi.sl.usermodel.Shape;
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.XmlObject;
import org.openxmlformats.schemas.drawingml.x2006.main.CTBlip;
import org.openxmlformats.schemas.drawingml.x2006.main.CTBlipFillProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTGradientFillProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTGradientStop;
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.STPathShadeType;
import org.openxmlformats.schemas.presentationml.x2006.main.CTApplicationNonVisualDrawingProps;
import org.openxmlformats.schemas.presentationml.x2006.main.CTBackgroundProperties;
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> {
    protected static final String PML_NS = "http://schemas.openxmlformats.org/presentationml/2006/main";
    
    private final XmlObject _shape;
    private final XSLFSheet _sheet;
    private XSLFShapeContainer _parent;

    private CTShapeStyle _spStyle;
    private CTNonVisualDrawingProps _nvPr;
    private CTPlaceholder _ph;

    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;
    }
    
    public XSLFSheet getSheet() {
        return _sheet;
    }
    
    /**
     * @return human-readable name of this shape, e.g. "Rectange 3"
     */
    public String getShapeName(){
        return getCNvPr().getName();
    }

    /**
     * Returns a unique identifier for this shape within the current document.
     * This ID may be used to assist in uniquely identifying this object so that it can
     * be referred to by other parts of the document.
     * <p>
     * If multiple objects within the same document share the same id attribute value,
     * then the document shall be considered non-conformant.
     * </p>
     *
     * @return unique id of this shape
     */
    public int getShapeId() {
        return (int)getCNvPr().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;
            ps.setAnchor(sh.getAnchor());
        }
        
        
    }
    
    public void setParent(XSLFShapeContainer parent) {
        this._parent = parent;
    }
    
    public XSLFShapeContainer getParent() {
        return this._parent;
    }
    
    protected PaintStyle getFillPaint() {
        final XSLFTheme theme = getSheet().getTheme();
        PropertyFetcher<PaintStyle> fetcher = new PropertyFetcher<PaintStyle>() {
            public boolean fetch(XSLFShape shape) {
                XSLFFillProperties fp = XSLFPropertiesDelegate.getFillDelegate(shape.getShapeProperties());
                if (fp == null) {
                    return false;
                }

                if (fp.isSetNoFill()) {
                    setValue(null);
                    return true;
                }
                
                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.getFillRef());
                    paint = selectPaint(fp, null, pp, theme);
                }
                if (paint != null) {
                    setValue(paint);
                    return true;
                }
                
                
                return false;
            }
        };
        fetchShapeProperty(fetcher);

        return fetcher.getValue();
    }

    protected CTBackgroundProperties getBgPr() {
        return getChild(CTBackgroundProperties.class, PML_NS, "bgPr");
    }
    
    protected CTStyleMatrixReference getBgRef() {
        return getChild(CTStyleMatrixReference.class, PML_NS, "bgRef");
    }
    
    protected CTGroupShapeProperties getGrpSpPr() {
        return getChild(CTGroupShapeProperties.class, PML_NS, "grpSpPr");
    }
    
    protected CTNonVisualDrawingProps getCNvPr() {
        if (_nvPr == null) {
            String xquery = "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//*/p:cNvPr";
            _nvPr = selectProperty(CTNonVisualDrawingProps.class, xquery);
        }
        return _nvPr;
    }

    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")
    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();
        }
        cur.dispose();
        return child;
    }
    
    protected CTPlaceholder getCTPlaceholder() {
        if (_ph == null) {
            String xquery = "declare namespace p='"+PML_NS+"' .//*/p:nvPr/p:ph";
            _ph = selectProperty(CTPlaceholder.class, xquery);
        }
        return _ph;
    }

    public Placeholder getPlaceholder() {
        CTPlaceholder ph = getCTPlaceholder();
        if (ph == null || !(ph.isSetType() || ph.isSetIdx())) {
            return null;
        }
        return Placeholder.lookupOoxml(ph.getType().intValue());
    }
    
    /**
     * Specifies that the corresponding shape should be represented by the generating application
     * as a placeholder. When a shape is considered a placeholder by the generating application
     * it can have special properties to alert the user that they may enter content into the shape.
     * Different types of placeholders are allowed and can be specified by using the placeholder
     * type attribute for this element
     *
     * @param placeholder The shape to use as placeholder or null if no placeholder should be set.
     */
    protected void setPlaceholder(Placeholder placeholder) {
        String xquery = "declare namespace p='"+PML_NS+"' .//*/p:nvPr";
        CTApplicationNonVisualDrawingProps nv = selectProperty(CTApplicationNonVisualDrawingProps.class, xquery);
        if (nv == null) return;
        if(placeholder == null) {
            if (nv.isSetPh()) nv.unsetPh();
            _ph = null;
        } else {
            nv.addNewPh().setType(STPlaceholderType.Enum.forInt(placeholder.ooxmlId));
        }
    }
    
    
    /**
     * 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")
    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.
     *
     * The following order of inheritance is assumed:
     * <p>
     * slide <-- slideLayout <-- slideMaster
     * </p>
     *
     * @param visitor the object that collects the desired property
     * @return true if the property was fetched
     */
    protected boolean fetchShapeProperty(PropertyFetcher<?> visitor) {
        boolean ok = visitor.fetch(this);

        XSLFSimpleShape masterShape;
        XSLFSheet masterSheet = (XSLFSheet)getSheet().getMasterSheet();
        CTPlaceholder ph = getCTPlaceholder();

        if (masterSheet != null && ph != null) {
            if (!ok) {
                masterShape = masterSheet.getPlaceholder(ph);
                if (masterShape != null) {
                    ok = visitor.fetch(masterShape);
                }
            }

            // try slide master
            if (!ok ) {
                int textType;
                if ( !ph.isSetType()) textType = STPlaceholderType.INT_BODY;
                else {
                    switch (ph.getType().intValue()) {
                        case STPlaceholderType.INT_TITLE:
                        case STPlaceholderType.INT_CTR_TITLE:
                            textType = STPlaceholderType.INT_TITLE;
                            break;
                        case STPlaceholderType.INT_FTR:
                        case STPlaceholderType.INT_SLD_NUM:
                        case STPlaceholderType.INT_DT:
                            textType = ph.getType().intValue();
                            break;
                        default:
                            textType = STPlaceholderType.INT_BODY;
                            break;
                    }
                }
                XSLFSheet master = (XSLFSheet)masterSheet.getMasterSheet();
                if (master != null) {
                    masterShape = master.getPlaceholderByType(textType);
                    if (masterShape != null) {
                        ok = visitor.fetch(masterShape);
                    }
                }
            }
        }
        return ok;
    }

    /**
     * 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
     */
    protected static PaintStyle selectPaint(XSLFFillProperties fp, final CTSchemeColor phClr, final PackagePart parentPart, final XSLFTheme theme) {
        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);
        } else if (fp.isSetGradFill()) {
            return selectPaint(fp.getGradFill(), phClr, theme);
        } else if (fp.isSetMatrixStyle()) {
            return selectPaint(fp.getMatrixStyle(), theme, fp.isLineStyle());
        } else {
            return null;
        }
    }

    protected static PaintStyle selectPaint(CTSolidColorFillProperties solidFill, CTSchemeColor phClr, final XSLFTheme theme) {
        if (phClr == null && solidFill.isSetSchemeClr()) {
            phClr = solidFill.getSchemeClr();
        }
        final XSLFColor c = new XSLFColor(solidFill, theme, phClr);
        return DrawPaint.createSolidPaint(c.getColorStyle());
    }
    
    protected static PaintStyle selectPaint(final CTBlipFillProperties blipFill, final PackagePart parentPart) {
        final CTBlip blip = blipFill.getBlip();
        return new TexturePaint() {
            private PackagePart getPart() {
                try {
                    String blipId = blip.getEmbed();
                    PackageRelationship rel = parentPart.getRelationship(blipId);
                    return parentPart.getRelatedPart(rel);
                } catch (InvalidFormatException e) {
                    throw new RuntimeException(e);
                }
            }
            
            public InputStream getImageData() {
                try {
                    return getPart().getInputStream();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }

            public String getContentType() {
                /* TOOD: map content-type */
                return getPart().getContentType();
            }

            public int getAlpha() {
                return (blip.sizeOfAlphaModFixArray() > 0)
                    ? blip.getAlphaModFixArray(0).getAmt()
                    : 100000;
            }
        };        
    }
    
    protected static PaintStyle selectPaint(final CTGradientFillProperties gradFill, CTSchemeColor phClr, final XSLFTheme theme) {

        final CTGradientStop[] gs = gradFill.getGsLst().getGsArray();

        Arrays.sort(gs, new Comparator<CTGradientStop>() {
            public int compare(CTGradientStop o1, CTGradientStop o2) {
                Integer pos1 = o1.getPos();
                Integer pos2 = o2.getPos();
                return pos1.compareTo(pos2);
            }
        });

        final ColorStyle cs[] = new ColorStyle[gs.length];
        final float fractions[] = new float[gs.length];
        
        int i=0;
        for (CTGradientStop cgs : gs) {
            CTSchemeColor phClrCgs = phClr;
            if (phClrCgs == null && cgs.isSetSchemeClr()) {
                phClrCgs = cgs.getSchemeClr();
            }
            cs[i] = new XSLFColor(cgs, theme, phClrCgs).getColorStyle();
            fractions[i] = cgs.getPos() / 100000.f;
            i++;
        }
        
        return new GradientPaint() {

            public double getGradientAngle() {
                return (gradFill.isSetLin())
                    ? gradFill.getLin().getAng() / 60000.d
                    : 0;
            }

            public ColorStyle[] getGradientColors() {
                return cs;
            }

            public float[] getGradientFractions() {
                return fractions;
            }

            public boolean isRotatedWithShape() {
                // TODO: is this correct???
                return (gradFill.isSetRotWithShape() || !gradFill.getRotWithShape());
            }

            public GradientType getGradientType() {
                if (gradFill.isSetLin()) {
                    return GradientType.linear;
                }
                
                if (gradFill.isSetPath()) {
                    /* TODO: handle rect path */
                    STPathShadeType.Enum ps = gradFill.getPath().getPath();
                    if (ps == STPathShadeType.CIRCLE) {
                        return GradientType.circular;
                    } else if (ps == STPathShadeType.SHAPE) {
                        return GradientType.shape;
                    }
                }
                
                return GradientType.linear;
            }
        };        
    }
    
    protected static PaintStyle selectPaint(CTStyleMatrixReference fillRef, final XSLFTheme theme, boolean isLineStyle) {
        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.
        int idx = (int)fillRef.getIdx();
        CTSchemeColor phClr = fillRef.getSchemeClr();
        CTStyleMatrix matrix = theme.getXmlObject().getThemeElements().getFmtScheme();
        final XmlObject styleLst;
        int 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(childIdx)) {
            fp = XSLFPropertiesDelegate.getFillDelegate(cur.getObject());
        }
        cur.dispose();
        
        return selectPaint(fp, phClr, theme.getPackagePart(), theme);
    }
    
    @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");
    }
}