/* ====================================================================
   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.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.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.EscherProperties;
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.Test;


/**
 * Test escher drawing
 * 
 * optionally the system setting "poi.deserialize.escher" can be set to {@code true}
 */
public 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
    public 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
    public 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());
        assertTrue(((EscherBoolProperty) opt.lookup(EscherProperties.GROUPSHAPE__PRINT)).isTrue());
        assertTrue(((EscherBoolProperty) opt.lookup(EscherProperties.LINESTYLE__NOLINEDRAWDASH)).isTrue());
        assertEquals(0x00000004, ((EscherSimpleProperty) opt.lookup(EscherProperties.GEOMETRY__SHAPEPATH)).getPropertyValue());
        assertNull(opt.lookup(EscherProperties.TEXT__SIZE_TEXT_TO_FIT_SHAPE));
    }

    @Test
    public 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
    public 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
    public 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());

        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);
        assertEquals(((EscherSimpleProperty)((EscherOptRecord)HSSFTestHelper.getEscherContainer(rectangle).getChildById(EscherOptRecord.RECORD_ID))
                .lookup(EscherProperties.TEXT__TEXTID)).getPropertyValue(), "teeeest".hashCode());
        assertEquals(rectangle.isNoFill(), true);
        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);
        assertEquals(rectangle2.isNoFill(), true);
        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);
        assertEquals(rectangle2.isNoFill(), false);
        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
    public 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);
        assertEquals(picture.isNoFill(), false);

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


    /* assert shape properties when reading shapes from a existing workbook */
    @Test
    public 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);
        assertEquals(shape.isNoFill(), false);
        assertEquals(shape.getLineStyle(), HSSFShape.LINESTYLE_DASHDOTGEL);
        assertEquals(shape.getLineStyleColor(), 0x616161);
        assertEquals(HexDump.toHex(shape.getFillColor()), shape.getFillColor(), 0x2CE03D);
        assertEquals(shape.getLineWidth(), HSSFShape.LINEWIDTH_ONE_PT * 2);
        assertEquals(shape.getString().getString(), "POItest");
        assertEquals(shape.getRotationDegree(), 27);
        wb.close();
    }

    @Test
    public 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);
        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.getChildRecords().size());

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

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

        EscherSpRecord sp2 =
                ((EscherContainerRecord) spgrContainer.getChild(2)).getChildById(EscherSpRecord.RECORD_ID);
        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
    public 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
    public 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
    public 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);
        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
    public 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
    public 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
    public 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
    public 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);

        assertEquals(rectangle.isFlipVertical(), false);
        assertEquals(rectangle.isFlipHorizontal(), false);

        rectangle.setFlipVertical(true);
        assertEquals(rectangle.isFlipVertical(), true);
        rectangle.setFlipHorizontal(true);
        assertEquals(rectangle.isFlipHorizontal(), true);

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

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

        assertEquals(rectangle.isFlipHorizontal(), true);
        rectangle.setFlipHorizontal(false);
        assertEquals(rectangle.isFlipHorizontal(), false);

        assertEquals(rectangle.isFlipVertical(), true);
        rectangle.setFlipVertical(false);
        assertEquals(rectangle.isFlipVertical(), false);

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

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

        assertEquals(rectangle.isFlipVertical(), false);
        assertEquals(rectangle.isFlipHorizontal(), false);
        wb3.close();
    }

    @Test
    public 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
    public 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
    public 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
    public void testBug45312() throws Exception {
        HSSFWorkbook wb = new HSSFWorkbook();
        try {
            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);
            }
            
            /*OutputStream stream = new FileOutputStream("/tmp/45312.xls");
            try {
                wb.write(stream);
            } finally {
                stream.close();
            }*/
            
            checkWorkbookBack(wb);
        } finally {
            wb.close();
        }
    }

    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();
    }
}
