/* ====================================================================
   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.hssf.model;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.io.IOException;
import java.util.List;

import org.apache.poi.ddf.EscherBoolProperty;
import org.apache.poi.ddf.EscherContainerRecord;
import org.apache.poi.ddf.EscherDgRecord;
import org.apache.poi.ddf.EscherOptRecord;
import org.apache.poi.ddf.EscherProperty;
import org.apache.poi.ddf.EscherPropertyTypes;
import org.apache.poi.ddf.EscherRecord;
import org.apache.poi.ddf.EscherSimpleProperty;
import org.apache.poi.ddf.EscherSpRecord;
import org.apache.poi.ddf.EscherTextboxRecord;
import org.apache.poi.hssf.HSSFTestDataSamples;
import org.apache.poi.hssf.record.CommonObjectDataSubRecord;
import org.apache.poi.hssf.record.EscherAggregate;
import org.apache.poi.hssf.record.ObjRecord;
import org.apache.poi.hssf.usermodel.HSSFAnchor;
import org.apache.poi.hssf.usermodel.HSSFChildAnchor;
import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
import org.apache.poi.hssf.usermodel.HSSFComment;
import org.apache.poi.hssf.usermodel.HSSFPatriarch;
import org.apache.poi.hssf.usermodel.HSSFPicture;
import org.apache.poi.hssf.usermodel.HSSFPolygon;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFShape;
import org.apache.poi.hssf.usermodel.HSSFShapeGroup;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFSimpleShape;
import org.apache.poi.hssf.usermodel.HSSFTestHelper;
import org.apache.poi.hssf.usermodel.HSSFTextbox;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.ClientAnchor.AnchorType;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.util.HexDump;
import org.junit.jupiter.api.Test;


/**
 * Test escher drawing
 *
 * optionally the system setting "poi.deserialize.escher" can be set to {@code true}
 */
class TestDrawingShapes {
    /**
     * HSSFShape tree bust be built correctly
     * Check file with such records structure:
     * -patriarch
     * --shape
     * --group
     * ---group
     * ----shape
     * ----shape
     * ---shape
     * ---group
     * ----shape
     * ----shape
     */
    @Test
    void testDrawingGroups() throws IOException {
        HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("drawings.xls");
        HSSFSheet sheet = wb.getSheet("groups");
        HSSFPatriarch patriarch = sheet.getDrawingPatriarch();
        assertEquals(patriarch.getChildren().size(), 2);
        HSSFShapeGroup group = (HSSFShapeGroup) patriarch.getChildren().get(1);
        assertEquals(3, group.getChildren().size());
        HSSFShapeGroup group1 = (HSSFShapeGroup) group.getChildren().get(0);
        assertEquals(2, group1.getChildren().size());
        group1 = (HSSFShapeGroup) group.getChildren().get(2);
        assertEquals(2, group1.getChildren().size());
        wb.close();
    }

    @Test
    void testHSSFShapeCompatibility() {
        HSSFSimpleShape shape = new HSSFSimpleShape(null, new HSSFClientAnchor());
        shape.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE);
        assertEquals(0x08000040, shape.getLineStyleColor());
        assertEquals(0x08000009, shape.getFillColor());
        assertEquals(HSSFShape.LINEWIDTH_DEFAULT, shape.getLineWidth());
        assertEquals(HSSFShape.LINESTYLE_SOLID, shape.getLineStyle());
        assertFalse(shape.isNoFill());

        EscherOptRecord opt = shape.getOptRecord();

