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

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Stroke;
import java.awt.geom.AffineTransform;
import java.awt.geom.Path2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map.Entry;

import org.apache.poi.POIXMLException;
import org.apache.poi.util.Internal;
import org.apache.poi.xdgf.exceptions.XDGFException;
import org.apache.poi.xdgf.usermodel.section.CombinedIterable;
import org.apache.poi.xdgf.usermodel.section.GeometrySection;
import org.apache.poi.xdgf.usermodel.section.XDGFSection;
import org.apache.poi.xdgf.usermodel.shape.ShapeVisitor;
import org.apache.poi.xdgf.usermodel.shape.exceptions.StopVisitingThisBranch;

import com.microsoft.schemas.office.visio.x2012.main.ShapeSheetType;
import com.microsoft.schemas.office.visio.x2012.main.TextType;

/**
 * A shape is a collection of Geometry Visualization, Format, Text, Images, and
 * Shape Data in a Drawing Page.
 */
public class XDGFShape extends XDGFSheet {

    XDGFBaseContents _parentPage;
    XDGFShape _parent; // only non-null if a subshape

    XDGFMaster _master = null;
    XDGFShape _masterShape = null;

    XDGFText _text = null;

    // subshapes if they exist
    List<XDGFShape> _shapes = null;

    // properties specific to shapes

    // center of rotation relative to origin of parent
    Double _pinX = null;
    Double _pinY = null;

    Double _width = null;
    Double _height = null;

    // center of rotation relative to self
    Double _locPinX = null;
    Double _locPinY = null;

    // start x coordinate, relative to parent
    // -> one dimensional shapes only
    Double _beginX = null;
    Double _beginY = null;

    // end x coordinate, relative to parent
    // -> one dimensional shapes only
    Double _endX = null;
    Double _endY = null;

    Double _angle = null;
    Double _rotationXAngle = null;
    Double _rotationYAngle = null;
    Double _rotationZAngle = null;

    // end x coordinate, relative to parent
    Boolean _flipX = null;
    Boolean _flipY = null;

    // center of text relative to this shape
    Double _txtPinX = null;
    Double _txtPinY = null;

    // center of text relative to text block
    Double _txtLocPinX = null;
    Double _txtLocPinY = null;

    Double _txtAngle = null;

    Double _txtWidth = null;
    Double _txtHeight = null;

    public XDGFShape(ShapeSheetType shapeSheet, XDGFBaseContents parentPage,
            XDGFDocument document) {
        this(null, shapeSheet, parentPage, document);
    }

    public XDGFShape(XDGFShape parent, ShapeSheetType shapeSheet,
            XDGFBaseContents parentPage, XDGFDocument document) {

        super(shapeSheet, document);

        _parent = parent;
        _parentPage = parentPage;

        TextType text = shapeSheet.getText();
        if (text != null)
            _text = new XDGFText(text, this);

        if (shapeSheet.isSetShapes()) {
            _shapes = new ArrayList<XDGFShape>();
            for (ShapeSheetType shape : shapeSheet.getShapes().getShapeArray())
                _shapes.add(new XDGFShape(this, shape, parentPage, document));
        }

        readProperties();
    }

    @Override
    public String toString() {
        if (_parentPage instanceof XDGFMasterContents)
            return _parentPage + ": <Shape ID=\"" + getID() + "\">";
        else
            return "<Shape ID=\"" + getID() + "\">";
    }

