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

import static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.xml.namespace.QName;

import org.apache.poi.POIXMLDocument;
import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.POIXMLException;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackagePartName;
import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.openxml4j.opc.PackageRelationshipTypes;
import org.apache.poi.openxml4j.opc.PackagingURIHelper;
import org.apache.poi.openxml4j.opc.TargetMode;
import org.apache.poi.ss.usermodel.ClientAnchor;
import org.apache.poi.ss.usermodel.Drawing;
import org.apache.poi.ss.util.CellAddress;
import org.apache.poi.ss.util.ImageUtils;
import org.apache.poi.util.Internal;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import org.apache.poi.util.Units;
import org.apache.poi.xssf.model.CommentsTable;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlOptions;
import org.apache.xmlbeans.impl.values.XmlAnyTypeImpl;
import org.openxmlformats.schemas.drawingml.x2006.main.CTBlipFillProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTGroupTransform2D;
import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D;
import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTConnector;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTDrawing;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTGraphicalObjectFrame;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTGroupShape;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTMarker;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTOneCellAnchor;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTPicture;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTShape;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTTwoCellAnchor;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.STEditAs;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTOleObject;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTOleObjects;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet;

/**
 * Represents a SpreadsheetML drawing
 */
public final class XSSFDrawing extends POIXMLDocumentPart implements Drawing<XSSFShape> {
    private static final POILogger LOG = POILogFactory.getLogger(XSSFDrawing.class);

    /**
     * Root element of the SpreadsheetML Drawing part
     */
    private CTDrawing drawing;
    private long numOfGraphicFrames = 0L;

    protected static final String NAMESPACE_A = XSSFRelation.NS_DRAWINGML;
    protected static final String NAMESPACE_C = XSSFRelation.NS_CHART;

    /**
     * Create a new SpreadsheetML drawing
     *
     * @see org.apache.poi.xssf.usermodel.XSSFSheet#createDrawingPatriarch()
     */
    protected XSSFDrawing() {
        super();
        drawing = newDrawing();
    }

    /**
     * Construct a SpreadsheetML drawing from a package part
     *
     * @param part the package part holding the drawing data,
     * the content type must be <code>application/vnd.openxmlformats-officedocument.drawing+xml</code>
     *
     * @since POI 3.14-Beta1
     */
    public XSSFDrawing(PackagePart part) throws IOException, XmlException {
        super(part);
        XmlOptions options  = new XmlOptions(DEFAULT_XML_OPTIONS);
        //Removing root element
        options.setLoadReplaceDocumentElement(null);
        InputStream is = part.getInputStream();
        try {
            drawing = CTDrawing.Factory.parse(is,options);
        } finally {
            is.close();
        }
    }

    /**
     * Construct a new CTDrawing bean. By default, it's just an empty placeholder for drawing objects
     *
     * @return a new CTDrawing bean
     */
    private static CTDrawing newDrawing(){
        return CTDrawing.Factory.newInstance();
    }

    /**
     * Return the underlying CTDrawing bean, the root element of the SpreadsheetML Drawing part.
     *
     * @return the underlying CTDrawing bean
     */
    @Internal
    public CTDrawing getCTDrawing(){
        return drawing;
    }

    @Override
    protected void commit() throws IOException {
        XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS);

        /*
            Saved drawings must have the following namespaces set:
            <xdr:wsDr
                xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
                xmlns:xdr="http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing">
        */
        xmlOptions.setSaveSyntheticDocumentElement(
                new QName(CTDrawing.type.getName().getNamespaceURI(), "wsDr", "xdr")
        );