        assertEquals(7, opt.getEscherProperties().size());
        assertNotEquals(((EscherSimpleProperty) opt.lookup(EscherPropertyTypes.GROUPSHAPE__FLAGS)).getPropertyValue(), 0);
        assertTrue(((EscherBoolProperty) opt.lookup(EscherPropertyTypes.LINESTYLE__NOLINEDRAWDASH)).isTrue());
        assertEquals(0x00000004, ((EscherSimpleProperty) opt.lookup(EscherPropertyTypes.GEOMETRY__SHAPEPATH)).getPropertyValue());
        assertNull(opt.lookup(EscherPropertyTypes.TEXT__SIZE_TEXT_TO_FIT_SHAPE));
    }

    @Test
    void testDefaultPictureSettings() {
        HSSFPicture picture = new HSSFPicture(null, new HSSFClientAnchor());
        assertEquals(picture.getLineWidth(), HSSFShape.LINEWIDTH_DEFAULT);
        assertEquals(picture.getFillColor(), HSSFShape.FILL__FILLCOLOR_DEFAULT);
        assertEquals(picture.getLineStyle(), HSSFShape.LINESTYLE_NONE);
        assertEquals(picture.getLineStyleColor(), HSSFShape.LINESTYLE__COLOR_DEFAULT);
        assertFalse(picture.isNoFill());
        assertEquals(picture.getPictureIndex(), -1);//not set yet
    }

    /**
     * No NullPointerException should appear
     */
    @Test
    void testDefaultSettingsWithEmptyContainer() {
        EscherContainerRecord container = new EscherContainerRecord();
        EscherOptRecord opt = new EscherOptRecord();
        opt.setRecordId(EscherOptRecord.RECORD_ID);
        container.addChildRecord(opt);
        ObjRecord obj = new ObjRecord();
        CommonObjectDataSubRecord cod = new CommonObjectDataSubRecord();
        cod.setObjectType(HSSFSimpleShape.OBJECT_TYPE_PICTURE);
        obj.addSubRecord(cod);
        HSSFPicture picture = new HSSFPicture(container, obj);

        assertEquals(picture.getLineWidth(), HSSFShape.LINEWIDTH_DEFAULT);
        assertEquals(picture.getFillColor(), HSSFShape.FILL__FILLCOLOR_DEFAULT);
        assertEquals(picture.getLineStyle(), HSSFShape.LINESTYLE_DEFAULT);
        assertEquals(picture.getLineStyleColor(), HSSFShape.LINESTYLE__COLOR_DEFAULT);
        assertEquals(picture.isNoFill(), HSSFShape.NO_FILL_DEFAULT);
        assertEquals(picture.getPictureIndex(), -1);//not set yet
    }

    /**
     * create a rectangle, save the workbook, read back and verify that all shape properties are there
     */
    @Test
    void testReadWriteRectangle() throws IOException {
        HSSFWorkbook wb1 = new HSSFWorkbook();
        HSSFSheet sheet = wb1.createSheet();

        HSSFPatriarch drawing = sheet.createDrawingPatriarch();
        HSSFClientAnchor anchor = new HSSFClientAnchor(10, 10, 50, 50, (short) 2, 2, (short) 4, 4);
        anchor.setAnchorType(AnchorType.MOVE_DONT_RESIZE);
        assertEquals(AnchorType.MOVE_DONT_RESIZE, anchor.getAnchorType());
        anchor.setAnchorType(AnchorType.MOVE_DONT_RESIZE);
        assertEquals(AnchorType.MOVE_DONT_RESIZE, anchor.getAnchorType());

        HSSFSimpleShape rectangle = drawing.createSimpleShape(anchor);
        rectangle.setShapeType(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE);
        rectangle.setLineWidth(10000);
        rectangle.setFillColor(777);
        assertEquals(rectangle.getFillColor(), 777);
        assertEquals(10000, rectangle.getLineWidth());
        rectangle.setLineStyle(10);
        assertEquals(10, rectangle.getLineStyle());
        assertEquals(rectangle.getWrapText(), HSSFSimpleShape.WRAP_SQUARE);
        rectangle.setLineStyleColor(1111);
        rectangle.setNoFill(true);
        rectangle.setWrapText(HSSFSimpleShape.WRAP_NONE);
        rectangle.setString(new HSSFRichTextString("teeeest"));
        assertEquals(rectangle.getLineStyleColor(), 1111);
        EscherContainerRecord escherContainer = HSSFTestHelper.getEscherContainer(rectangle);
        assertNotNull(escherContainer);
        EscherRecord childById = escherContainer.getChildById(EscherOptRecord.RECORD_ID);
        assertNotNull(childById);
        EscherProperty lookup = ((EscherOptRecord) childById).lookup(EscherPropertyTypes.TEXT__TEXTID);
        assertNotNull(lookup);
        assertEquals(((EscherSimpleProperty) lookup).getPropertyValue(), "teeeest".hashCode());
        assertTrue(rectangle.isNoFill());
        assertEquals(rectangle.getWrapText(), HSSFSimpleShape.WRAP_NONE);
        assertEquals(rectangle.getString().getString(), "teeeest");

        HSSFWorkbook wb2 = HSSFTestDataSamples.writeOutAndReadBack(wb1);
        wb1.close();
        sheet = wb2.getSheetAt(0);
        drawing = sheet.getDrawingPatriarch();
        assertEquals(1, drawing.getChildren().size());

        HSSFSimpleShape rectangle2 =
                (HSSFSimpleShape) drawing.getChildren().get(0);
        assertEquals(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE,
                rectangle2.getShapeType());
        assertEquals(10000, rectangle2.getLineWidth());
        assertEquals(10, rectangle2.getLineStyle());
        assertEquals(anchor, rectangle2.getAnchor());
        assertEquals(rectangle2.getLineStyleColor(), 1111);
        assertEquals(rectangle2.getFillColor(), 777);
        assertTrue(rectangle2.isNoFill());
        assertEquals(rectangle2.getString().getString(), "teeeest");
        assertEquals(rectangle.getWrapText(), HSSFSimpleShape.WRAP_NONE);

        rectangle2.setFillColor(3333);
        rectangle2.setLineStyle(9);
        rectangle2.setLineStyleColor(4444);
        rectangle2.setNoFill(false);
        rectangle2.setLineWidth(77);
        rectangle2.getAnchor().setDx1(2);
        rectangle2.getAnchor().setDx2(3);
        rectangle2.getAnchor().setDy1(4);
        rectangle2.getAnchor().setDy2(5);
        rectangle.setWrapText(HSSFSimpleShape.WRAP_BY_POINTS);
        rectangle2.setString(new HSSFRichTextString("test22"));

        HSSFWorkbook wb3 = HSSFTestDataSamples.writeOutAndReadBack(wb2);
        wb2.close();
        sheet = wb3.getSheetAt(0);
        drawing = sheet.getDrawingPatriarch();
        assertEquals(1, drawing.getChildren().size());
        rectangle2 = (HSSFSimpleShape) drawing.getChildren().get(0);
        assertEquals(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE, rectangle2.getShapeType());
        assertEquals(rectangle.getWrapText(), HSSFSimpleShape.WRAP_BY_POINTS);
        assertEquals(77, rectangle2.getLineWidth());
        assertEquals(9, rectangle2.getLineStyle());
        assertEquals(rectangle2.getLineStyleColor(), 4444);
        assertEquals(rectangle2.getFillColor(), 3333);
        assertEquals(rectangle2.getAnchor().getDx1(), 2);
        assertEquals(rectangle2.getAnchor().getDx2(), 3);
        assertEquals(rectangle2.getAnchor().getDy1(), 4);
        assertEquals(rectangle2.getAnchor().getDy2(), 5);
        assertFalse(rectangle2.isNoFill());
        assertEquals(rectangle2.getString().getString(), "test22");

        HSSFSimpleShape rect3 = drawing.createSimpleShape(new HSSFClientAnchor());
        rect3.setShapeType(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE);
        HSSFWorkbook wb4 = HSSFTestDataSamples.writeOutAndReadBack(wb3);
        wb3.close();

        drawing = wb4.getSheetAt(0).getDrawingPatriarch();
        assertEquals(drawing.getChildren().size(), 2);
        wb4.close();
    }

    @Test
    void testReadExistingImage() throws IOException {
        HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("drawings.xls");
        HSSFSheet sheet = wb.getSheet("pictures");
        HSSFPatriarch drawing = sheet.getDrawingPatriarch();
        assertEquals(1, drawing.getChildren().size());
        HSSFPicture picture = (HSSFPicture) drawing.getChildren().get(0);

        assertEquals(picture.getPictureIndex(), 2);
        assertEquals(picture.getLineStyleColor(), HSSFShape.LINESTYLE__COLOR_DEFAULT);
        assertEquals(picture.getFillColor(), 0x5DC943);
        assertEquals(picture.getLineWidth(), HSSFShape.LINEWIDTH_DEFAULT);
        assertEquals(picture.getLineStyle(), HSSFShape.LINESTYLE_DEFAULT);
        assertFalse(picture.isNoFill());

        picture.setPictureIndex(2);
        assertEquals(picture.getPictureIndex(), 2);
        wb.close();
    }


    /* assert shape properties when reading shapes from a existing workbook */
    @Test
    void testReadExistingRectangle() throws IOException {
        HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("drawings.xls");
        HSSFSheet sheet = wb.getSheet("rectangles");
        HSSFPatriarch drawing = sheet.getDrawingPatriarch();
        assertEquals(1, drawing.getChildren().size());

        HSSFSimpleShape shape = (HSSFSimpleShape) drawing.getChildren().get(0);
        assertFalse(shape.isNoFill());
        assertEquals(shape.getLineStyle(), HSSFShape.LINESTYLE_DASHDOTGEL);
        assertEquals(shape.getLineStyleColor(), 0x616161);
        assertEquals(shape.getFillColor(), 0x2CE03D, HexDump.toHex(shape.getFillColor()));
        assertEquals(shape.getLineWidth(), HSSFShape.LINEWIDTH_ONE_PT * 2);
        assertEquals(shape.getString().getString(), "POItest");
        assertEquals(shape.getRotationDegree(), 27);
        wb.close();
    }

    @Test
    void testShapeIds() throws IOException {
        HSSFWorkbook wb1 = new HSSFWorkbook();
        HSSFSheet sheet1 = wb1.createSheet();
        HSSFPatriarch patriarch1 = sheet1.createDrawingPatriarch();
        for (int i = 0; i < 2; i++) {
            patriarch1.createSimpleShape(new HSSFClientAnchor());
        }

        HSSFWorkbook wb2 = HSSFTestDataSamples.writeOutAndReadBack(wb1);
        wb1.close();
        sheet1 = wb2.getSheetAt(0);
        patriarch1 = sheet1.getDrawingPatriarch();

        EscherAggregate agg1 = HSSFTestHelper.getEscherAggregate(patriarch1);
        // last shape ID cached in EscherDgRecord
        EscherDgRecord dg1 = agg1.getEscherContainer().getChildById(EscherDgRecord.RECORD_ID);
        assertNotNull(dg1);
        assertEquals(1026, dg1.getLastMSOSPID());

        // iterate over shapes and check shapeId
        EscherContainerRecord spgrContainer =
                agg1.getEscherContainer().getChildContainers().get(0);
        // root spContainer + 2 spContainers for shapes
        assertEquals(3, spgrContainer.getChildCount());

        EscherSpRecord sp0 =
                ((EscherContainerRecord) spgrContainer.getChild(0)).getChildById(EscherSpRecord.RECORD_ID);
        assertNotNull(sp0);
        assertEquals(1024, sp0.getShapeId());

        EscherSpRecord sp1 =
                ((EscherContainerRecord) spgrContainer.getChild(1)).getChildById(EscherSpRecord.RECORD_ID);
        assertNotNull(sp1);
        assertEquals(1025, sp1.getShapeId());

        EscherSpRecord sp2 =
                ((EscherContainerRecord) spgrContainer.getChild(2)).getChildById(EscherSpRecord.RECORD_ID);
        assertNotNull(sp2);
        assertEquals(1026, sp2.getShapeId());
        wb2.close();
    }

    /**
     * Test get new id for shapes from existing file
     * File already have for 1 shape on each sheet, because document must contain EscherDgRecord for each sheet
     */
    @Test
    void testAllocateNewIds() throws IOException {
        HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("empty.xls");
        HSSFSheet sheet = wb.getSheetAt(0);
        HSSFPatriarch patriarch = sheet.getDrawingPatriarch();

        // 2048 - main SpContainer id
        // 2049 - existing shape id
        assertEquals(HSSFTestHelper.allocateNewShapeId(patriarch), 2050);
        assertEquals(HSSFTestHelper.allocateNewShapeId(patriarch), 2051);
        assertEquals(HSSFTestHelper.allocateNewShapeId(patriarch), 2052);

        sheet = wb.getSheetAt(1);
        patriarch = sheet.getDrawingPatriarch();

        // 3072 - main SpContainer id
        // 3073 - existing shape id
        assertEquals(HSSFTestHelper.allocateNewShapeId(patriarch), 3074);
        assertEquals(HSSFTestHelper.allocateNewShapeId(patriarch), 3075);
        assertEquals(HSSFTestHelper.allocateNewShapeId(patriarch), 3076);


        sheet = wb.getSheetAt(2);
        patriarch = sheet.getDrawingPatriarch();

        assertEquals(HSSFTestHelper.allocateNewShapeId(patriarch), 1026);
        assertEquals(HSSFTestHelper.allocateNewShapeId(patriarch), 1027);
        assertEquals(HSSFTestHelper.allocateNewShapeId(patriarch), 1028);
        wb.close();
    }

    @Test
    void testOpt() throws IOException {
        HSSFWorkbook wb = new HSSFWorkbook();

        // create a sheet with a text box
        HSSFSheet sheet = wb.createSheet();
        HSSFPatriarch patriarch = sheet.createDrawingPatriarch();

        HSSFTextbox textbox = patriarch.createTextbox(new HSSFClientAnchor());
        EscherOptRecord opt1 = HSSFTestHelper.getOptRecord(textbox);
        EscherOptRecord opt2 = HSSFTestHelper.getEscherContainer(textbox).getChildById(EscherOptRecord.RECORD_ID);
        assertSame(opt1, opt2);
        wb.close();
    }

    @Test
    void testCorrectOrderInOptRecord() throws IOException{
        HSSFWorkbook wb = new HSSFWorkbook();

        HSSFSheet sheet = wb.createSheet();
        HSSFPatriarch patriarch = sheet.createDrawingPatriarch();

        HSSFTextbox textbox = patriarch.createTextbox(new HSSFClientAnchor());
        EscherOptRecord opt = HSSFTestHelper.getOptRecord(textbox);

        String opt1Str = opt.toXml();

        textbox.setFillColor(textbox.getFillColor());
        EscherContainerRecord container = HSSFTestHelper.getEscherContainer(textbox);
        EscherOptRecord optRecord = container.getChildById(EscherOptRecord.RECORD_ID);
        assertNotNull(optRecord);
        assertEquals(opt1Str, optRecord.toXml());
        textbox.setLineStyle(textbox.getLineStyle());
        assertEquals(opt1Str, optRecord.toXml());
        textbox.setLineWidth(textbox.getLineWidth());
        assertEquals(opt1Str, optRecord.toXml());
        textbox.setLineStyleColor(textbox.getLineStyleColor());
        assertEquals(opt1Str, optRecord.toXml());
        wb.close();
    }

    @Test
    void testDgRecordNumShapes() throws IOException {
        HSSFWorkbook wb = new HSSFWorkbook();
        HSSFSheet sheet = wb.createSheet();
        HSSFPatriarch patriarch = sheet.createDrawingPatriarch();

        EscherAggregate aggregate = HSSFTestHelper.getEscherAggregate(patriarch);
        EscherDgRecord dgRecord = (EscherDgRecord) aggregate.getEscherRecord(0).getChild(0);
        assertEquals(dgRecord.getNumShapes(), 1);
        wb.close();
    }

    @Test
    void testTextForSimpleShape() throws IOException {
        HSSFWorkbook wb1 = new HSSFWorkbook();
        HSSFSheet sheet = wb1.createSheet();
        HSSFPatriarch patriarch = sheet.createDrawingPatriarch();

        HSSFSimpleShape shape = patriarch.createSimpleShape(new HSSFClientAnchor());
        shape.setShapeType(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE);

        EscherAggregate agg = HSSFTestHelper.getEscherAggregate(patriarch);
        assertEquals(agg.getShapeToObjMapping().size(), 2);

        HSSFWorkbook wb2 = HSSFTestDataSamples.writeOutAndReadBack(wb1);
        wb1.close();
        sheet = wb2.getSheetAt(0);
        patriarch = sheet.getDrawingPatriarch();

        shape = (HSSFSimpleShape) patriarch.getChildren().get(0);

        agg = HSSFTestHelper.getEscherAggregate(patriarch);
        assertEquals(agg.getShapeToObjMapping().size(), 2);

        shape.setString(new HSSFRichTextString("string1"));
        assertEquals(shape.getString().getString(), "string1");

        assertNotNull(HSSFTestHelper.getEscherContainer(shape).getChildById(EscherTextboxRecord.RECORD_ID));
        assertEquals(agg.getShapeToObjMapping().size(), 2);

        HSSFWorkbook wb3 = HSSFTestDataSamples.writeOutAndReadBack(wb2);
        wb2.close();

        HSSFWorkbook wb4 = HSSFTestDataSamples.writeOutAndReadBack(wb3);
        wb3.close();
        sheet = wb4.getSheetAt(0);
        patriarch = sheet.getDrawingPatriarch();

        shape = (HSSFSimpleShape) patriarch.getChildren().get(0);

        assertNotNull(HSSFTestHelper.getTextObjRecord(shape));
        assertEquals(shape.getString().getString(), "string1");
        assertNotNull(HSSFTestHelper.getEscherContainer(shape).getChildById(EscherTextboxRecord.RECORD_ID));
        assertEquals(agg.getShapeToObjMapping().size(), 2);
        wb4.close();
    }

    @Test
    void testRemoveShapes() throws IOException {
        HSSFWorkbook wb1 = new HSSFWorkbook();
        HSSFSheet sheet = wb1.createSheet();
        HSSFPatriarch patriarch = sheet.createDrawingPatriarch();

        HSSFSimpleShape rectangle = patriarch.createSimpleShape(new HSSFClientAnchor());
        rectangle.setShapeType(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE);

        int idx = wb1.addPicture(new byte[]{1,2,3}, Workbook.PICTURE_TYPE_JPEG);
        patriarch.createPicture(new HSSFClientAnchor(), idx);

        patriarch.createCellComment(new HSSFClientAnchor());

        HSSFPolygon polygon = patriarch.createPolygon(new HSSFClientAnchor());
        polygon.setPoints(new int[]{1,2}, new int[]{2,3});

        patriarch.createTextbox(new HSSFClientAnchor());

        HSSFShapeGroup group = patriarch.createGroup(new HSSFClientAnchor());
        group.createTextbox(new HSSFChildAnchor());
        group.createPicture(new HSSFChildAnchor(), idx);

        assertEquals(patriarch.getChildren().size(), 6);
        assertEquals(group.getChildren().size(), 2);

        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 12);
        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 1);

        HSSFWorkbook wb2 = HSSFTestDataSamples.writeOutAndReadBack(wb1);
        wb1.close();
        sheet = wb2.getSheetAt(0);
        patriarch = sheet.getDrawingPatriarch();

        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 12);
        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 1);

        assertEquals(patriarch.getChildren().size(), 6);

        group = (HSSFShapeGroup) patriarch.getChildren().get(5);
        group.removeShape(group.getChildren().get(0));

        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 10);
        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 1);

        HSSFWorkbook wb3 = HSSFTestDataSamples.writeOutAndReadBack(wb2);
        wb2.close();
        sheet = wb3.getSheetAt(0);
        patriarch = sheet.getDrawingPatriarch();

        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 10);
        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 1);

        group = (HSSFShapeGroup) patriarch.getChildren().get(5);
        patriarch.removeShape(group);

        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 8);
        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 1);

        HSSFWorkbook wb4 = HSSFTestDataSamples.writeOutAndReadBack(wb3);
        wb3.close();
        sheet = wb4.getSheetAt(0);
        patriarch = sheet.getDrawingPatriarch();

        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 8);
        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 1);
        assertEquals(patriarch.getChildren().size(), 5);

        HSSFShape shape = patriarch.getChildren().get(0);
        patriarch.removeShape(shape);

        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 6);
        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 1);
        assertEquals(patriarch.getChildren().size(), 4);

        HSSFWorkbook wb5 = HSSFTestDataSamples.writeOutAndReadBack(wb4);
        wb4.close();
        sheet = wb5.getSheetAt(0);
        patriarch = sheet.getDrawingPatriarch();

        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 6);
        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 1);
        assertEquals(patriarch.getChildren().size(), 4);

        HSSFPicture picture = (HSSFPicture) patriarch.getChildren().get(0);
        patriarch.removeShape(picture);

        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 5);
        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 1);
        assertEquals(patriarch.getChildren().size(), 3);

        HSSFWorkbook wb6 = HSSFTestDataSamples.writeOutAndReadBack(wb5);
        wb5.close();
        sheet = wb6.getSheetAt(0);
        patriarch = sheet.getDrawingPatriarch();

        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 5);
        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 1);
        assertEquals(patriarch.getChildren().size(), 3);

        HSSFComment comment = (HSSFComment) patriarch.getChildren().get(0);
        patriarch.removeShape(comment);

        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 3);
        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 0);
        assertEquals(patriarch.getChildren().size(), 2);

        HSSFWorkbook wb7 = HSSFTestDataSamples.writeOutAndReadBack(wb6);
        wb6.close();
        sheet = wb7.getSheetAt(0);
        patriarch = sheet.getDrawingPatriarch();

        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 3);
        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 0);
        assertEquals(patriarch.getChildren().size(), 2);

        polygon = (HSSFPolygon) patriarch.getChildren().get(0);
        patriarch.removeShape(polygon);

        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 2);
        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 0);
        assertEquals(patriarch.getChildren().size(), 1);

        HSSFWorkbook wb8 = HSSFTestDataSamples.writeOutAndReadBack(wb7);
        wb7.close();
        sheet = wb8.getSheetAt(0);
        patriarch = sheet.getDrawingPatriarch();

        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 2);
        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 0);
        assertEquals(patriarch.getChildren().size(), 1);

        HSSFTextbox textbox = (HSSFTextbox) patriarch.getChildren().get(0);
        patriarch.removeShape(textbox);

        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 0);
        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 0);
        assertEquals(patriarch.getChildren().size(), 0);

        HSSFWorkbook wb9 = HSSFTestDataSamples.writeOutAndReadBack(wb8);
        wb8.close();
        sheet = wb9.getSheetAt(0);
        patriarch = sheet.getDrawingPatriarch();

        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 0);
        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 0);
        assertEquals(patriarch.getChildren().size(), 0);
        wb9.close();
    }

    @Test
    void testShapeFlip() throws IOException {
        HSSFWorkbook wb1 = new HSSFWorkbook();
        HSSFSheet sheet = wb1.createSheet();
        HSSFPatriarch patriarch = sheet.createDrawingPatriarch();

        HSSFSimpleShape rectangle = patriarch.createSimpleShape(new HSSFClientAnchor());
        rectangle.setShapeType(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE);

        assertFalse(rectangle.isFlipVertical());
        assertFalse(rectangle.isFlipHorizontal());

        rectangle.setFlipVertical(true);
        assertTrue(rectangle.isFlipVertical());
        rectangle.setFlipHorizontal(true);
        assertTrue(rectangle.isFlipHorizontal());

        HSSFWorkbook wb2 = HSSFTestDataSamples.writeOutAndReadBack(wb1);
        wb1.close();
        sheet = wb2.getSheetAt(0);
        patriarch = sheet.getDrawingPatriarch();

        rectangle = (HSSFSimpleShape) patriarch.getChildren().get(0);

        assertTrue(rectangle.isFlipHorizontal());
        rectangle.setFlipHorizontal(false);
        assertFalse(rectangle.isFlipHorizontal());

        assertTrue(rectangle.isFlipVertical());
        rectangle.setFlipVertical(false);
        assertFalse(rectangle.isFlipVertical());

        HSSFWorkbook wb3 = HSSFTestDataSamples.writeOutAndReadBack(wb2);
        wb2.close();
        sheet = wb3.getSheetAt(0);
        patriarch = sheet.getDrawingPatriarch();

        rectangle = (HSSFSimpleShape) patriarch.getChildren().get(0);

        assertFalse(rectangle.isFlipVertical());
        assertFalse(rectangle.isFlipHorizontal());
        wb3.close();
    }

    @Test
    void testRotation() throws IOException {
        HSSFWorkbook wb1 = new HSSFWorkbook();
        HSSFSheet sheet = wb1.createSheet();
        HSSFPatriarch patriarch = sheet.createDrawingPatriarch();

        HSSFSimpleShape rectangle = patriarch.createSimpleShape(new HSSFClientAnchor(0,0,100,100, (short) 0,0,(short)5,5));
        rectangle.setShapeType(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE);

        assertEquals(rectangle.getRotationDegree(), 0);
        rectangle.setRotationDegree((short) 45);
        assertEquals(rectangle.getRotationDegree(), 45);
        rectangle.setFlipHorizontal(true);

        HSSFWorkbook wb2 = HSSFTestDataSamples.writeOutAndReadBack(wb1);
        wb1.close();
        sheet = wb2.getSheetAt(0);
        patriarch = sheet.getDrawingPatriarch();
        rectangle = (HSSFSimpleShape) patriarch.getChildren().get(0);
        assertEquals(rectangle.getRotationDegree(), 45);
        rectangle.setRotationDegree((short) 30);
        assertEquals(rectangle.getRotationDegree(), 30);

        patriarch.setCoordinates(0, 0, 10, 10);
        rectangle.setString(new HSSFRichTextString("1234"));
        wb2.close();
    }

    @SuppressWarnings("unused")
    @Test
    void testShapeContainerImplementsIterable() throws IOException {
        HSSFWorkbook wb = new HSSFWorkbook();

        HSSFSheet sheet = wb.createSheet();
        HSSFPatriarch patriarch = sheet.createDrawingPatriarch();

        patriarch.createSimpleShape(new HSSFClientAnchor());
        patriarch.createSimpleShape(new HSSFClientAnchor());

        int i=2;

        for (HSSFShape shape: patriarch){
            i--;
        }
        assertEquals(i, 0);
        wb.close();
    }

    @Test
    void testClearShapesForPatriarch() throws IOException {
        HSSFWorkbook wb1 = new HSSFWorkbook();
        HSSFSheet sheet = wb1.createSheet();
        HSSFPatriarch patriarch = sheet.createDrawingPatriarch();

        patriarch.createSimpleShape(new HSSFClientAnchor());
        patriarch.createSimpleShape(new HSSFClientAnchor());
        patriarch.createCellComment(new HSSFClientAnchor());

        EscherAggregate agg = HSSFTestHelper.getEscherAggregate(patriarch);

        assertEquals(agg.getShapeToObjMapping().size(), 6);
        assertEquals(agg.getTailRecords().size(), 1);
        assertEquals(patriarch.getChildren().size(), 3);

        patriarch.clear();

        assertEquals(agg.getShapeToObjMapping().size(), 0);
        assertEquals(agg.getTailRecords().size(), 0);
        assertEquals(patriarch.getChildren().size(), 0);

        HSSFWorkbook wb2 = HSSFTestDataSamples.writeOutAndReadBack(wb1);
        wb1.close();
        sheet = wb2.getSheetAt(0);
        patriarch = sheet.getDrawingPatriarch();

        assertEquals(agg.getShapeToObjMapping().size(), 0);
        assertEquals(agg.getTailRecords().size(), 0);
        assertEquals(patriarch.getChildren().size(), 0);
        wb2.close();
    }

    @Test
    void testBug45312() throws Exception {
        try (HSSFWorkbook wb = new HSSFWorkbook()) {
            HSSFSheet sheet = wb.createSheet();
            HSSFPatriarch patriarch = sheet.createDrawingPatriarch();

            {
                HSSFClientAnchor a1 = new HSSFClientAnchor();
                a1.setAnchor( (short)1, 1, 0, 0, (short) 1, 1, 512, 100);
                HSSFSimpleShape shape1 = patriarch.createSimpleShape(a1);
                shape1.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE);
            }
            {
                HSSFClientAnchor a1 = new HSSFClientAnchor();
                a1.setAnchor( (short)1, 1, 512, 0, (short) 1, 1, 1024, 100);
                HSSFSimpleShape shape1 = patriarch.createSimpleShape(a1);
                shape1.setFlipVertical(true);
                shape1.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE);
            }

            {
                HSSFClientAnchor a1 = new HSSFClientAnchor();
                a1.setAnchor( (short)2, 2, 0, 0, (short) 2, 2, 512, 100);
                HSSFSimpleShape shape1 = patriarch.createSimpleShape(a1);
                shape1.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE);
            }
            {
                HSSFClientAnchor a1 = new HSSFClientAnchor();
                a1.setAnchor( (short)2, 2, 0, 100, (short) 2, 2, 512, 200);
                HSSFSimpleShape shape1 = patriarch.createSimpleShape(a1);
                shape1.setFlipHorizontal(true);
                shape1.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE);
            }

            checkWorkbookBack(wb);
        }
    }

    private void checkWorkbookBack(HSSFWorkbook wb) throws IOException {
        HSSFWorkbook wbBack = HSSFTestDataSamples.writeOutAndReadBack(wb);
        assertNotNull(wbBack);

        HSSFSheet sheetBack = wbBack.getSheetAt(0);
        assertNotNull(sheetBack);

        HSSFPatriarch patriarchBack = sheetBack.getDrawingPatriarch();
        assertNotNull(patriarchBack);

        List<HSSFShape> children = patriarchBack.getChildren();
        assertEquals(4, children.size());
        HSSFShape hssfShape = children.get(0);
        assertTrue(hssfShape instanceof HSSFSimpleShape);
        HSSFAnchor anchor = hssfShape.getAnchor();
        assertTrue(anchor instanceof HSSFClientAnchor);
        assertEquals(0, anchor.getDx1());
        assertEquals(512, anchor.getDx2());
        assertEquals(0, anchor.getDy1());
        assertEquals(100, anchor.getDy2());
        HSSFClientAnchor cAnchor = (HSSFClientAnchor) anchor;
        assertEquals(1, cAnchor.getCol1());
        assertEquals(1, cAnchor.getCol2());
        assertEquals(1, cAnchor.getRow1());
        assertEquals(1, cAnchor.getRow2());

        hssfShape = children.get(1);
        assertTrue(hssfShape instanceof HSSFSimpleShape);
        anchor = hssfShape.getAnchor();
        assertTrue(anchor instanceof HSSFClientAnchor);
        assertEquals(512, anchor.getDx1());
        assertEquals(1024, anchor.getDx2());
        assertEquals(0, anchor.getDy1());
        assertEquals(100, anchor.getDy2());
        cAnchor = (HSSFClientAnchor) anchor;
        assertEquals(1, cAnchor.getCol1());
        assertEquals(1, cAnchor.getCol2());
        assertEquals(1, cAnchor.getRow1());
        assertEquals(1, cAnchor.getRow2());

        hssfShape = children.get(2);
        assertTrue(hssfShape instanceof HSSFSimpleShape);
        anchor = hssfShape.getAnchor();
        assertTrue(anchor instanceof HSSFClientAnchor);
        assertEquals(0, anchor.getDx1());
        assertEquals(512, anchor.getDx2());
        assertEquals(0, anchor.getDy1());
        assertEquals(100, anchor.getDy2());
        cAnchor = (HSSFClientAnchor) anchor;
        assertEquals(2, cAnchor.getCol1());
        assertEquals(2, cAnchor.getCol2());
        assertEquals(2, cAnchor.getRow1());
        assertEquals(2, cAnchor.getRow2());

        hssfShape = children.get(3);
        assertTrue(hssfShape instanceof HSSFSimpleShape);
        anchor = hssfShape.getAnchor();
        assertTrue(anchor instanceof HSSFClientAnchor);
        assertEquals(0, anchor.getDx1());
        assertEquals(512, anchor.getDx2());
        assertEquals(100, anchor.getDy1());
        assertEquals(200, anchor.getDy2());
        cAnchor = (HSSFClientAnchor) anchor;
        assertEquals(2, cAnchor.getCol1());
        assertEquals(2, cAnchor.getCol2());
        assertEquals(2, cAnchor.getRow1());
        assertEquals(2, cAnchor.getRow2());

        wbBack.close();
    }
}