    protected void readProperties() {

        _pinX = XDGFCell.maybeGetDouble(_cells, "PinX");
        _pinY = XDGFCell.maybeGetDouble(_cells, "PinY");
        _width = XDGFCell.maybeGetDouble(_cells, "Width");
        _height = XDGFCell.maybeGetDouble(_cells, "Height");
        _locPinX = XDGFCell.maybeGetDouble(_cells, "LocPinX");
        _locPinY = XDGFCell.maybeGetDouble(_cells, "LocPinY");
        _beginX = XDGFCell.maybeGetDouble(_cells, "BeginX");
        _beginY = XDGFCell.maybeGetDouble(_cells, "BeginY");
        _endX = XDGFCell.maybeGetDouble(_cells, "EndX");
        _endY = XDGFCell.maybeGetDouble(_cells, "EndY");

        _angle = XDGFCell.maybeGetDouble(_cells, "Angle");
        _rotationXAngle = XDGFCell.maybeGetDouble(_cells, "RotationXAngle");
        _rotationYAngle = XDGFCell.maybeGetDouble(_cells, "RotationYAngle");
        _rotationZAngle = XDGFCell.maybeGetDouble(_cells, "RotationZAngle");

        _flipX = XDGFCell.maybeGetBoolean(_cells, "FlipX");
        _flipY = XDGFCell.maybeGetBoolean(_cells, "FlipY");

        _txtPinX = XDGFCell.maybeGetDouble(_cells, "TxtPinX");
        _txtPinY = XDGFCell.maybeGetDouble(_cells, "TxtPinY");
        _txtLocPinX = XDGFCell.maybeGetDouble(_cells, "TxtLocPinX");
        _txtLocPinY = XDGFCell.maybeGetDouble(_cells, "TxtLocPinY");
        _txtWidth = XDGFCell.maybeGetDouble(_cells, "TxtWidth");
        _txtHeight = XDGFCell.maybeGetDouble(_cells, "TxtHeight");

        _txtAngle = XDGFCell.maybeGetDouble(_cells, "TxtAngle");
    }

    /**
     * Setup top level shapes
     *
     * Shapes that have a 'Master' attribute refer to a specific master in the
     * page, whereas shapes with a 'MasterShape' attribute refer to a subshape
     * of a Master.
     */
    protected void setupMaster(XDGFPageContents pageContents,
            XDGFMasterContents master) {

        ShapeSheetType obj = getXmlObject();

        if (obj.isSetMaster()) {
            _master = pageContents.getMasterById(obj.getMaster());
            if (_master == null)
                throw XDGFException.error("refers to non-existant master "
                        + obj.getMaster(), this);

            /*
             * If a master has one top-level shape, a shape that inherits from
             * that master inherits the descendant elements of that master
             * shape. If a master has more than one master shape, a shape that
             * inherits from that master inherits those master shapes as
             * subshapes.
             */

            Collection<XDGFShape> masterShapes = _master.getContent()
                    .getTopLevelShapes();

            switch (masterShapes.size()) {
            case 0:
                throw XDGFException
                .error("Could not retrieve master shape from "
                        + _master, this);
            case 1:
                _masterShape = masterShapes.iterator().next();
                break;
            default:
                break;
            }

        } else if (obj.isSetMasterShape()) {
            _masterShape = master.getShapeById(obj.getMasterShape());
            if (_masterShape == null)
                throw XDGFException.error(
                        "refers to non-existant master shape "
                                + obj.getMasterShape(), this);

        }

        setupSectionMasters();

        if (_shapes != null) {
            for (XDGFShape shape : _shapes) {
                shape.setupMaster(pageContents, _master == null ? master
                        : _master.getContent());
            }
        }
    }

    protected void setupSectionMasters() {

        if (_masterShape == null)
            return;

        try {
            for (Entry<String, XDGFSection> section : _sections.entrySet()) {
                XDGFSection master = _masterShape.getSection(section.getKey());
                if (master != null)
                    section.getValue().setupMaster(master);
            }

            for (Entry<Long, GeometrySection> section : _geometry.entrySet()) {
                GeometrySection master = _masterShape.getGeometryByIdx(section
                        .getKey());
                if (master != null)
                    section.getValue().setupMaster(master);
            }
        } catch (POIXMLException e) {
            throw XDGFException.wrap(this.toString(), e);
        }
    }