        PackagePart part = getPackagePart();
        OutputStream out = part.getOutputStream();
        drawing.save(out, xmlOptions);
        out.close();
    }

	@Override
    public XSSFClientAnchor createAnchor(int dx1, int dy1, int dx2, int dy2,
			int col1, int row1, int col2, int row2) {
		return new XSSFClientAnchor(dx1, dy1, dx2, dy2, col1, row1, col2, row2);
	}

    /**
     * Constructs a textbox under the drawing.
     *
     * @param anchor    the client anchor describes how this group is attached
     *                  to the sheet.
     * @return      the newly created textbox.
     */
    public XSSFTextBox createTextbox(XSSFClientAnchor anchor){
        long shapeId = newShapeId();
        CTTwoCellAnchor ctAnchor = createTwoCellAnchor(anchor);
        CTShape ctShape = ctAnchor.addNewSp();
        ctShape.set(XSSFSimpleShape.prototype());
        ctShape.getNvSpPr().getCNvPr().setId(shapeId);
        XSSFTextBox shape = new XSSFTextBox(this, ctShape);
        shape.anchor = anchor;
        return shape;

    }

    /**
     * Creates a picture.
     *
     * @param anchor    the client anchor describes how this picture is attached to the sheet.
     * @param pictureIndex the index of the picture in the workbook collection of pictures,
     *   {@link org.apache.poi.xssf.usermodel.XSSFWorkbook#getAllPictures()} .
     *
     * @return  the newly created picture shape.
     */
    public XSSFPicture createPicture(XSSFClientAnchor anchor, int pictureIndex)
    {
        PackageRelationship rel = addPictureReference(pictureIndex);

        long shapeId = newShapeId();
        CTTwoCellAnchor ctAnchor = createTwoCellAnchor(anchor);
        CTPicture ctShape = ctAnchor.addNewPic();
        ctShape.set(XSSFPicture.prototype());

        ctShape.getNvPicPr().getCNvPr().setId(shapeId);

        XSSFPicture shape = new XSSFPicture(this, ctShape);
        shape.anchor = anchor;
        shape.setPictureReference(rel);
        ctShape.getSpPr().setXfrm(createXfrm(anchor));

        return shape;
    }

    @Override
    public XSSFPicture createPicture(ClientAnchor anchor, int pictureIndex){
        return createPicture((XSSFClientAnchor)anchor, pictureIndex);
    }

	/**
	 * Creates a chart.
	 * @param anchor the client anchor describes how this chart is attached to
	 *               the sheet.
	 * @return the newly created chart
	 * @see org.apache.poi.xssf.usermodel.XSSFDrawing#createChart(ClientAnchor)
	 */
    public XSSFChart createChart(XSSFClientAnchor anchor) {
        int chartNumber = getPackagePart().getPackage().
            getPartsByContentType(XSSFRelation.CHART.getContentType()).size() + 1;

        RelationPart rp = createRelationship(
            XSSFRelation.CHART, XSSFFactory.getInstance(), chartNumber, false);
        XSSFChart chart = rp.getDocumentPart();
        String chartRelId = rp.getRelationship().getId();

        XSSFGraphicFrame frame = createGraphicFrame(anchor);
        frame.setChart(chart, chartRelId);
        frame.getCTGraphicalObjectFrame().setXfrm(createXfrm(anchor));

        return chart;
    }

	@Override
    public XSSFChart createChart(ClientAnchor anchor) {
		return createChart((XSSFClientAnchor)anchor);
	}

    /**
     * Add the indexed picture to this drawing relations
     *
     * @param pictureIndex the index of the picture in the workbook collection of pictures,
     *   {@link org.apache.poi.xssf.usermodel.XSSFWorkbook#getAllPictures()} .
     */
    @SuppressWarnings("resource")
    protected PackageRelationship addPictureReference(int pictureIndex){
        XSSFWorkbook wb = (XSSFWorkbook)getParent().getParent();
        XSSFPictureData data = wb.getAllPictures().get(pictureIndex);
        XSSFPictureData pic = new XSSFPictureData(data.getPackagePart());
        RelationPart rp = addRelation(null, XSSFRelation.IMAGES, pic);
        return rp.getRelationship();
    }

    /**
     * Creates a simple shape.  This includes such shapes as lines, rectangles,
     * and ovals.
     *
     * @param anchor    the client anchor describes how this group is attached
     *                  to the sheet.
     * @return  the newly created shape.
     */
    public XSSFSimpleShape createSimpleShape(XSSFClientAnchor anchor)
    {
        long shapeId = newShapeId();
        CTTwoCellAnchor ctAnchor = createTwoCellAnchor(anchor);
        CTShape ctShape = ctAnchor.addNewSp();
        ctShape.set(XSSFSimpleShape.prototype());
        ctShape.getNvSpPr().getCNvPr().setId(shapeId);
        ctShape.getSpPr().setXfrm(createXfrm(anchor));
        XSSFSimpleShape shape = new XSSFSimpleShape(this, ctShape);
        shape.anchor = anchor;
        return shape;
    }

    /**
     * Creates a simple shape.  This includes such shapes as lines, rectangles,
     * and ovals.
     *
     * @param anchor    the client anchor describes how this group is attached
     *                  to the sheet.
     * @return  the newly created shape.
     */
    public XSSFConnector createConnector(XSSFClientAnchor anchor)
    {
        CTTwoCellAnchor ctAnchor = createTwoCellAnchor(anchor);
        CTConnector ctShape = ctAnchor.addNewCxnSp();
        ctShape.set(XSSFConnector.prototype());

        XSSFConnector shape = new XSSFConnector(this, ctShape);
        shape.anchor = anchor;
        return shape;
    }

    /**
     * Creates a simple shape.  This includes such shapes as lines, rectangles,
     * and ovals.
     *
     * @param anchor    the client anchor describes how this group is attached
     *                  to the sheet.
     * @return  the newly created shape.
     */
    public XSSFShapeGroup createGroup(XSSFClientAnchor anchor)
    {
        CTTwoCellAnchor ctAnchor = createTwoCellAnchor(anchor);
        CTGroupShape ctGroup = ctAnchor.addNewGrpSp();
        ctGroup.set(XSSFShapeGroup.prototype());
        CTTransform2D xfrm = createXfrm(anchor);
        CTGroupTransform2D grpXfrm =ctGroup.getGrpSpPr().getXfrm();
        grpXfrm.setOff(xfrm.getOff());
        grpXfrm.setExt(xfrm.getExt());
        grpXfrm.setChExt(xfrm.getExt());

        XSSFShapeGroup shape = new XSSFShapeGroup(this, ctGroup);
        shape.anchor = anchor;
        return shape;
    }

	/**
	 * Creates a comment.
	 * @param anchor the client anchor describes how this comment is attached
	 *               to the sheet.
	 * @return the newly created comment.
	 */
    @Override
    public XSSFComment createCellComment(ClientAnchor anchor) {
        XSSFClientAnchor ca = (XSSFClientAnchor)anchor;
        XSSFSheet sheet = getSheet();

        //create comments and vmlDrawing parts if they don't exist
        CommentsTable comments = sheet.getCommentsTable(true);
        XSSFVMLDrawing vml = sheet.getVMLDrawing(true);
        com.microsoft.schemas.vml.CTShape vmlShape = vml.newCommentShape();
        if(ca.isSet()){
            // convert offsets from emus to pixels since we get a DrawingML-anchor
            // but create a VML Drawing
            int dx1Pixels = ca.getDx1()/Units.EMU_PER_PIXEL;
            int dy1Pixels = ca.getDy1()/Units.EMU_PER_PIXEL;
            int dx2Pixels = ca.getDx2()/Units.EMU_PER_PIXEL;
            int dy2Pixels = ca.getDy2()/Units.EMU_PER_PIXEL;
            String position =
                    ca.getCol1() + ", " + dx1Pixels + ", " +
                    ca.getRow1() + ", " + dy1Pixels + ", " +
                    ca.getCol2() + ", " + dx2Pixels + ", " +
                    ca.getRow2() + ", " + dy2Pixels;
            vmlShape.getClientDataArray(0).setAnchorArray(0, position);
        }
        CellAddress ref = new CellAddress(ca.getRow1(), ca.getCol1());

        if(comments.findCellComment(ref) != null) {
            throw new IllegalArgumentException("Multiple cell comments in one cell are not allowed, cell: " + ref);
        }

        return new XSSFComment(comments, comments.newComment(ref), vmlShape);
    }

    /**
     * Creates a new graphic frame.
     *
     * @param anchor    the client anchor describes how this frame is attached
     *                  to the sheet
     * @return  the newly created graphic frame
     */
    private XSSFGraphicFrame createGraphicFrame(XSSFClientAnchor anchor) {
        CTTwoCellAnchor ctAnchor = createTwoCellAnchor(anchor);
        CTGraphicalObjectFrame ctGraphicFrame = ctAnchor.addNewGraphicFrame();
        ctGraphicFrame.set(XSSFGraphicFrame.prototype());
        ctGraphicFrame.setXfrm(createXfrm(anchor));

        long frameId = numOfGraphicFrames++;
        XSSFGraphicFrame graphicFrame = new XSSFGraphicFrame(this, ctGraphicFrame);
        graphicFrame.setAnchor(anchor);
        graphicFrame.setId(frameId);
        graphicFrame.setName("Diagramm" + frameId);
        return graphicFrame;
    }

    @Override
    public XSSFObjectData createObjectData(ClientAnchor anchor, int storageId, int pictureIndex) {
        XSSFSheet sh = getSheet();
        PackagePart sheetPart = sh.getPackagePart();
        long shapeId = newShapeId();

        // add reference to OLE part
        PackagePartName olePN;
        try {
            olePN = PackagingURIHelper.createPartName( "/xl/embeddings/oleObject"+storageId+".bin" );
        } catch (InvalidFormatException e) {
            throw new POIXMLException(e);
        }
        PackageRelationship olePR = sheetPart.addRelationship( olePN, TargetMode.INTERNAL, POIXMLDocument.OLE_OBJECT_REL_TYPE );

        // add reference to image part
        XSSFPictureData imgPD = sh.getWorkbook().getAllPictures().get(pictureIndex);
        PackagePartName imgPN = imgPD.getPackagePart().getPartName();
        PackageRelationship imgSheetPR = sheetPart.addRelationship( imgPN, TargetMode.INTERNAL, PackageRelationshipTypes.IMAGE_PART );
        PackageRelationship imgDrawPR = getPackagePart().addRelationship( imgPN, TargetMode.INTERNAL, PackageRelationshipTypes.IMAGE_PART );


        // add OLE part metadata to sheet
        CTWorksheet cwb = sh.getCTWorksheet();
        CTOleObjects oo = cwb.isSetOleObjects() ? cwb.getOleObjects() : cwb.addNewOleObjects();

        CTOleObject ole1 = oo.addNewOleObject();
        ole1.setProgId("Package");
        ole1.setShapeId(shapeId);
        ole1.setId(olePR.getId());

        XmlCursor cur1 = ole1.newCursor();
        cur1.toEndToken();
        cur1.beginElement("objectPr", XSSFRelation.NS_SPREADSHEETML);
        cur1.insertAttributeWithValue("id", PackageRelationshipTypes.CORE_PROPERTIES_ECMA376_NS, imgSheetPR.getId());
        cur1.insertAttributeWithValue("defaultSize", "0");
        cur1.beginElement("anchor", XSSFRelation.NS_SPREADSHEETML);
        cur1.insertAttributeWithValue("moveWithCells", "1");

        CTTwoCellAnchor ctAnchor = createTwoCellAnchor((XSSFClientAnchor)anchor);
        
        XmlCursor cur2 = ctAnchor.newCursor();
        cur2.copyXmlContents(cur1);
        cur2.dispose();

        cur1.toParent();
        cur1.toFirstChild();
        cur1.setName(new QName(XSSFRelation.NS_SPREADSHEETML, "from"));
        cur1.toNextSibling();
        cur1.setName(new QName(XSSFRelation.NS_SPREADSHEETML, "to"));

        cur1.dispose();

        // add a new shape and link OLE & image part
        CTShape ctShape = ctAnchor.addNewSp();
        ctShape.set(XSSFObjectData.prototype());
        ctShape.getSpPr().setXfrm(createXfrm((XSSFClientAnchor)anchor));
        
        // workaround for not having the vmlDrawing filled
        CTBlipFillProperties blipFill = ctShape.getSpPr().addNewBlipFill();
        blipFill.addNewBlip().setEmbed(imgDrawPR.getId());
        blipFill.addNewStretch().addNewFillRect();
        
        CTNonVisualDrawingProps cNvPr = ctShape.getNvSpPr().getCNvPr();
        cNvPr.setId(shapeId);

        XmlCursor extCur = cNvPr.getExtLst().getExtArray(0).newCursor();
        extCur.toFirstChild();
        extCur.setAttributeText(new QName("spid"), "_x0000_s"+shapeId);
        extCur.dispose();

        XSSFObjectData shape = new XSSFObjectData(this, ctShape);
        shape.anchor = (XSSFClientAnchor)anchor;

        return shape;
    }


    /**
     * Returns all charts in this drawing.
     */
    public List<XSSFChart> getCharts() {
       List<XSSFChart> charts = new ArrayList<XSSFChart>();
       for(POIXMLDocumentPart part : getRelations()) {
          if(part instanceof XSSFChart) {
             charts.add((XSSFChart)part);
          }
       }
       return charts;
    }

    /**
     * Create and initialize a CTTwoCellAnchor that anchors a shape against top-left and bottom-right cells.
     *
     * @return a new CTTwoCellAnchor
     */
    private CTTwoCellAnchor createTwoCellAnchor(XSSFClientAnchor anchor) {
        CTTwoCellAnchor ctAnchor = drawing.addNewTwoCellAnchor();
        ctAnchor.setFrom(anchor.getFrom());
        ctAnchor.setTo(anchor.getTo());
        ctAnchor.addNewClientData();
        anchor.setTo(ctAnchor.getTo());
        anchor.setFrom(ctAnchor.getFrom());
        STEditAs.Enum aditAs;
        switch(anchor.getAnchorType()) {
            case DONT_MOVE_AND_RESIZE: aditAs = STEditAs.ABSOLUTE; break;
            case MOVE_AND_RESIZE: aditAs = STEditAs.TWO_CELL; break;
            case MOVE_DONT_RESIZE: aditAs = STEditAs.ONE_CELL; break;
            default: aditAs = STEditAs.ONE_CELL;
        }
        ctAnchor.setEditAs(aditAs);
        return ctAnchor;
    }

    private CTTransform2D createXfrm(XSSFClientAnchor anchor) {
        CTTransform2D xfrm = CTTransform2D.Factory.newInstance();
        CTPoint2D off = xfrm.addNewOff();
        off.setX(anchor.getDx1());
        off.setY(anchor.getDy1());
        XSSFSheet sheet = getSheet();
        double widthPx = 0;
        for (int col=anchor.getCol1(); col<anchor.getCol2(); col++) {
            widthPx += sheet.getColumnWidthInPixels(col);
        }
        double heightPx = 0;
        for (int row=anchor.getRow1(); row<anchor.getRow2(); row++) {
            heightPx += ImageUtils.getRowHeightInPixels(sheet, row);
        }
        long width = Units.pixelToEMU((int)widthPx);
        long height = Units.pixelToEMU((int)heightPx);
        CTPositiveSize2D ext = xfrm.addNewExt();
        ext.setCx(width - anchor.getDx1() + anchor.getDx2());
        ext.setCy(height - anchor.getDy1() + anchor.getDy2());

        // TODO: handle vflip/hflip
        return xfrm;
    }

    private long newShapeId(){
        return drawing.sizeOfTwoCellAnchorArray() + 1;
    }

    /**
     * @return list of shapes in this drawing
     */
    public List<XSSFShape> getShapes(){
        List<XSSFShape> lst = new ArrayList<XSSFShape>();
        XmlCursor cur = drawing.newCursor();
        try {
            if (cur.toFirstChild()) {
                addShapes(cur, lst);
            }
        } finally {
            cur.dispose();
        }
        return lst;
    }

    /**
     * @return list of shapes in this shape group
     */
    public List<XSSFShape> getShapes(XSSFShapeGroup groupshape){
        List<XSSFShape> lst = new ArrayList<XSSFShape>();
        XmlCursor cur = groupshape.getCTGroupShape().newCursor();
        try {
            addShapes(cur, lst);
        } finally {
            cur.dispose();
        }
        return lst;
    }

    private void addShapes(XmlCursor cur, List<XSSFShape> lst) {
        try {
            do {
                cur.push();
                if (cur.toFirstChild()) {
                    do {
                        XmlObject obj = cur.getObject();

                        XSSFShape shape;
                        if (obj instanceof CTMarker) {
                            // ignore anchor elements
                            continue;
                        } else if (obj instanceof CTPicture) {
                            shape = new XSSFPicture(this, (CTPicture)obj) ;
                        } else if(obj instanceof CTConnector) {
                            shape = new XSSFConnector(this, (CTConnector)obj) ;
                        } else if(obj instanceof CTShape) {
                            shape = hasOleLink(obj)
                                ? new XSSFObjectData(this, (CTShape)obj)
                                : new XSSFSimpleShape(this, (CTShape)obj) ;
                        } else if(obj instanceof CTGraphicalObjectFrame) {
                            shape = new XSSFGraphicFrame(this, (CTGraphicalObjectFrame)obj) ;
                        } else if(obj instanceof CTGroupShape) {
                            shape = new XSSFShapeGroup(this, (CTGroupShape)obj) ;
                        } else if(obj instanceof XmlAnyTypeImpl) {
                            LOG.log(POILogger.WARN, "trying to parse AlternateContent, "
                                    + "this unlinks the returned Shapes from the underlying xml content, "
                                    + "so those shapes can't be used to modify the drawing, "
                                    + "i.e. modifications will be ignored!");

                            // XmlAnyTypeImpl is returned for AlternateContent parts, which might contain a CTDrawing
                            cur.push();
                            cur.toFirstChild();
                            XmlCursor cur2 = null;
                            try {
                                // need to parse AlternateContent again, otherwise the child elements aren't typed,
                                // but also XmlAnyTypes
                                CTDrawing alterWS = CTDrawing.Factory.parse(cur.newXMLStreamReader());
                                cur2 = alterWS.newCursor();
                                if (cur2.toFirstChild()) {
                                    addShapes(cur2, lst);
                                }
                            } catch (XmlException e) {
                                LOG.log(POILogger.WARN, "unable to parse CTDrawing in alternate content.", e);
                            } finally {
                                if (cur2 != null) {
                                    cur2.dispose();
                                }
                                cur.pop();
                            }
                            continue;
                        } else {
                            // ignore anything else
                            continue;
                        }

                        assert(shape != null);
                        shape.anchor = getAnchorFromParent(obj);
                        lst.add(shape);

                    } while (cur.toNextSibling());
                }
                cur.pop();
            } while (cur.toNextSibling());
        } finally {
            cur.dispose();
        }
    }

    private boolean hasOleLink(XmlObject shape) {
        QName uriName = new QName(null, "uri");
        String xquery = "declare namespace a='"+XSSFRelation.NS_DRAWINGML+"' .//a:extLst/a:ext";
        XmlCursor cur = shape.newCursor();
        cur.selectPath(xquery);
        try {
            while (cur.toNextSelection()) {
                String uri = cur.getAttributeText(uriName);
                if ("{63B3BB69-23CF-44E3-9099-C40C66FF867C}".equals(uri)) {
                    return true;
                }
            }
        } finally {
            cur.dispose();
        }
        return false;
    }

    private XSSFAnchor getAnchorFromParent(XmlObject obj){
        XSSFAnchor anchor = null;

        XmlObject parentXbean = null;
        XmlCursor cursor = obj.newCursor();
        if(cursor.toParent()) {
            parentXbean = cursor.getObject();
        }
        cursor.dispose();
        if(parentXbean != null){
            if (parentXbean instanceof CTTwoCellAnchor) {
                CTTwoCellAnchor ct = (CTTwoCellAnchor)parentXbean;
                anchor = new XSSFClientAnchor(ct.getFrom(), ct.getTo());
            } else if (parentXbean instanceof CTOneCellAnchor) {
                CTOneCellAnchor ct = (CTOneCellAnchor)parentXbean;
                anchor = new XSSFClientAnchor(ct.getFrom(), CTMarker.Factory.newInstance());
            }
        }
        return anchor;
    }

    @Override
    public Iterator<XSSFShape> iterator() {
        return getShapes().iterator();
    }

    /**
     * @return the sheet associated with the drawing
     */
    public XSSFSheet getSheet() {
        return (XSSFSheet)getParent();
    }

}
