/* ====================================================================
   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.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNotSame;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;

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

import org.apache.poi.hssf.HSSFTestDataSamples;
import org.apache.poi.ooxml.POIXMLDocumentPart;
import org.apache.poi.ooxml.POIXMLDocumentPart.RelationPart;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.ss.usermodel.ClientAnchor;
import org.apache.poi.ss.usermodel.FontUnderline;
import org.apache.poi.ss.usermodel.ShapeTypes;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.util.Units;
import org.apache.poi.xssf.XSSFTestDataSamples;
import org.junit.jupiter.api.Test;
import org.openxmlformats.schemas.drawingml.x2006.main.CTGroupTransform2D;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraph;
import org.openxmlformats.schemas.drawingml.x2006.main.STTextUnderlineType;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTDrawing;

class TestXSSFDrawing {
    @Test
    void bug54803() throws Exception {
        try (XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("bug54803.xlsx")) {
            XSSFSheet sheet = wb.getSheetAt(0);
            sheet.createDrawingPatriarch();
            try (XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb)) {
                XSSFSheet sheet2 = wb2.getSheetAt(0);
                assertNotNull(sheet2.getDrawingPatriarch());
            }
        }
    }

    @Test
    void testRead() throws IOException {
        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("WithDrawing.xlsx");
        XSSFSheet sheet = wb.getSheetAt(0);
        //the sheet has one relationship and it is XSSFDrawing
        List<RelationPart> rels = sheet.getRelationParts();
        assertEquals(1, rels.size());
        RelationPart rp = rels.get(0);
        assertTrue(rp.getDocumentPart() instanceof XSSFDrawing);

        XSSFDrawing drawing = rp.getDocumentPart();
        //sheet.createDrawingPatriarch() should return the same instance of XSSFDrawing
        assertSame(drawing, sheet.createDrawingPatriarch());
        String drawingId = rp.getRelationship().getId();

        //there should be a relation to this drawing in the worksheet
        assertTrue(sheet.getCTWorksheet().isSetDrawing());
        assertEquals(drawingId, sheet.getCTWorksheet().getDrawing().getId());

        List<XSSFShape> shapes = drawing.getShapes();
        assertEquals(6, shapes.size());

        assertTrue(shapes.get(0) instanceof XSSFPicture);
        assertTrue(shapes.get(1) instanceof XSSFPicture);
        assertTrue(shapes.get(2) instanceof XSSFPicture);
        assertTrue(shapes.get(3) instanceof XSSFPicture);
        assertTrue(shapes.get(4) instanceof XSSFSimpleShape);
        assertTrue(shapes.get(5) instanceof XSSFPicture);

        for(XSSFShape sh : shapes) assertNotNull(sh.getAnchor());

        checkRewrite(wb);
        wb.close();
    }

    @Test
    void testNew() throws IOException {
        XSSFWorkbook wb1 = new XSSFWorkbook();
        XSSFSheet sheet = wb1.createSheet();
        //multiple calls of createDrawingPatriarch should return the same instance of XSSFDrawing
        XSSFDrawing dr1 = sheet.createDrawingPatriarch();
        XSSFDrawing dr2 = sheet.createDrawingPatriarch();
        assertSame(dr1, dr2);

        List<RelationPart> rels = sheet.getRelationParts();
        assertEquals(1, rels.size());
        RelationPart rp = rels.get(0);
        assertTrue(rp.getDocumentPart() instanceof XSSFDrawing);

        XSSFDrawing drawing = rp.getDocumentPart();
        String drawingId = rp.getRelationship().getId();

        //there should be a relation to this drawing in the worksheet
        assertTrue(sheet.getCTWorksheet().isSetDrawing());
        assertEquals(drawingId, sheet.getCTWorksheet().getDrawing().getId());

        XSSFConnector c1= drawing.createConnector(new XSSFClientAnchor(0,0,0,0,0,0,2,2));
        c1.setLineWidth(2.5);
        c1.setLineStyle(1);

        XSSFShapeGroup c2 = drawing.createGroup(new XSSFClientAnchor(0,0,0,0,0,0,5,5));
        assertNotNull(c2);

        XSSFSimpleShape c3 = drawing.createSimpleShape(new XSSFClientAnchor(0,0,0,0,2,2,3,4));
        c3.setText(new XSSFRichTextString("Test String"));
        c3.setFillColor(128, 128, 128);

        XSSFTextBox c4 = drawing.createTextbox(new XSSFClientAnchor(0,0,0,0,4,4,5,6));
        XSSFRichTextString rt = new XSSFRichTextString("Test String");
        rt.applyFont(0, 5, wb1.createFont());
        rt.applyFont(5, 6, wb1.createFont());
        c4.setText(rt);

        c4.setNoFill(true);
        assertEquals(4, drawing.getCTDrawing().sizeOfTwoCellAnchorArray());

        List<XSSFShape> shapes = drawing.getShapes();
        assertEquals(4, shapes.size());
        assertTrue(shapes.get(0) instanceof XSSFConnector);
        assertTrue(shapes.get(1) instanceof XSSFShapeGroup);
        assertTrue(shapes.get(2) instanceof XSSFSimpleShape);
        assertTrue(shapes.get(3) instanceof XSSFSimpleShape); //

        // Save and re-load it
        XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1);
        wb1.close();
        sheet = wb2.getSheetAt(0);

        // Check
        dr1 = sheet.createDrawingPatriarch();
        CTDrawing ctDrawing = dr1.getCTDrawing();

        // Connector, shapes and text boxes are all two cell anchors
        assertEquals(0, ctDrawing.sizeOfAbsoluteAnchorArray());
        assertEquals(0, ctDrawing.sizeOfOneCellAnchorArray());
        assertEquals(4, ctDrawing.sizeOfTwoCellAnchorArray());

        shapes = dr1.getShapes();
        assertEquals(4, shapes.size());
        assertTrue(shapes.get(0) instanceof XSSFConnector);
        assertTrue(shapes.get(1) instanceof XSSFShapeGroup);
        assertTrue(shapes.get(2) instanceof XSSFSimpleShape);
        assertTrue(shapes.get(3) instanceof XSSFSimpleShape); //

        // Ensure it got the right namespaces
        String xml = ctDrawing.toString();
        assertTrue(xml.contains("xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\""));
        assertTrue(xml.contains("xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\""));

        checkRewrite(wb2);
        wb2.close();
    }

    @Test
    void testMultipleDrawings() throws IOException{
        XSSFWorkbook wb = new XSSFWorkbook();
        for (int i = 0; i < 3; i++) {
            XSSFSheet sheet = wb.createSheet();
            XSSFDrawing drawing = sheet.createDrawingPatriarch();
            assertNotNull(drawing);
        }
        try (OPCPackage pkg = wb.getPackage()) {
            assertEquals(3, pkg.getPartsByContentType(XSSFRelation.DRAWINGS.getContentType()).size());
            checkRewrite(wb);
        }
        wb.close();
    }

    @Test
    void testClone() throws Exception{
        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("WithDrawing.xlsx");
        XSSFSheet sheet1 = wb.getSheetAt(0);

        XSSFSheet sheet2 = wb.cloneSheet(0);

        //the source sheet has one relationship and it is XSSFDrawing
        List<POIXMLDocumentPart> rels1 = sheet1.getRelations();
        assertEquals(1, rels1.size());
        assertTrue(rels1.get(0) instanceof XSSFDrawing);

        List<POIXMLDocumentPart> rels2 = sheet2.getRelations();
        assertEquals(1, rels2.size());
        assertTrue(rels2.get(0) instanceof XSSFDrawing);

        XSSFDrawing drawing1 = (XSSFDrawing)rels1.get(0);
        XSSFDrawing drawing2 = (XSSFDrawing)rels2.get(0);
        assertNotSame(drawing1, drawing2);  // drawing2 is a clone of drawing1

        List<XSSFShape> shapes1 = drawing1.getShapes();
        List<XSSFShape> shapes2 = drawing2.getShapes();
        assertEquals(shapes1.size(), shapes2.size());

        for(int i = 0; i < shapes1.size(); i++){
            XSSFShape sh1 = shapes1.get(i);
            XSSFShape sh2 = shapes2.get(i);

            assertSame(sh1.getClass(), sh2.getClass());
            assertEquals(sh1.getShapeProperties().toString(), sh2.getShapeProperties().toString());
        }

        checkRewrite(wb);
        wb.close();
    }

    /**
     * ensure that rich text attributes defined in a XSSFRichTextString
     * are passed to XSSFSimpleShape.
     *
     * See Bugzilla 52219.
     */
    @Test
    void testRichText() throws IOException {
        XSSFWorkbook wb = new XSSFWorkbook();
        XSSFSheet sheet = wb.createSheet();
        XSSFDrawing drawing = sheet.createDrawingPatriarch();

        XSSFTextBox shape = drawing.createTextbox(new XSSFClientAnchor(0, 0, 0, 0, 2, 2, 3, 4));
        XSSFRichTextString rt = new XSSFRichTextString("Test String");

        XSSFFont font = wb.createFont();
        font.setColor(new XSSFColor(new Color(0, 128, 128), wb.getStylesSource().getIndexedColors()));
        font.setItalic(true);
        font.setBold(true);
        font.setUnderline(FontUnderline.SINGLE);
        rt.applyFont(font);

        shape.setText(rt);

        CTTextParagraph pr = shape.getCTShape().getTxBody().getPArray(0);
        assertEquals(1, pr.sizeOfRArray());

        CTTextCharacterProperties rPr = pr.getRArray(0).getRPr();
        assertTrue(rPr.getB());
        assertTrue(rPr.getI());
        assertEquals(STTextUnderlineType.SNG, rPr.getU());
        assertArrayEquals(
                new byte[]{0, (byte)128, (byte)128} ,
                rPr.getSolidFill().getSrgbClr().getVal());

        checkRewrite(wb);
        wb.close();
    }

    /**
     *  test that anchor is not null when reading shapes from existing drawings
     */
    @Test
    void testReadAnchors() throws IOException {
        XSSFWorkbook wb1 = new XSSFWorkbook();
        XSSFSheet sheet = wb1.createSheet();
        XSSFDrawing drawing = sheet.createDrawingPatriarch();

        XSSFClientAnchor anchor1 = new XSSFClientAnchor(0, 0, 0, 0, 2, 2, 3, 4);
        XSSFShape shape1 = drawing.createTextbox(anchor1);
        assertNotNull(shape1);

        XSSFClientAnchor anchor2 = new XSSFClientAnchor(0, 0, 0, 0, 2, 2, 3, 5);
        XSSFShape shape2 = drawing.createTextbox(anchor2);
        assertNotNull(shape2);

        int pictureIndex= wb1.addPicture(new byte[]{}, XSSFWorkbook.PICTURE_TYPE_PNG);
        XSSFClientAnchor anchor3 = new XSSFClientAnchor(0, 0, 0, 0, 2, 2, 3, 6);
        XSSFShape shape3 = drawing.createPicture(anchor3, pictureIndex);
        assertNotNull(shape3);

        XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1);
        wb1.close();
        sheet = wb2.getSheetAt(0);
        drawing = sheet.createDrawingPatriarch();
        List<XSSFShape> shapes = drawing.getShapes();
        assertEquals(shapes.get(0).getAnchor(), anchor1);
        assertEquals(shapes.get(1).getAnchor(), anchor2);
        assertEquals(shapes.get(2).getAnchor(), anchor3);

        checkRewrite(wb2);
        wb2.close();
    }

    /**
     * ensure that font and color rich text attributes defined in a XSSFRichTextString
     * are passed to XSSFSimpleShape.
     *
     * See Bugzilla 54969.
     */
    @Test
    void testRichTextFontAndColor() throws IOException {
        XSSFWorkbook wb = new XSSFWorkbook();
        XSSFSheet sheet = wb.createSheet();
        XSSFDrawing drawing = sheet.createDrawingPatriarch();

        XSSFTextBox shape = drawing.createTextbox(new XSSFClientAnchor(0, 0, 0, 0, 2, 2, 3, 4));
        XSSFRichTextString rt = new XSSFRichTextString("Test String");

        XSSFFont font = wb.createFont();
        font.setColor(new XSSFColor(new Color(0, 128, 128), wb.getStylesSource().getIndexedColors()));
        font.setFontName("Arial");
        rt.applyFont(font);

        shape.setText(rt);

        CTTextParagraph pr = shape.getCTShape().getTxBody().getPArray(0);
        assertEquals(1, pr.sizeOfRArray());

        CTTextCharacterProperties rPr = pr.getRArray(0).getRPr();
        assertEquals("Arial", rPr.getLatin().getTypeface());
        assertArrayEquals(
                new byte[]{0, (byte)128, (byte)128} ,
                rPr.getSolidFill().getSrgbClr().getVal());
        checkRewrite(wb);
        wb.close();
    }

    /**
     * Test setText single paragraph to ensure backwards compatibility
     */
    @Test
    void testSetTextSingleParagraph() throws IOException {
        XSSFWorkbook wb = new XSSFWorkbook();
        XSSFSheet sheet = wb.createSheet();
        XSSFDrawing drawing = sheet.createDrawingPatriarch();

        XSSFTextBox shape = drawing.createTextbox(new XSSFClientAnchor(0, 0, 0, 0, 2, 2, 3, 4));
        XSSFRichTextString rt = new XSSFRichTextString("Test String");

        XSSFFont font = wb.createFont();
        font.setColor(new XSSFColor(new Color(0, 255, 255), wb.getStylesSource().getIndexedColors()));
        font.setFontName("Arial");
        rt.applyFont(font);

        shape.setText(rt);

        List<XSSFTextParagraph> paras = shape.getTextParagraphs();
        assertEquals(1, paras.size());
        assertEquals("Test String", paras.get(0).getText());

        List<XSSFTextRun> runs = paras.get(0).getTextRuns();
        assertEquals(1, runs.size());
        assertEquals("Arial", runs.get(0).getFontFamily());

        Color clr = runs.get(0).getFontColor();
        assertArrayEquals(
                new int[] { 0, 255, 255 } ,
                new int[] { clr.getRed(), clr.getGreen(), clr.getBlue() });

        checkRewrite(wb);
        wb.close();
    }

    /**
     * Test addNewTextParagraph
     */
    @Test
    void testAddNewTextParagraph() throws IOException {
        XSSFWorkbook wb = new XSSFWorkbook();
        XSSFSheet sheet = wb.createSheet();
        XSSFDrawing drawing = sheet.createDrawingPatriarch();

        XSSFTextBox shape = drawing.createTextbox(new XSSFClientAnchor(0, 0, 0, 0, 2, 2, 3, 4));

        XSSFTextParagraph para = shape.addNewTextParagraph();
        para.addNewTextRun().setText("Line 1");

        List<XSSFTextParagraph> paras = shape.getTextParagraphs();
        assertEquals(2, paras.size());  // this should be 2 as XSSFSimpleShape creates a default paragraph (no text), and then we add a string to that.

        List<XSSFTextRun> runs = para.getTextRuns();
        assertEquals(1, runs.size());
        assertEquals("Line 1", runs.get(0).getText());

        checkRewrite(wb);
        wb.close();
    }

    /**
     * Test addNewTextParagraph using RichTextString
     */
    @Test
    void testAddNewTextParagraphWithRTS() throws IOException {
        XSSFWorkbook wb1 = new XSSFWorkbook();
        XSSFSheet sheet = wb1.createSheet();
        XSSFDrawing drawing = sheet.createDrawingPatriarch();

        XSSFTextBox shape = drawing.createTextbox(new XSSFClientAnchor(0, 0, 0, 0, 2, 2, 3, 4));
        XSSFRichTextString rt = new XSSFRichTextString("Test Rich Text String");

        XSSFFont font = wb1.createFont();
        font.setColor(new XSSFColor(new Color(0, 255, 255), wb1.getStylesSource().getIndexedColors()));
        font.setFontName("Arial");
        rt.applyFont(font);

        XSSFFont midfont = wb1.createFont();
        midfont.setColor(new XSSFColor(new Color(0, 255, 0), wb1.getStylesSource().getIndexedColors()));
        rt.applyFont(5, 14, midfont);   // set the text "Rich Text" to be green and the default font

        XSSFTextParagraph para = shape.addNewTextParagraph(rt);

        // Save and re-load it
        XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1);
        wb1.close();
        sheet = wb2.getSheetAt(0);

        // Check
        drawing = sheet.createDrawingPatriarch();

        List<XSSFShape> shapes = drawing.getShapes();
        assertEquals(1, shapes.size());
        assertTrue(shapes.get(0) instanceof XSSFSimpleShape);

        XSSFSimpleShape sshape = (XSSFSimpleShape) shapes.get(0);

        List<XSSFTextParagraph> paras = sshape.getTextParagraphs();
        assertEquals(2, paras.size());  // this should be 2 as XSSFSimpleShape creates a default paragraph (no text), and then we add a string to that.

        List<XSSFTextRun> runs = para.getTextRuns();
        assertEquals(3, runs.size());

        // first run properties
        assertEquals("Test ", runs.get(0).getText());
        assertEquals("Arial", runs.get(0).getFontFamily());

        Color clr = runs.get(0).getFontColor();
        assertArrayEquals(
                new int[] { 0, 255, 255 } ,
                new int[] { clr.getRed(), clr.getGreen(), clr.getBlue() });

        // second run properties
        assertEquals("Rich Text", runs.get(1).getText());
        assertEquals(XSSFFont.DEFAULT_FONT_NAME, runs.get(1).getFontFamily());

        clr = runs.get(1).getFontColor();
        assertArrayEquals(
                new int[] { 0, 255, 0 } ,
                new int[] { clr.getRed(), clr.getGreen(), clr.getBlue() });

        // third run properties
        assertEquals(" String", runs.get(2).getText());
        assertEquals("Arial", runs.get(2).getFontFamily());
        clr = runs.get(2).getFontColor();
        assertArrayEquals(
                new int[] { 0, 255, 255 } ,
                new int[] { clr.getRed(), clr.getGreen(), clr.getBlue() });

        checkRewrite(wb2);
        wb2.close();
    }

    /**
     * Test add multiple paragraphs and retrieve text
     */
    @Test
    void testAddMultipleParagraphs() throws IOException {
        XSSFWorkbook wb = new XSSFWorkbook();
        XSSFSheet sheet = wb.createSheet();
        XSSFDrawing drawing = sheet.createDrawingPatriarch();

        XSSFTextBox shape = drawing.createTextbox(new XSSFClientAnchor(0, 0, 0, 0, 2, 2, 3, 4));

        XSSFTextParagraph para = shape.addNewTextParagraph();
        para.addNewTextRun().setText("Line 1");

        para = shape.addNewTextParagraph();
        para.addNewTextRun().setText("Line 2");

        para = shape.addNewTextParagraph();
        para.addNewTextRun().setText("Line 3");

        List<XSSFTextParagraph> paras = shape.getTextParagraphs();
        assertEquals(4, paras.size());  // this should be 4 as XSSFSimpleShape creates a default paragraph (no text), and then we added 3 paragraphs
        assertEquals("Line 1\nLine 2\nLine 3", shape.getText());

        checkRewrite(wb);
        wb.close();
    }

    /**
     * Test setting the text, then adding multiple paragraphs and retrieve text
     */
    @Test
    void testSetAddMultipleParagraphs() throws IOException {
        XSSFWorkbook wb = new XSSFWorkbook();
        XSSFSheet sheet = wb.createSheet();
        XSSFDrawing drawing = sheet.createDrawingPatriarch();

        XSSFTextBox shape = drawing.createTextbox(new XSSFClientAnchor(0, 0, 0, 0, 2, 2, 3, 4));

        shape.setText("Line 1");

        XSSFTextParagraph para = shape.addNewTextParagraph();
        para.addNewTextRun().setText("Line 2");

        para = shape.addNewTextParagraph();
        para.addNewTextRun().setText("Line 3");

        List<XSSFTextParagraph> paras = shape.getTextParagraphs();
        assertEquals(3, paras.size());  // this should be 3 as we overwrote the default paragraph with setText, then added 2 new paragraphs
        assertEquals("Line 1\nLine 2\nLine 3", shape.getText());

        checkRewrite(wb);
        wb.close();
    }

    /**
     * Test reading text from a textbox in an existing file
     */
    @Test
    void testReadTextBox() throws IOException {
        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("WithDrawing.xlsx");
        XSSFSheet sheet = wb.getSheetAt(0);
        //the sheet has one relationship and it is XSSFDrawing
        List<RelationPart> rels = sheet.getRelationParts();
        assertEquals(1, rels.size());
        RelationPart rp = rels.get(0);
        assertTrue(rp.getDocumentPart() instanceof XSSFDrawing);

        XSSFDrawing drawing = rp.getDocumentPart();
        //sheet.createDrawingPatriarch() should return the same instance of XSSFDrawing
        assertSame(drawing, sheet.createDrawingPatriarch());
        String drawingId = rp.getRelationship().getId();

        //there should be a relation to this drawing in the worksheet
        assertTrue(sheet.getCTWorksheet().isSetDrawing());
        assertEquals(drawingId, sheet.getCTWorksheet().getDrawing().getId());

        List<XSSFShape> shapes = drawing.getShapes();
        assertEquals(6, shapes.size());

        assertTrue(shapes.get(4) instanceof XSSFSimpleShape);

        XSSFSimpleShape textbox = (XSSFSimpleShape) shapes.get(4);
        assertEquals("Sheet with various pictures\n(jpeg, png, wmf, emf and pict)", textbox.getText());

        checkRewrite(wb);
        wb.close();
    }


    /**
     * Test reading multiple paragraphs from a textbox in an existing file
     */
    @Test
    void testReadTextBoxParagraphs() throws IOException {
        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("WithTextBox.xlsx");
        XSSFSheet sheet = wb.getSheetAt(0);
        //the sheet has one relationship and it is XSSFDrawing
        List<RelationPart> rels = sheet.getRelationParts();
        assertEquals(1, rels.size());
        RelationPart rp = rels.get(0);

        assertTrue(rp.getDocumentPart() instanceof XSSFDrawing);

        XSSFDrawing drawing = rp.getDocumentPart();

        //sheet.createDrawingPatriarch() should return the same instance of XSSFDrawing
        assertSame(drawing, sheet.createDrawingPatriarch());
        String drawingId = rp.getRelationship().getId();

        //there should be a relation to this drawing in the worksheet
        assertTrue(sheet.getCTWorksheet().isSetDrawing());
        assertEquals(drawingId, sheet.getCTWorksheet().getDrawing().getId());

        List<XSSFShape> shapes = drawing.getShapes();
        assertEquals(1, shapes.size());

        assertTrue(shapes.get(0) instanceof XSSFSimpleShape);

        XSSFSimpleShape textbox = (XSSFSimpleShape) shapes.get(0);

        List<XSSFTextParagraph> paras = textbox.getTextParagraphs();
        assertEquals(3, paras.size());

        assertEquals("Line 2", paras.get(1).getText()); // check content of second paragraph

        assertEquals("Line 1\nLine 2\nLine 3", textbox.getText());  // check content of entire textbox

        // check attributes of paragraphs
        assertEquals(TextAlign.LEFT, paras.get(0).getTextAlign());
        assertEquals(TextAlign.CENTER, paras.get(1).getTextAlign());
        assertEquals(TextAlign.RIGHT, paras.get(2).getTextAlign());

        Color clr = paras.get(0).getTextRuns().get(0).getFontColor();
        assertArrayEquals(
                new int[] { 255, 0, 0 } ,
                new int[] { clr.getRed(), clr.getGreen(), clr.getBlue() });

        clr = paras.get(1).getTextRuns().get(0).getFontColor();
        assertArrayEquals(
                new int[] { 0, 255, 0 } ,
                new int[] { clr.getRed(), clr.getGreen(), clr.getBlue() });

        clr = paras.get(2).getTextRuns().get(0).getFontColor();
        assertArrayEquals(
                new int[] { 0, 0, 255 } ,
                new int[] { clr.getRed(), clr.getGreen(), clr.getBlue() });

        checkRewrite(wb);
        wb.close();
    }

    /**
     * Test adding and reading back paragraphs as bullet points
     */
    @Test
    void testAddBulletParagraphs() throws IOException {

        XSSFWorkbook wb1 = new XSSFWorkbook();
        XSSFSheet sheet = wb1.createSheet();
        XSSFDrawing drawing = sheet.createDrawingPatriarch();

        XSSFTextBox shape = drawing.createTextbox(new XSSFClientAnchor(0, 0, 0, 0, 2, 2, 10, 20));

        String paraString1 = "A normal paragraph";
        String paraString2 = "First bullet";
        String paraString3 = "Second bullet (level 1)";
        String paraString4 = "Third bullet";
        String paraString5 = "Another normal paragraph";
        String paraString6 = "First numbered bullet";
        String paraString7 = "Second bullet (level 1)";
        String paraString8 = "Third bullet (level 1)";
        String paraString9 = "Fourth bullet (level 1)";
        String paraString10 = "Fifth Bullet";

        XSSFTextParagraph para = shape.addNewTextParagraph(paraString1);
        assertNotNull(para);
        para = shape.addNewTextParagraph(paraString2);
        para.setBullet(true);

        para = shape.addNewTextParagraph(paraString3);
        para.setBullet(true);
        para.setLevel(1);

        para = shape.addNewTextParagraph(paraString4);
        para.setBullet(true);

        para = shape.addNewTextParagraph(paraString5);
        assertNotNull(para);
        para = shape.addNewTextParagraph(paraString6);
        para.setBullet(ListAutoNumber.ARABIC_PERIOD);

        para = shape.addNewTextParagraph(paraString7);
        para.setBullet(ListAutoNumber.ARABIC_PERIOD, 3);
        para.setLevel(1);

        para = shape.addNewTextParagraph(paraString8);
        para.setBullet(ListAutoNumber.ARABIC_PERIOD, 3);
        para.setLevel(1);

        para = shape.addNewTextParagraph("");
        para.setBullet(ListAutoNumber.ARABIC_PERIOD, 3);
        para.setLevel(1);

        para = shape.addNewTextParagraph(paraString9);
        para.setBullet(ListAutoNumber.ARABIC_PERIOD, 3);
        para.setLevel(1);

        para = shape.addNewTextParagraph(paraString10);
        para.setBullet(ListAutoNumber.ARABIC_PERIOD);

        // Save and re-load it
        XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1);
        wb1.close();
        sheet = wb2.getSheetAt(0);

        // Check
        drawing = sheet.createDrawingPatriarch();

        List<XSSFShape> shapes = drawing.getShapes();
        assertEquals(1, shapes.size());
        assertTrue(shapes.get(0) instanceof XSSFSimpleShape);

        XSSFSimpleShape sshape = (XSSFSimpleShape) shapes.get(0);

        List<XSSFTextParagraph> paras = sshape.getTextParagraphs();
        assertEquals(12, paras.size());  // this should be 12 as XSSFSimpleShape creates a default paragraph (no text), and then we added to that

        String builder =
                paraString1 +
                "\n" +
                "\u2022 " +
                paraString2 +
                "\n" +
                "\t\u2022 " +
                paraString3 +
                "\n" +
                "\u2022 " +
                paraString4 +
                "\n" +
                paraString5 +
                "\n" +
                "1. " +
                paraString6 +
                "\n" +
                "\t3. " +
                paraString7 +
                "\n" +
                "\t4. " +
                paraString8 +
                "\n" +
                "\t" +   // should be empty
                "\n" +
                "\t5. " +
                paraString9 +
                "\n" +
                "2. " +
                paraString10;

        assertEquals(builder, sshape.getText());

        checkRewrite(wb2);
        wb2.close();
    }

    /**
     * Test reading bullet numbering from a textbox in an existing file
     */
    @Test
    void testReadTextBox2() throws IOException {
        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("WithTextBox2.xlsx");
        XSSFSheet sheet = wb.getSheetAt(0);
        XSSFDrawing drawing = sheet.createDrawingPatriarch();
        List<XSSFShape> shapes = drawing.getShapes();
        XSSFSimpleShape textbox = (XSSFSimpleShape) shapes.get(0);
        String extracted = textbox.getText();
        String sb =
                "1. content1A\n" +
                "\t1. content1B\n" +
                "\t2. content2B\n" +
                "\t3. content3B\n" +
                "2. content2A\n" +
                "\t3. content2BStartAt3\n" +
                "\t\n\t\n\t" +
                "4. content2BStartAt3Incremented\n" +
                "\t\n\t\n\t\n\t";

        assertEquals(sb, extracted);
        checkRewrite(wb);
        wb.close();
    }

    @Test
    void testXSSFSimpleShapeCausesNPE56514() throws IOException {
        XSSFWorkbook wb1 = XSSFTestDataSamples.openSampleWorkbook("56514.xlsx");
        XSSFSheet sheet = wb1.getSheetAt(0);
        XSSFDrawing drawing = sheet.createDrawingPatriarch();
        List<XSSFShape> shapes = drawing.getShapes();
        assertEquals(4, shapes.size());

        XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1);
        wb1.close();
        sheet = wb2.getSheetAt(0);
        drawing = sheet.createDrawingPatriarch();

        shapes = drawing.getShapes();
        assertEquals(4, shapes.size());
        wb2.close();
        }

    @Test
    void testXSSFSAddPicture() throws Exception {
        XSSFWorkbook wb1 = new XSSFWorkbook();
        XSSFSheet sheet = wb1.createSheet();
        //multiple calls of createDrawingPatriarch should return the same instance of XSSFDrawing
        XSSFDrawing dr1 = sheet.createDrawingPatriarch();
        XSSFDrawing dr2 = sheet.createDrawingPatriarch();
        assertSame(dr1, dr2);

        List<RelationPart> rels = sheet.getRelationParts();
        assertEquals(1, rels.size());
        RelationPart rp = rels.get(0);
        assertTrue(rp.getDocumentPart() instanceof XSSFDrawing);

        assertEquals(0, rp.getDocumentPart().getRelations().size());

        XSSFDrawing drawing = rp.getDocumentPart();
        String drawingId = rp.getRelationship().getId();

        //there should be a relation to this drawing in the worksheet
        assertTrue(sheet.getCTWorksheet().isSetDrawing());
        assertEquals(drawingId, sheet.getCTWorksheet().getDrawing().getId());

        byte[] pictureData = HSSFTestDataSamples.getTestDataFileContent("45829.png");

        ClientAnchor anchor = wb1.getCreationHelper().createClientAnchor();
        anchor.setCol1(1);
        anchor.setRow1(1);

        drawing.createPicture(anchor, wb1.addPicture(pictureData, Workbook.PICTURE_TYPE_JPEG));
        final int pictureIndex = wb1.addPicture(pictureData, Workbook.PICTURE_TYPE_JPEG);
        drawing.createPicture(anchor, pictureIndex);
        drawing.createPicture(anchor, pictureIndex);

        // repeated additions of same share package relationship
        assertEquals(2, rp.getDocumentPart().getPackagePart().getRelationships().size());

        List<XSSFShape> shapes = drawing.getShapes();
        assertEquals(3, shapes.size());
        assertTrue(shapes.get(0) instanceof XSSFPicture);
        assertTrue(shapes.get(1) instanceof XSSFPicture);

        // Save and re-load it
        XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1);
        wb1.close();
        sheet = wb2.getSheetAt(0);

        // Check
        dr1 = sheet.createDrawingPatriarch();
        CTDrawing ctDrawing = dr1.getCTDrawing();

        // Connector, shapes and text boxes are all two cell anchors
        assertEquals(0, ctDrawing.sizeOfAbsoluteAnchorArray());
        assertEquals(0, ctDrawing.sizeOfOneCellAnchorArray());
        assertEquals(3, ctDrawing.sizeOfTwoCellAnchorArray());

        shapes = dr1.getShapes();
        assertEquals(3, shapes.size());
        assertTrue(shapes.get(0) instanceof XSSFPicture);
        assertTrue(shapes.get(1) instanceof XSSFPicture);

        checkRewrite(wb2);
        wb2.close();
    }

    @Test
    void testBug56835CellComment() throws IOException {
        try (XSSFWorkbook wb = new XSSFWorkbook()) {
            XSSFSheet sheet = wb.createSheet();
            XSSFDrawing drawing = sheet.createDrawingPatriarch();

            // first comment works
            ClientAnchor anchor = new XSSFClientAnchor(1, 1, 2, 2, 3, 3, 4, 4);
            XSSFComment comment = drawing.createCellComment(anchor);
            assertNotNull(comment);

            // Should fail if we try to add the same comment for the same cell
            assertThrows(IllegalArgumentException.class, () -> drawing.createCellComment(anchor));
        }
    }

    @Test
    void testGroupShape() throws Exception {
        XSSFWorkbook wb1 = new XSSFWorkbook();
        XSSFSheet sheet = wb1.createSheet();
        XSSFDrawing drawing = sheet.createDrawingPatriarch();

        XSSFSimpleShape s0 = drawing.createSimpleShape(drawing.createAnchor(0, 0, Units.pixelToEMU(30), Units.pixelToEMU(30), 1, 1, 10, 10));
        s0.setShapeType(ShapeTypes.RECT);
        s0.setLineStyleColor(100, 0, 0);

        XSSFShapeGroup g1 = drawing.createGroup(drawing.createAnchor(0, 0, 300, 300, 1, 1, 10, 10));
        CTGroupTransform2D xfrmG1 = g1.getCTGroupShape().getGrpSpPr().getXfrm();

        XSSFSimpleShape s1 = g1.createSimpleShape(new XSSFChildAnchor(
            (int)(xfrmG1.getChExt().getCx()*0.1),
            (int)(xfrmG1.getChExt().getCy()*0.1),
            (int)(xfrmG1.getChExt().getCx()*0.9),
            (int)(xfrmG1.getChExt().getCy()*0.9)
        ));
        s1.setShapeType(ShapeTypes.RECT);
        s1.setLineStyleColor(0, 100, 0);

        XSSFShapeGroup g2 = g1.createGroup(new XSSFChildAnchor(
            (int)(xfrmG1.getChExt().getCx()*0.2),
            (int)(xfrmG1.getChExt().getCy()*0.2),
            (int)(xfrmG1.getChExt().getCx()*0.8),
            (int)(xfrmG1.getChExt().getCy()*0.8)
        ));
        CTGroupTransform2D xfrmG2 = g2.getCTGroupShape().getGrpSpPr().getXfrm();

        XSSFSimpleShape s2 = g2.createSimpleShape(new XSSFChildAnchor(
            (int)(xfrmG2.getChExt().getCx()*0.1),
            (int)(xfrmG2.getChExt().getCy()*0.1),
            (int)(xfrmG2.getChExt().getCx()*0.9),
            (int)(xfrmG2.getChExt().getCy()*0.9)
        ));
        s2.setShapeType(ShapeTypes.RECT);
        s2.setLineStyleColor(0, 0, 100);

        XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1);
        wb1.close();

        XSSFDrawing draw = wb2.getSheetAt(0).getDrawingPatriarch();
        List<XSSFShape> shapes = draw.getShapes();
        assertEquals(2, shapes.size());
        assertTrue(shapes.get(0) instanceof XSSFSimpleShape);
        assertTrue(shapes.get(1) instanceof XSSFShapeGroup);
        shapes = draw.getShapes((XSSFShapeGroup)shapes.get(1));
        assertEquals(2, shapes.size());
        assertTrue(shapes.get(0) instanceof XSSFSimpleShape);
        assertTrue(shapes.get(1) instanceof XSSFShapeGroup);
        shapes = draw.getShapes((XSSFShapeGroup)shapes.get(1));
        assertEquals(1, shapes.size());
        assertTrue(shapes.get(0) instanceof XSSFSimpleShape);

        wb2.close();
    }

    @Test
    void testBug63901() throws IOException {
        try (XSSFWorkbook workbook = XSSFTestDataSamples.openSampleWorkbook("chartTitle_withTitle.xlsx")) {
            XSSFSheet sheet = workbook.getSheetAt(0);
            XSSFDrawing drawing = sheet.getDrawingPatriarch();
            assertEquals(1, drawing.getCharts().size());

            XSSFWorkbook workbook2 = new XSSFWorkbook();
            XSSFSheet sheet2 = workbook2.createSheet();
            XSSFDrawing drawing2 = sheet2.createDrawingPatriarch();

            drawing.getCharts().forEach(drawing2::importChart);
            assertEquals(1, drawing2.getCharts().size());
        }
    }

    private static void checkRewrite(XSSFWorkbook wb) throws IOException {
        XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb);
        assertNotNull(wb2);
        wb2.close();
    }
}