    @Override
    @Internal
    public ShapeSheetType getXmlObject() {
        return (ShapeSheetType) _sheet;
    }

    public long getID() {
        return getXmlObject().getID();
    }

    public String getType() {
        return getXmlObject().getType();
    }

    public String getTextAsString() {
        XDGFText text = getText();
        if (text == null)
            return "";

        return text.getTextContent();
    }

    public boolean hasText() {
        return _text != null
                || (_masterShape != null && _masterShape._text != null);
    }

    @Override
    public XDGFCell getCell(String cellName) {
        XDGFCell _cell = super.getCell(cellName);

        // if not found, ask the master
        if (_cell == null && _masterShape != null) {
            _cell = _masterShape.getCell(cellName);
        }

        return _cell;
    }

    public GeometrySection getGeometryByIdx(long idx) {
        return _geometry.get(idx);
    }

    /**
     * Only available if this shape is a shape group, may be null 
     */
    // -> May be null
    public List<XDGFShape> getShapes() {
        return _shapes;
    }

    // unique to this shape on the page?
    public String getName() {
        String name = getXmlObject().getName();
        if (name == null)
            return "";
        return name;
    }

    // unique to this shape on the page?
    public String getShapeType() {
        String type = getXmlObject().getType();
        if (type == null)
            return "";
        return type;
    }

    // name of the symbol that this was derived from
    public String getSymbolName() {

        if (_master == null)
            return "";

        String name = _master.getName();
        if (name == null)
            return "";

        return name;
    }

    public XDGFShape getMasterShape() {
        return _masterShape;
    }

    /**
     * @return The parent shape if this is a subshape, null otherwise
     */
    public XDGFShape getParentShape() {
        return _parent;
    }

    public XDGFShape getTopmostParentShape() {
        XDGFShape top = null;
        if (_parent != null) {
            top = _parent.getTopmostParentShape();
            if (top == null)
                top = _parent;
        }

        return top;
    }

    public boolean hasMaster() {
        return _master != null;
    }

    public boolean hasMasterShape() {
        return _masterShape != null;
    }

    public boolean hasParent() {
        return _parent != null;
    }

    public boolean hasShapes() {
        return _shapes != null;
    }

    public boolean isTopmost() {
        return _parent == null;
    }

    public boolean isShape1D() {
        return getBeginX() != null;
    }

    public boolean isDeleted() {
        return getXmlObject().isSetDel() ? getXmlObject().getDel() : false;
    }

    public XDGFText getText() {
        if (_text == null && _masterShape != null)
            return _masterShape.getText();

        return _text;
    }

    public Double getPinX() {
        if (_pinX == null && _masterShape != null)
            return _masterShape.getPinX();

        if (_pinX == null)
            throw XDGFException.error("PinX not set!", this);

        return _pinX;
    }

    public Double getPinY() {
        if (_pinY == null && _masterShape != null)
            return _masterShape.getPinY();

        if (_pinY == null)
            throw XDGFException.error("PinY not specified!", this);

        return _pinY;
    }

    public Double getWidth() {
        if (_width == null && _masterShape != null)
            return _masterShape.getWidth();

        if (_width == null)
            throw XDGFException.error("Width not specified!", this);

        return _width;
    }

    public Double getHeight() {
        if (_height == null && _masterShape != null)
            return _masterShape.getHeight();

        if (_height == null)
            throw XDGFException.error("Height not specified!", this);

        return _height;
    }

    public Double getLocPinX() {
        if (_locPinX == null && _masterShape != null)
            return _masterShape.getLocPinX();

        if (_locPinX == null)
            throw XDGFException.error("LocPinX not specified!", this);

        return _locPinX;
    }

    public Double getLocPinY() {
        if (_locPinY == null && _masterShape != null)
            return _masterShape.getLocPinY();

        if (_locPinY == null)
            throw XDGFException.error("LocPinY not specified!", this);

        return _locPinY;
    }

