/* ====================================================================
   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 java.util.Iterator;

import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.ss.usermodel.ShapeContainer;
import org.apache.poi.util.Internal;
import org.openxmlformats.schemas.drawingml.x2006.main.CTGroupShapeProperties;
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.CTShapeProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTConnector;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTGroupShape;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTGroupShapeNonVisual;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTPicture;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTShape;

/**
 * This object specifies a group shape that represents many shapes grouped together. This shape is to be treated
 * just as if it were a regular shape but instead of being described by a single geometry it is made up of all the
 * shape geometries encompassed within it. Within a group shape each of the shapes that make up the group are
 * specified just as they normally would.
 */
public final class XSSFShapeGroup extends XSSFShape implements ShapeContainer<XSSFShape> {
    private static CTGroupShape prototype;

    private CTGroupShape ctGroup;

    /**
     * Construct a new XSSFSimpleShape object.
     *
     * @param drawing the XSSFDrawing that owns this shape
     * @param ctGroup the XML bean that stores this group content
     */
    protected XSSFShapeGroup(XSSFDrawing drawing, CTGroupShape ctGroup) {
        this.drawing = drawing;
        this.ctGroup = ctGroup;
    }

    /**
     * Initialize default structure of a new shape group
     */
    protected static CTGroupShape prototype() {
        if (prototype == null) {
            CTGroupShape shape = CTGroupShape.Factory.newInstance();

            CTGroupShapeNonVisual nv = shape.addNewNvGrpSpPr();
            CTNonVisualDrawingProps nvpr = nv.addNewCNvPr();
            nvpr.setId(0);
            nvpr.setName("Group 0");
            nv.addNewCNvGrpSpPr();
            CTGroupShapeProperties sp = shape.addNewGrpSpPr();
            CTGroupTransform2D t2d = sp.addNewXfrm();
            CTPositiveSize2D p1 = t2d.addNewExt();
            p1.setCx(0);
            p1.setCy(0);
            CTPoint2D p2 = t2d.addNewOff();
            p2.setX(0);
            p2.setY(0);
            CTPositiveSize2D p3 = t2d.addNewChExt();
            p3.setCx(0);
            p3.setCy(0);
            CTPoint2D p4 = t2d.addNewChOff();
            p4.setX(0);
            p4.setY(0);

            prototype = shape;
        }
        return prototype;
    }

    /**
     * Constructs a textbox.
     *
     * @param anchor the child anchor describes how this shape is attached
     *               to the group.
     * @return      the newly created textbox.
     */
    public XSSFTextBox createTextbox(XSSFChildAnchor anchor){
        CTShape ctShape = ctGroup.addNewSp();
        ctShape.set(XSSFSimpleShape.prototype());

        XSSFTextBox shape = new XSSFTextBox(getDrawing(), ctShape);
        shape.parent = this;
        shape.anchor = anchor;
        shape.setXfrm(anchor.getCTTransform2D());
        return shape;

    }
    /**
     * Creates a simple shape.  This includes such shapes as lines, rectangles,
     * and ovals.
     *
     * @param anchor the child anchor describes how this shape is attached
     *               to the group.
     * @return the newly created shape.
     */
    public XSSFSimpleShape createSimpleShape(XSSFChildAnchor anchor) {
        CTShape ctShape = ctGroup.addNewSp();
        ctShape.set(XSSFSimpleShape.prototype());

        XSSFSimpleShape shape = new XSSFSimpleShape(getDrawing(), ctShape);
        shape.parent = this;
        shape.anchor = anchor;
        shape.setXfrm(anchor.getCTTransform2D());
        return shape;
    }

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

        XSSFConnector shape = new XSSFConnector(getDrawing(), ctShape);
        shape.parent = this;
        shape.anchor = anchor;
        shape.getCTConnector().getSpPr().setXfrm(anchor.getCTTransform2D());
        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 XSSFWorkbook#getAllPictures()} .
     * @return the newly created picture shape.
     */
    public XSSFPicture createPicture(XSSFClientAnchor anchor, int pictureIndex) {
        PackageRelationship rel = getDrawing().addPictureReference(pictureIndex);

        CTPicture ctShape = ctGroup.addNewPic();
        ctShape.set(XSSFPicture.prototype());

        XSSFPicture shape = new XSSFPicture(getDrawing(), ctShape);
        shape.parent = this;
        shape.anchor = anchor;
        shape.setPictureReference(rel);
        return shape;
    }

    /**
     * Creates a group shape.
     *
     * @param anchor       the client anchor describes how this group is attached to the group.
     * @return the newly created group shape.
     */
    public XSSFShapeGroup createGroup(XSSFChildAnchor anchor) {
        CTGroupShape ctShape = ctGroup.addNewGrpSp();
        ctShape.set(prototype());

        XSSFShapeGroup shape = new XSSFShapeGroup(getDrawing(), ctShape);
        shape.parent = this;
        shape.anchor = anchor;

        // TODO: calculate bounding rectangle on anchor and set off/ext correctly

        CTGroupTransform2D xfrm = shape.getCTGroupShape().getGrpSpPr().getXfrm();
        CTTransform2D t2 = anchor.getCTTransform2D();
        xfrm.setOff(t2.getOff());
        xfrm.setExt(t2.getExt());
        // child offset is left to 0,0
        xfrm.setChExt(t2.getExt());
        xfrm.setFlipH(t2.getFlipH());
        xfrm.setFlipV(t2.getFlipV());

        return shape;
    }

    @Internal
    public CTGroupShape getCTGroupShape() {
        return ctGroup;
    }

    /**
     * Sets the coordinate space of this group.  All children are constrained
     * to these coordinates.
     */
    public void setCoordinates(int x1, int y1, int x2, int y2) {
        CTGroupTransform2D t2d = ctGroup.getGrpSpPr().getXfrm();
        CTPoint2D off = t2d.getOff();
        off.setX(x1);
        off.setY(y1);
        CTPositiveSize2D ext = t2d.getExt();
        ext.setCx(x2);
        ext.setCy(y2);

        CTPoint2D chOff = t2d.getChOff();
        chOff.setX(x1);
        chOff.setY(y1);
        CTPositiveSize2D chExt = t2d.getChExt();
        chExt.setCx(x2);
        chExt.setCy(y2);
    }

    @Override
    protected CTShapeProperties getShapeProperties() {
        throw new IllegalStateException("Not supported for shape group");
    }

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

    @Override
    public String getShapeName() {
        return ctGroup.getNvGrpSpPr().getCNvPr().getName();
    }
}