    public Double getBeginX() {
        if (_beginX == null && _masterShape != null)
            return _masterShape.getBeginX();

        return _beginX;
    }

    public Double getBeginY() {
        if (_beginY == null && _masterShape != null)
            return _masterShape.getBeginY();

        return _beginY;
    }

    public Double getEndX() {
        if (_endX == null && _masterShape != null)
            return _masterShape.getEndX();

        return _endX;
    }

    public Double getEndY() {
        if (_endY == null && _masterShape != null)
            return _masterShape.getEndY();

        return _endY;
    }

    public Double getAngle() {
        if (_angle == null && _masterShape != null)
            return _masterShape.getAngle();

        return _angle;
    }

    public Boolean getFlipX() {
        if (_flipX == null && _masterShape != null)
            return _masterShape.getFlipX();

        return _flipX;
    }

    public Boolean getFlipY() {
        if (_flipY == null && _masterShape != null)
            return _masterShape.getFlipY();

        return _flipY;
    }

    public Double getTxtPinX() {
        if (_txtPinX == null && _masterShape != null
                && _masterShape._txtPinX != null)
            return _masterShape._txtPinX;

        if (_txtPinX == null)
            return getWidth() * 0.5;

        return _txtPinX;
    }

    public Double getTxtPinY() {
        if (_txtLocPinY == null && _masterShape != null
                && _masterShape._txtLocPinY != null)
            return _masterShape._txtLocPinY;

        if (_txtPinY == null)
            return getHeight() * 0.5;

        return _txtPinY;
    }

    public Double getTxtLocPinX() {
        if (_txtLocPinX == null && _masterShape != null
                && _masterShape._txtLocPinX != null)
            return _masterShape._txtLocPinX;

        if (_txtLocPinX == null)
            return getTxtWidth() * 0.5;

        return _txtLocPinX;
    }

    public Double getTxtLocPinY() {
        if (_txtLocPinY == null && _masterShape != null
                && _masterShape._txtLocPinY != null)
            return _masterShape._txtLocPinY;

        if (_txtLocPinY == null)
            return getTxtHeight() * 0.5;

        return _txtLocPinY;
    }

    public Double getTxtAngle() {
        if (_txtAngle == null && _masterShape != null)
            return _masterShape.getTxtAngle();

        return _txtAngle;
    }

    public Double getTxtWidth() {
        if (_txtWidth == null && _masterShape != null
                && _masterShape._txtWidth != null)
            return _masterShape._txtWidth;

        if (_txtWidth == null)
            return getWidth();

        return _txtWidth;
    }

    public Double getTxtHeight() {
        if (_txtHeight == null && _masterShape != null
                && _masterShape._txtHeight != null)
            return _masterShape._txtHeight;

        if (_txtHeight == null)
            return getHeight();

        return _txtHeight;
    }

    @Override
    public Integer getLineCap() {

        Integer lineCap = super.getLineCap();
        if (lineCap != null)
            return lineCap;

        // get from master
        if (_masterShape != null) {
            return _masterShape.getLineCap();
        }

        // get default
        return _document.getDefaultLineStyle().getLineCap();
    }

    @Override
    public Color getLineColor() {

        Color lineColor = super.getLineColor();
        if (lineColor != null)
            return lineColor;

        // get from master
        if (_masterShape != null) {
            return _masterShape.getLineColor();
        }

        // get default
        return _document.getDefaultLineStyle().getLineColor();
    }

    @Override
    public Integer getLinePattern() {

        Integer linePattern = super.getLinePattern();
        if (linePattern != null)
            return linePattern;

        // get from master
        if (_masterShape != null) {
            return _masterShape.getLinePattern();
        }

        // get default
        return _document.getDefaultLineStyle().getLinePattern();
    }

    @Override
    public Double getLineWeight() {

        Double lineWeight = super.getLineWeight();
        if (lineWeight != null)
            return lineWeight;

        // get from master
        if (_masterShape != null) {
            return _masterShape.getLineWeight();
        }

        // get default
        return _document.getDefaultLineStyle().getLineWeight();
    }

    @Override
    public Color getFontColor() {

        Color fontColor = super.getFontColor();
        if (fontColor != null)
            return fontColor;

        // get from master
        if (_masterShape != null) {
            return _masterShape.getFontColor();
        }

        // get default
        return _document.getDefaultTextStyle().getFontColor();
    }

    @Override
    public Double getFontSize() {

        Double fontSize = super.getFontSize();
        if (fontSize != null)
            return fontSize;

        // get from master
        if (_masterShape != null) {
            return _masterShape.getFontSize();
        }

        // get default
        return _document.getDefaultTextStyle().getFontSize();
    }

    public Stroke getStroke() {

        float lineWeight = getLineWeight().floatValue();
        int cap;
        int join = BasicStroke.JOIN_MITER;
        float miterlimit = 10.0f;

        switch (getLineCap()) {
        case 0:
            cap = BasicStroke.CAP_ROUND;
            break;
        case 1:
            cap = BasicStroke.CAP_SQUARE;
            break;
        case 2:
            cap = BasicStroke.CAP_BUTT; // TODO: what does extended mean?
            break;
        default:
            throw new POIXMLException("Invalid line cap specified");
        }

        float[] dash = null;

        // these line patterns are just approximations
        switch (getLinePattern()) {
        case 0: // transparent
            break;
        case 1: // solid
            break;
        case 2:
            dash = new float[] { 5, 3 };
            break;
        case 3:
            dash = new float[] { 1, 4 };
            break;
        case 4:
            dash = new float[] { 6, 3, 1, 3 };
            break;
        case 5:
            dash = new float[] { 6, 3, 1, 3, 1, 3 };
            break;
        case 6:
            dash = new float[] { 1, 3, 6, 3, 6, 3 };
            break;
        case 7:
            dash = new float[] { 15, 3, 6, 3 };
            break;
        case 8:
            dash = new float[] { 6, 3, 6, 3 };
            break;
        case 9:
            dash = new float[] { 3, 2 };
            break;
        case 10:
            dash = new float[] { 1, 2 };
            break;
        case 11:
            dash = new float[] { 3, 2, 1, 2 };
            break;
        case 12:
            dash = new float[] { 3, 2, 1, 2, 1 };
            break;
        case 13:
            dash = new float[] { 1, 2, 3, 2, 3, 2 };
            break;
        case 14:
            dash = new float[] { 3, 2, 7, 2 };
            break;
        case 15:
            dash = new float[] { 7, 2, 3, 2, 3, 2 };
            break;
        case 16:
            dash = new float[] { 12, 6 };
            break;
        case 17:
            dash = new float[] { 1, 6 };
            break;
        case 18:
            dash = new float[] { 1, 6, 12, 6 };
            break;
        case 19:
            dash = new float[] { 1, 6, 1, 6, 12, 6 };
            break;
        case 20:
            dash = new float[] { 1, 6, 12, 6, 12, 6 };
            break;
        case 21:
            dash = new float[] { 30, 6, 12, 6 };
            break;
        case 22:
            dash = new float[] { 30, 6, 12, 6, 12, 6 };
            break;
        case 23:
            dash = new float[] { 1 };
            break;
        case 254:
            throw new POIXMLException("Unsupported line pattern value");
        default:
            throw new POIXMLException("Invalid line pattern value");
        }

        // dashes are in units of line width
        if (dash != null) {
            for (int i = 0; i < dash.length; i++) {
                dash[i] *= lineWeight;
            }
        }

        return new BasicStroke(lineWeight, cap, join, miterlimit, dash, 0);
    }

    //
    // Geometry
    //

    public Iterable<GeometrySection> getGeometrySections() {
        return new CombinedIterable<GeometrySection>(_geometry,
                _masterShape != null ? _masterShape._geometry : null);
    }

    /**
     * @return rectangle in local coordinates
     */
    public Rectangle2D.Double getBounds() {
        return new Rectangle2D.Double(0, 0, getWidth(), getHeight());
    }
    
    /**
     * @return returns bounds as a path in local coordinates, which is
     *         userful if you need to transform to global coordinates
     *         
     * Warning: Don't use this for 1d objects, and will fail for
     *          infinite line objects
     */
    public Path2D.Double getBoundsAsPath() {

        Double w = getWidth();
        Double h = getHeight();

        Path2D.Double bounds = new Path2D.Double();
        bounds.moveTo(0, 0);
        bounds.lineTo(w, 0);
        bounds.lineTo(w, h);
        bounds.lineTo(0, h);
        bounds.lineTo(0, 0);

        return bounds;
    }

    /**
     * @return The outline of the shape in local coordinates
     */
    public Path2D.Double getPath() {
        for (GeometrySection geoSection : getGeometrySections()) {
            if (geoSection.getNoShow() == true)
                continue;

            return geoSection.getPath(this);
        }

        return null;
    }

    /*
     * Returns true if the shape has a drawable geometry associated with it
     */
    public boolean hasGeometry() {
        for (GeometrySection geoSection : getGeometrySections()) {
            if (geoSection.getNoShow() == false)
                return true;
        }
        return false;
    }

    /**
     * Returns a transform that can translate shape-local coordinates to the
     * coordinates of its parent shape
     */
    protected AffineTransform getParentTransform() {
        // TODO: There's probably a better way to do this
        AffineTransform tr = new AffineTransform();

        Double locX = getLocPinX();
        Double locY = getLocPinY();
        Boolean flipX = getFlipX();
        Boolean flipY = getFlipY();
        Double angle = getAngle();

        tr.translate(-locX, -locY);

        tr.translate(getPinX(), getPinY());

        // rotate about the origin
        if (angle != null && Math.abs(angle) > 0.001) {
            tr.rotate(angle, locX, locY);
        }

        // flip if necessary

        if (flipX != null && flipX) {
            tr.scale(-1, 1);
            tr.translate(-getWidth(), 0);
        }

        if (flipY != null && flipY) {
            tr.scale(1, -1);
            tr.translate(0, -getHeight());
        }

        return tr;
    }

    /**
     * The visitor will first visit this shape, then it's children
     *
     * This is useful because exceptions will be marked with the shapes as it
     * propagates up the shape hierarchy.
     */
    public void visitShapes(ShapeVisitor visitor, AffineTransform tr, int level) {

        tr = (AffineTransform) tr.clone();
        tr.concatenate(getParentTransform());

        try {
            if (visitor.accept(this))
                visitor.visit(this, tr, level);

            if (_shapes != null) {
                for (XDGFShape shape : _shapes) {
                    shape.visitShapes(visitor, tr, level + 1);
                }
            }
        } catch (StopVisitingThisBranch e) {
            // intentionally empty
        } catch (POIXMLException e) {
            throw XDGFException.wrap(this.toString(), e);
        }
    }

    /**
     * The visitor will first visit this shape, then it's children. No transform
     * is calculated for this visit
     *
     * This is useful because exceptions will be marked with the shapes as it
     * propagates up the shape hierarchy.
     */
    public void visitShapes(ShapeVisitor visitor, int level) {

        try {
            if (visitor.accept(this))
                visitor.visit(this, null, level);

            if (_shapes != null) {
                for (XDGFShape shape : _shapes) {
                    shape.visitShapes(visitor, level + 1);
                }
            }
        } catch (StopVisitingThisBranch e) {
            // intentionally empty
        } catch (POIXMLException e) {
            throw XDGFException.wrap(this.toString(), e);
        }
    }

}
