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

import static org.apache.poi.sl.usermodel.BaseTestSlideShow.getColor;
import static org.apache.poi.xslf.usermodel.TestXSLFSimpleShape.getSpPr;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
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 static org.junit.jupiter.api.Assumptions.assumeFalse;

import java.awt.Color;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;

import org.apache.poi.POIDataSamples;
import org.apache.poi.sl.usermodel.Placeholder;
import org.apache.poi.sl.usermodel.Shape;
import org.apache.poi.sl.usermodel.SlideShow;
import org.apache.poi.sl.usermodel.SlideShowFactory;
import org.apache.poi.sl.usermodel.TextParagraph.TextAlign;
import org.apache.poi.sl.usermodel.VerticalAlignment;
import org.apache.poi.xddf.usermodel.text.XDDFBodyProperties;
import org.apache.poi.xddf.usermodel.text.XDDFTextBody;
import org.apache.poi.xddf.usermodel.text.XDDFTextParagraph;
import org.apache.poi.xslf.XSLFTestDataSamples;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBodyProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.STTextAlignType;
import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder;
import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType;

class TestXSLFTextShape {
    private static boolean xslfOnly;

    @BeforeAll
    public static void checkHslf() {
        try {
            Class.forName("org.apache.poi.hslf.usermodel.HSLFSlideShow");
        } catch (Exception e) {
            xslfOnly = true;
        }
    }

    @Test
    void testLayouts() throws IOException {
        XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("layouts.pptx");

        List<XSLFSlide> slide = ppt.getSlides();

        verifySlide1(slide.get(0));
        verifySlide2(slide.get(1));
        verifySlide3(slide.get(2));
        verifySlide4(slide.get(3));
        verifySlide7(slide.get(6));
        verifySlide8(slide.get(7));
        verifySlide10(slide.get(9));

        ppt.close();
    }

    void verifySlide1(XSLFSlide slide){
        XSLFSlideLayout layout = slide.getSlideLayout();
        List<XSLFShape> shapes = slide.getShapes();
        assertEquals("Title Slide",layout.getName());

        XSLFTextShape shape1 = (XSLFTextShape)shapes.get(0);
        XDDFTextBody tb1 = shape1.getTextBody();
        XDDFBodyProperties tbp1 = tb1.getBodyProperties();
        CTPlaceholder ph1 = shape1.getPlaceholderDetails().getCTPlaceholder(false);
        assertEquals(STPlaceholderType.CTR_TITLE, ph1.getType());
        // anchor is not defined in the shape
        assertNull(getSpPr(shape1).getXfrm());

        XSLFTextShape masterShape1 = (XSLFTextShape)layout.getPlaceholder(ph1);
        assertNotNull(getSpPr(masterShape1).getXfrm());
        assertEquals(masterShape1.getAnchor(), shape1.getAnchor());

        CTTextBodyProperties bodyPr1 = shape1.getTextBodyPr();
        // none of the following properties are set in the shapes and fetched from the master shape
        assertTrue(
                !bodyPr1.isSetLIns() && !bodyPr1.isSetRIns() &&
                !bodyPr1.isSetBIns() && !bodyPr1.isSetTIns() &&
                !bodyPr1.isSetAnchor()
        );
        assertEquals(7.2, shape1.getLeftInset(), 0);  // 0.1"
        assertEquals(7.2, shape1.getRightInset(), 0); // 0.1"
        assertEquals(3.6, shape1.getTopInset(), 0);  // 0.05"
        assertEquals(3.6, shape1.getBottomInset(), 0); // 0.05"
        assertEquals(VerticalAlignment.MIDDLE, shape1.getVerticalAlignment());
        assertNull(tbp1.getLeftInset());
        assertNull(tbp1.getRightInset());
        assertNull(tbp1.getBottomInset());
        assertNull(tbp1.getTopInset());
        assertNull(tbp1.getAnchoring());

        // now check text properties
        assertEquals("Centered Title", shape1.getText());
        assertEquals("Centered Title",
            tb1.getParagraphs().stream().map(XDDFTextParagraph::getText).collect(Collectors.joining("\n")));
        XSLFTextRun r1 = shape1.getTextParagraphs().get(0).getTextRuns().get(0);
        assertEquals("Calibri", r1.getFontFamily());
        assertEquals(44.0, r1.getFontSize(), 0);
        assertEquals(Color.black, getColor(r1.getFontColor()));

        XSLFTextShape shape2 = (XSLFTextShape)shapes.get(1);
        XDDFTextBody tb2 = shape2.getTextBody();
        XDDFBodyProperties tbp2 = tb2.getBodyProperties();
        CTPlaceholder ph2 = shape2.getPlaceholderDetails().getCTPlaceholder(false);
        assertEquals(STPlaceholderType.SUB_TITLE, ph2.getType());
        // anchor is not defined in the shape
        assertNull(getSpPr(shape2).getXfrm());

        XSLFTextShape masterShape2 = (XSLFTextShape)layout.getPlaceholder(ph2);
        assertNotNull(getSpPr(masterShape2).getXfrm());
        assertEquals(masterShape2.getAnchor(), shape2.getAnchor());

        CTTextBodyProperties bodyPr2 = shape2.getTextBodyPr();
        // none of the following properties are set in the shapes and fetched from the master shape
        assertTrue(
                !bodyPr2.isSetLIns() && !bodyPr2.isSetRIns() &&
                !bodyPr2.isSetBIns() && !bodyPr2.isSetTIns() &&
                !bodyPr2.isSetAnchor()
        );
        assertEquals(7.2, shape2.getLeftInset(), 0);  // 0.1"
        assertEquals(7.2, shape2.getRightInset(), 0); // 0.1"
        assertEquals(3.6, shape2.getTopInset(), 0);  // 0.05"
        assertEquals(3.6, shape2.getBottomInset(), 0); // 0.05"
        assertEquals(VerticalAlignment.TOP, shape2.getVerticalAlignment());
        assertNull(tbp2.getLeftInset());
        assertNull(tbp2.getRightInset());
        assertNull(tbp2.getBottomInset());
        assertNull(tbp2.getTopInset());
        assertNull(tbp2.getAnchoring());

        assertEquals("subtitle", shape2.getText());
        assertEquals("subtitle", tb2.getParagraphs().stream().map(XDDFTextParagraph::getText).collect(Collectors.joining("\n")));
        XSLFTextRun r2 = shape2.getTextParagraphs().get(0).getTextRuns().get(0);
        assertEquals("Calibri", r2.getFontFamily());
        assertEquals(32.0, r2.getFontSize(), 0);
        // TODO fix calculation of tint
        //assertEquals(new Color(137, 137, 137), r2.getFontColor());
    }

    void verifySlide2(XSLFSlide slide){
        XSLFSlideLayout layout = slide.getSlideLayout();
        List<XSLFShape> shapes = slide.getShapes();
        assertEquals("Title and Content",layout.getName());

        XSLFTextShape shape1 = (XSLFTextShape)shapes.get(0);
        CTPlaceholder ph1 = shape1.getPlaceholderDetails().getCTPlaceholder(false);
        assertEquals(STPlaceholderType.TITLE, ph1.getType());
        // anchor is not defined in the shape
        assertNull(getSpPr(shape1).getXfrm());

        XSLFTextShape masterShape1 = (XSLFTextShape)layout.getPlaceholder(ph1);
        // layout does not have anchor info either, it is in the slide master
        assertNull(getSpPr(masterShape1).getXfrm());
        masterShape1 = (XSLFTextShape)layout.getSlideMaster().getPlaceholder(ph1);
        assertNotNull(getSpPr(masterShape1).getXfrm());
        assertEquals(masterShape1.getAnchor(), shape1.getAnchor());

        CTTextBodyProperties bodyPr1 = shape1.getTextBodyPr();
        // none of the following properties are set in the shapes and fetched from the master shape
        assertTrue(
                !bodyPr1.isSetLIns() && !bodyPr1.isSetRIns() &&
                !bodyPr1.isSetBIns() && !bodyPr1.isSetTIns() &&
                !bodyPr1.isSetAnchor()
        );
        assertEquals(7.2, shape1.getLeftInset(), 0);  // 0.1"
        assertEquals(7.2, shape1.getRightInset(), 0); // 0.1"
        assertEquals(3.6, shape1.getTopInset(), 0);  // 0.05"
        assertEquals(3.6, shape1.getBottomInset(), 0); // 0.05"
        assertEquals(VerticalAlignment.MIDDLE, shape1.getVerticalAlignment());

        // now check text properties
        assertEquals("Title", shape1.getText());
        XSLFTextRun r1 = shape1.getTextParagraphs().get(0).getTextRuns().get(0);
        assertEquals("Calibri", r1.getFontFamily());
        assertEquals(44.0, r1.getFontSize(), 0);
        assertEquals(Color.black, getColor(r1.getFontColor()));

        XSLFTextShape shape2 = (XSLFTextShape)shapes.get(1);
        CTPlaceholder ph2 = shape2.getPlaceholderDetails().getCTPlaceholder(false);
        assertFalse(ph2.isSetType()); // <p:ph idx="1"/>
        assertTrue(ph2.isSetIdx());
        assertEquals(1, ph2.getIdx());
        // anchor is not defined in the shape
        assertNull(getSpPr(shape2).getXfrm());

        XSLFTextShape masterShape2 = (XSLFTextShape)layout.getPlaceholder(ph2);
        // anchor of the body text is missing in the slide layout, llokup in the slide master
        assertNull(getSpPr(masterShape2).getXfrm());
        masterShape2 = (XSLFTextShape)layout.getSlideMaster().getPlaceholder(ph2);
        assertNotNull(getSpPr(masterShape2).getXfrm());
        assertEquals(masterShape2.getAnchor(), shape2.getAnchor());

        CTTextBodyProperties bodyPr2 = shape2.getTextBodyPr();
        // none of the following properties are set in the shapes and fetched from the master shape
        assertTrue(
                !bodyPr2.isSetLIns() && !bodyPr2.isSetRIns() &&
                !bodyPr2.isSetBIns() && !bodyPr2.isSetTIns() &&
                !bodyPr2.isSetAnchor()
        );
        assertEquals(7.2, shape2.getLeftInset(), 0);  // 0.1"
        assertEquals(7.2, shape2.getRightInset(), 0); // 0.1"
        assertEquals(3.6, shape2.getTopInset(), 0);  // 0.05"
        assertEquals(3.6, shape2.getBottomInset(), 0); // 0.05"
        assertEquals(VerticalAlignment.TOP, shape2.getVerticalAlignment());

        XSLFTextRun pr1 = shape2.getTextParagraphs().get(0).getTextRuns().get(0);
        assertEquals(0, pr1.getParagraph().getIndentLevel());
        assertEquals("Content", pr1.getRawText());
        assertEquals("Calibri", pr1.getFontFamily());
        assertEquals(32.0, pr1.getFontSize(), 0);
        assertEquals(27.0, pr1.getParagraph().getLeftMargin(), 0);
        assertEquals("\u2022", pr1.getParagraph().getBulletCharacter());
        assertEquals("Arial", pr1.getParagraph().getBulletFont());

        XSLFTextRun pr2 = shape2.getTextParagraphs().get(1).getTextRuns().get(0);
        assertEquals(1, pr2.getParagraph().getIndentLevel());
        assertEquals("Level 2", pr2.getRawText());
        assertEquals("Calibri", pr2.getFontFamily());
        assertEquals(28.0, pr2.getFontSize(), 0);
        assertEquals(58.5, pr2.getParagraph().getLeftMargin(), 0);
        assertEquals("\u2013", pr2.getParagraph().getBulletCharacter());
        assertEquals("Arial", pr2.getParagraph().getBulletFont());

        XSLFTextRun pr3 = shape2.getTextParagraphs().get(2).getTextRuns().get(0);
        assertEquals(2, pr3.getParagraph().getIndentLevel());
        assertEquals("Level 3", pr3.getRawText());
        assertEquals("Calibri", pr3.getFontFamily());
        assertEquals(24.0, pr3.getFontSize(), 0);
        assertEquals(90.0, pr3.getParagraph().getLeftMargin(), 0);
        assertEquals("\u2022", pr3.getParagraph().getBulletCharacter());
        assertEquals("Arial", pr3.getParagraph().getBulletFont());

        XSLFTextRun pr4 = shape2.getTextParagraphs().get(3).getTextRuns().get(0);
        assertEquals(3, pr4.getParagraph().getIndentLevel());
        assertEquals("Level 4", pr4.getRawText());
        assertEquals("Calibri", pr4.getFontFamily());
        assertEquals(20.0, pr4.getFontSize(), 0);
        assertEquals(126.0, pr4.getParagraph().getLeftMargin(), 0);
        assertEquals("\u2013", pr4.getParagraph().getBulletCharacter());
        assertEquals("Arial", pr4.getParagraph().getBulletFont());

        XSLFTextRun pr5 = shape2.getTextParagraphs().get(4).getTextRuns().get(0);
        assertEquals(4, pr5.getParagraph().getIndentLevel());
        assertEquals("Level 5", pr5.getRawText());
        assertEquals("Calibri", pr5.getFontFamily());
        assertEquals(20.0, pr5.getFontSize(), 0);
        assertEquals(162.0, pr5.getParagraph().getLeftMargin(), 0);
        assertEquals("\u00bb", pr5.getParagraph().getBulletCharacter());
        assertEquals("Arial", pr5.getParagraph().getBulletFont());

    }

    void verifySlide3(XSLFSlide slide){
        XSLFSlideLayout layout = slide.getSlideLayout();
        List<XSLFShape> shapes = slide.getShapes();
        assertEquals("Section Header",layout.getName());

        XSLFTextShape shape1 = (XSLFTextShape)shapes.get(0);
        CTPlaceholder ph1 = shape1.getPlaceholderDetails().getCTPlaceholder(false);
        assertEquals(STPlaceholderType.TITLE, ph1.getType());
        // anchor is not defined in the shape
        assertNull(getSpPr(shape1).getXfrm());

        XSLFTextShape masterShape1 = (XSLFTextShape)layout.getPlaceholder(ph1);
        assertNotNull(getSpPr(masterShape1).getXfrm());
        assertEquals(masterShape1.getAnchor(), shape1.getAnchor());

        CTTextBodyProperties bodyPr1 = shape1.getTextBodyPr();
        // none of the following properties are set in the shapes and fetched from the master shape
        assertTrue(
                !bodyPr1.isSetLIns() && !bodyPr1.isSetRIns() &&
                !bodyPr1.isSetBIns() && !bodyPr1.isSetTIns() &&
                !bodyPr1.isSetAnchor()
        );
        assertEquals(7.2, shape1.getLeftInset(), 0);  // 0.1"
        assertEquals(7.2, shape1.getRightInset(), 0); // 0.1"
        assertEquals(3.6, shape1.getTopInset(), 0);  // 0.05"
        assertEquals(3.6, shape1.getBottomInset(), 0); // 0.05"
        assertEquals(VerticalAlignment.TOP, shape1.getVerticalAlignment());

        // now check text properties
        assertEquals("Section Title", shape1.getText());
        XSLFTextRun r1 = shape1.getTextParagraphs().get(0).getTextRuns().get(0);
        assertEquals(TextAlign.LEFT, r1.getParagraph().getTextAlign());
        assertEquals("Calibri", r1.getFontFamily());
        assertEquals(40.0, r1.getFontSize(), 0);
        assertEquals(Color.black, getColor(r1.getFontColor()));
        assertTrue(r1.isBold());
        assertFalse(r1.isItalic());
        assertFalse(r1.isUnderlined());

        XSLFTextShape shape2 = (XSLFTextShape)shapes.get(1);
        CTPlaceholder ph2 = shape2.getPlaceholderDetails().getCTPlaceholder(false);
        assertEquals(STPlaceholderType.BODY, ph2.getType());
        // anchor is not defined in the shape
        assertNull(getSpPr(shape2).getXfrm());

        XSLFTextShape masterShape2 = (XSLFTextShape)layout.getPlaceholder(ph2);
        assertNotNull(getSpPr(masterShape2).getXfrm());
        assertEquals(masterShape2.getAnchor(), shape2.getAnchor());

        CTTextBodyProperties bodyPr2 = shape2.getTextBodyPr();
        // none of the following properties are set in the shapes and fetched from the master shape
        assertTrue(
                !bodyPr2.isSetLIns() && !bodyPr2.isSetRIns() &&
                !bodyPr2.isSetBIns() && !bodyPr2.isSetTIns() &&
                !bodyPr2.isSetAnchor()
        );
        assertEquals(7.2, shape2.getLeftInset(), 0);  // 0.1"
        assertEquals(7.2, shape2.getRightInset(), 0); // 0.1"
        assertEquals(3.6, shape2.getTopInset(), 0);  // 0.05"
        assertEquals(3.6, shape2.getBottomInset(), 0); // 0.05"
        assertEquals(VerticalAlignment.BOTTOM, shape2.getVerticalAlignment());

        assertEquals("Section Header", shape2.getText());
        XSLFTextRun r2 = shape2.getTextParagraphs().get(0).getTextRuns().get(0);
        assertEquals(TextAlign.LEFT, r2.getParagraph().getTextAlign());
        assertEquals("Calibri", r2.getFontFamily());
        assertEquals(20.0, r2.getFontSize(), 0);
        // TODO fix calculation of tint
        //assertEquals(new Color(137, 137, 137), r2.getFontColor());
    }

    void verifySlide4(XSLFSlide slide){
        XSLFSlideLayout layout = slide.getSlideLayout();
        List<XSLFShape> shapes = slide.getShapes();
        assertEquals("Two Content",layout.getName());

        XSLFTextShape shape1 = (XSLFTextShape)shapes.get(0);
        CTPlaceholder ph1 = shape1.getPlaceholderDetails().getCTPlaceholder(false);
        assertEquals(STPlaceholderType.TITLE, ph1.getType());
        // anchor is not defined in the shape
        assertNull(getSpPr(shape1).getXfrm());

        XSLFTextShape masterShape1 = (XSLFTextShape)layout.getPlaceholder(ph1);
        // layout does not have anchor info either, it is in the slide master
        assertNull(getSpPr(masterShape1).getXfrm());
        masterShape1 = (XSLFTextShape)layout.getSlideMaster().getPlaceholder(ph1);
        assertNotNull(getSpPr(masterShape1).getXfrm());
        assertEquals(masterShape1.getAnchor(), shape1.getAnchor());

        CTTextBodyProperties bodyPr1 = shape1.getTextBodyPr();
        // none of the following properties are set in the shapes and fetched from the master shape
        assertTrue(
                !bodyPr1.isSetLIns() && !bodyPr1.isSetRIns() &&
                !bodyPr1.isSetBIns() && !bodyPr1.isSetTIns() &&
                !bodyPr1.isSetAnchor()
        );
        assertEquals(7.2, shape1.getLeftInset(), 0);  // 0.1"
        assertEquals(7.2, shape1.getRightInset(), 0); // 0.1"
        assertEquals(3.6, shape1.getTopInset(), 0);  // 0.05"
        assertEquals(3.6, shape1.getBottomInset(), 0); // 0.05"
        assertEquals(VerticalAlignment.MIDDLE, shape1.getVerticalAlignment());

        // now check text properties
        assertEquals("Title", shape1.getText());
        XSLFTextRun r1 = shape1.getTextParagraphs().get(0).getTextRuns().get(0);
        assertEquals(TextAlign.CENTER, r1.getParagraph().getTextAlign());
        assertEquals("Calibri", r1.getFontFamily());
        assertEquals(44.0, r1.getFontSize(), 0);
        assertEquals(Color.black, getColor(r1.getFontColor()));

        XSLFTextShape shape2 = (XSLFTextShape)shapes.get(1);
        CTPlaceholder ph2 = shape2.getPlaceholderDetails().getCTPlaceholder(false);
        assertFalse(ph2.isSetType());
        assertTrue(ph2.isSetIdx());
        assertEquals(1, ph2.getIdx());  //<p:ph sz="half" idx="1"/>
        // anchor is not defined in the shape
        assertNull(getSpPr(shape2).getXfrm());

        XSLFTextShape masterShape2 = (XSLFTextShape)layout.getPlaceholder(ph2);
        assertNotNull(getSpPr(masterShape2).getXfrm());
        assertEquals(masterShape2.getAnchor(), shape2.getAnchor());

        CTTextBodyProperties bodyPr2 = shape2.getTextBodyPr();
        // none of the following properties are set in the shapes and fetched from the master shape
        assertTrue(
                !bodyPr2.isSetLIns() && !bodyPr2.isSetRIns() &&
                !bodyPr2.isSetBIns() && !bodyPr2.isSetTIns() &&
                !bodyPr2.isSetAnchor()
        );
        assertEquals(7.2, shape2.getLeftInset(), 0);  // 0.1"
        assertEquals(7.2, shape2.getRightInset(), 0); // 0.1"
        assertEquals(3.6, shape2.getTopInset(), 0);  // 0.05"
        assertEquals(3.6, shape2.getBottomInset(), 0); // 0.05"
        assertEquals(VerticalAlignment.TOP, shape2.getVerticalAlignment());

        XSLFTextRun pr1 = shape2.getTextParagraphs().get(0).getTextRuns().get(0);
        assertEquals(0, pr1.getParagraph().getIndentLevel());
        assertEquals("Left", pr1.getRawText());
        assertEquals("Calibri", pr1.getFontFamily());
        assertEquals(28.0, pr1.getFontSize(), 0);
        assertEquals(27.0, pr1.getParagraph().getLeftMargin(), 0);
        assertEquals("\u2022", pr1.getParagraph().getBulletCharacter());
        assertEquals("Arial", pr1.getParagraph().getBulletFont());

        XSLFTextRun pr2 = shape2.getTextParagraphs().get(1).getTextRuns().get(0);
        assertEquals(1, pr2.getParagraph().getIndentLevel());
        assertEquals("Level 2", pr2.getParagraph().getText());
        assertEquals("Calibri", pr2.getFontFamily());
        assertEquals(24.0, pr2.getFontSize(), 0);
        assertEquals(58.5, pr2.getParagraph().getLeftMargin(), 0);
        assertEquals("\u2013", pr2.getParagraph().getBulletCharacter());
        assertEquals("Arial", pr2.getParagraph().getBulletFont());

        XSLFTextRun pr3 = shape2.getTextParagraphs().get(2).getTextRuns().get(0);
        assertEquals(2, pr3.getParagraph().getIndentLevel());
        assertEquals("Level 3", pr3.getParagraph().getText());
        assertEquals("Calibri", pr3.getFontFamily());
        assertEquals(20.0, pr3.getFontSize(), 0);
        assertEquals(90.0, pr3.getParagraph().getLeftMargin(), 0);
        assertEquals("\u2022", pr3.getParagraph().getBulletCharacter());
        assertEquals("Arial", pr3.getParagraph().getBulletFont());

        XSLFTextRun pr4 = shape2.getTextParagraphs().get(3).getTextRuns().get(0);
        assertEquals(3, pr4.getParagraph().getIndentLevel());
        assertEquals("Level 4", pr4.getParagraph().getText());
        assertEquals("Calibri", pr4.getFontFamily());
        assertEquals(18.0, pr4.getFontSize(), 0);
        assertEquals(126.0, pr4.getParagraph().getLeftMargin(), 0);
        assertEquals("\u2013", pr4.getParagraph().getBulletCharacter());
        assertEquals("Arial", pr4.getParagraph().getBulletFont());

        XSLFTextShape shape3 = (XSLFTextShape)shapes.get(2);
        XSLFTextRun pr5 = shape3.getTextParagraphs().get(0).getTextRuns().get(0);
        assertEquals(0, pr5.getParagraph().getIndentLevel());
        assertEquals("Right", pr5.getRawText());
        assertEquals("Calibri", pr5.getFontFamily());
        assertEquals(Color.black, getColor(pr5.getFontColor()));
    }

    @SuppressWarnings("unused")
    void verifySlide5(XSLFSlide slide){
        XSLFSlideLayout layout = slide.getSlideLayout();
        List<XSLFShape> shapes = slide.getShapes();
        // TODO
    }

    void verifySlide7(XSLFSlide slide){
        XSLFSlideLayout layout = slide.getSlideLayout();
        List<XSLFShape> shapes = slide.getShapes();
        assertEquals("Blank",layout.getName());

        XSLFTextShape shape1 = (XSLFTextShape)shapes.get(0);
        CTPlaceholder ph1 = shape1.getPlaceholderDetails().getCTPlaceholder(false);
        assertEquals(STPlaceholderType.TITLE, ph1.getType());
        // anchor is not defined in the shape
        assertNull(getSpPr(shape1).getXfrm());

        CTTextBodyProperties bodyPr1 = shape1.getTextBodyPr();
        // none of the following properties are set in the shapes and fetched from the master shape
        assertTrue(
                !bodyPr1.isSetLIns() && !bodyPr1.isSetRIns() &&
                !bodyPr1.isSetBIns() && !bodyPr1.isSetTIns() &&
                !bodyPr1.isSetAnchor()
        );
        assertEquals(7.2, shape1.getLeftInset(), 0);  // 0.1"
        assertEquals(7.2, shape1.getRightInset(), 0); // 0.1"
        assertEquals(3.6, shape1.getTopInset(), 0);  // 0.05"
        assertEquals(3.6, shape1.getBottomInset(), 0); // 0.05"
        assertEquals(VerticalAlignment.MIDDLE, shape1.getVerticalAlignment());

        // now check text properties
        assertEquals("Blank with Default Title", shape1.getText());
        XSLFTextRun r1 = shape1.getTextParagraphs().get(0).getTextRuns().get(0);
        assertEquals(TextAlign.CENTER, r1.getParagraph().getTextAlign());
        assertEquals("Calibri", r1.getFontFamily());
        assertEquals(44.0, r1.getFontSize(), 0);
        assertEquals(Color.black, getColor(r1.getFontColor()));
        assertFalse(r1.isBold());

        XSLFTextShape shape2 = (XSLFTextShape)shapes.get(1);

        CTTextBodyProperties bodyPr2 = shape2.getTextBodyPr();
        // none of the following properties are set in the shapes and fetched from the master shape
        assertTrue(
                !bodyPr2.isSetLIns() && !bodyPr2.isSetRIns() &&
                !bodyPr2.isSetBIns() && !bodyPr2.isSetTIns() &&
                !bodyPr2.isSetAnchor()
        );
        assertEquals(7.2, shape2.getLeftInset(), 0);  // 0.1"
        assertEquals(7.2, shape2.getRightInset(), 0); // 0.1"
        assertEquals(3.6, shape2.getTopInset(), 0);  // 0.05"
        assertEquals(3.6, shape2.getBottomInset(), 0); // 0.05"
        assertEquals(VerticalAlignment.TOP, shape2.getVerticalAlignment());

        XSLFTextRun pr1 = shape2.getTextParagraphs().get(0).getTextRuns().get(0);
        assertEquals(0, pr1.getParagraph().getIndentLevel());
        assertEquals("Default Text", pr1.getRawText());
        assertEquals("Calibri", pr1.getFontFamily());
        assertEquals(18.0, pr1.getFontSize(), 0);

        XSLFTextShape shape3 = (XSLFTextShape)shapes.get(2);
        assertEquals("Default", shape3.getTextParagraphs().get(0).getText());
        assertEquals("Text with levels", shape3.getTextParagraphs().get(1).getText());
        assertEquals("Level 1", shape3.getTextParagraphs().get(2).getText());
        assertEquals("Level 2", shape3.getTextParagraphs().get(3).getText());
        assertEquals("Level 3", shape3.getTextParagraphs().get(4).getText());

        for(int p = 0; p < 5; p++) {
            XSLFTextParagraph pr = shape3.getTextParagraphs().get(p);
            assertEquals("Calibri", pr.getTextRuns().get(0).getFontFamily());
            assertEquals(18.0, pr.getTextRuns().get(0).getFontSize(), 0);
        }
    }

    void verifySlide8(XSLFSlide slide){
        XSLFSlideLayout layout = slide.getSlideLayout();
        List<XSLFShape> shapes = slide.getShapes();
        assertEquals("Content with Caption",layout.getName());

        XSLFTextShape shape1 = (XSLFTextShape)shapes.get(0);
        CTPlaceholder ph1 = shape1.getPlaceholderDetails().getCTPlaceholder(false);
        assertEquals(STPlaceholderType.TITLE, ph1.getType());
        // anchor is not defined in the shape
        assertNull(getSpPr(shape1).getXfrm());

        XSLFTextShape masterShape1 = (XSLFTextShape)layout.getPlaceholder(ph1);
        // layout does not have anchor info either, it is in the slide master
        assertNotNull(getSpPr(masterShape1).getXfrm());
        assertEquals(masterShape1.getAnchor(), shape1.getAnchor());

        CTTextBodyProperties bodyPr1 = shape1.getTextBodyPr();
        // none of the following properties are set in the shapes and fetched from the master shape
        assertTrue(
                !bodyPr1.isSetLIns() && !bodyPr1.isSetRIns() &&
                !bodyPr1.isSetBIns() && !bodyPr1.isSetTIns() &&
                !bodyPr1.isSetAnchor()
        );
        assertEquals(7.2, shape1.getLeftInset(), 0);  // 0.1"
        assertEquals(7.2, shape1.getRightInset(), 0); // 0.1"
        assertEquals(3.6, shape1.getTopInset(), 0);  // 0.05"
        assertEquals(3.6, shape1.getBottomInset(), 0); // 0.05"
        assertEquals(VerticalAlignment.BOTTOM, shape1.getVerticalAlignment());

        // now check text properties
        assertEquals("Caption", shape1.getText());
        XSLFTextRun r1 = shape1.getTextParagraphs().get(0).getTextRuns().get(0);
        assertEquals(TextAlign.LEFT, r1.getParagraph().getTextAlign());
        assertEquals("Calibri", r1.getFontFamily());
        assertEquals(20.0, r1.getFontSize(), 0);
        assertEquals(Color.black, getColor(r1.getFontColor()));
        assertTrue(r1.isBold());

        XSLFTextShape shape2 = (XSLFTextShape)shapes.get(1);
        CTPlaceholder ph2 = shape2.getPlaceholderDetails().getCTPlaceholder(false);
        assertFalse(ph2.isSetType());
        assertTrue(ph2.isSetIdx());
        assertEquals(1, ph2.getIdx());
        // anchor is not defined in the shape
        assertNull(getSpPr(shape2).getXfrm());

        XSLFTextShape masterShape2 = (XSLFTextShape)layout.getPlaceholder(ph2);
        assertNotNull(getSpPr(masterShape2).getXfrm());
        assertEquals(masterShape2.getAnchor(), shape2.getAnchor());

        CTTextBodyProperties bodyPr2 = shape2.getTextBodyPr();
        // none of the following properties are set in the shapes and fetched from the master shape
        assertTrue(
                !bodyPr2.isSetLIns() && !bodyPr2.isSetRIns() &&
                !bodyPr2.isSetBIns() && !bodyPr2.isSetTIns() &&
                !bodyPr2.isSetAnchor()
        );
        assertEquals(7.2, shape2.getLeftInset(), 0);  // 0.1"
        assertEquals(7.2, shape2.getRightInset(), 0); // 0.1"
        assertEquals(3.6, shape2.getTopInset(), 0);  // 0.05"
        assertEquals(3.6, shape2.getBottomInset(), 0); // 0.05"
        assertEquals(VerticalAlignment.TOP, shape2.getVerticalAlignment());

        XSLFTextRun pr1 = shape2.getTextParagraphs().get(0).getTextRuns().get(0);
        assertEquals(0, pr1.getParagraph().getIndentLevel());
        assertEquals("Level 1", pr1.getRawText());
        assertEquals("Calibri", pr1.getFontFamily());
        assertEquals(32.0, pr1.getFontSize(), 0);
        assertEquals(27.0, pr1.getParagraph().getLeftMargin(), 0);
        assertEquals("\u2022", pr1.getParagraph().getBulletCharacter());
        assertEquals("Arial", pr1.getParagraph().getBulletFont());

        XSLFTextRun pr2 = shape2.getTextParagraphs().get(1).getTextRuns().get(0);
        assertEquals(1, pr2.getParagraph().getIndentLevel());
        assertEquals("Level 2", pr2.getParagraph().getText());
        assertEquals("Calibri", pr2.getFontFamily());
        assertEquals(28.0, pr2.getFontSize(), 0);
        assertEquals(58.5, pr2.getParagraph().getLeftMargin(), 0);
        assertEquals("\u2013", pr2.getParagraph().getBulletCharacter());
        assertEquals("Arial", pr2.getParagraph().getBulletFont());

        XSLFTextRun pr3 = shape2.getTextParagraphs().get(2).getTextRuns().get(0);
        assertEquals(2, pr3.getParagraph().getIndentLevel());
        assertEquals("Level 3", pr3.getParagraph().getText());
        assertEquals("Calibri", pr3.getFontFamily());
        assertEquals(24.0, pr3.getFontSize(), 0);
        assertEquals(90.0, pr3.getParagraph().getLeftMargin(), 0);
        assertEquals("\u2022", pr3.getParagraph().getBulletCharacter());
        assertEquals("Arial", pr3.getParagraph().getBulletFont());

        XSLFTextRun pr4 = shape2.getTextParagraphs().get(3).getTextRuns().get(0);
        assertEquals(3, pr4.getParagraph().getIndentLevel());
        assertEquals("Level 4", pr4.getParagraph().getText());
        assertEquals("Calibri", pr4.getFontFamily());
        assertEquals(20.0, pr4.getFontSize(), 0);
        assertEquals(126.0, pr4.getParagraph().getLeftMargin(), 0);
        assertEquals("\u2013", pr4.getParagraph().getBulletCharacter());
        assertEquals("Arial", pr4.getParagraph().getBulletFont());

        XSLFTextShape shape3 = (XSLFTextShape)shapes.get(2);
        assertEquals(VerticalAlignment.TOP, shape3.getVerticalAlignment());
        assertEquals("Content with caption", shape3.getText());

        pr1 = shape3.getTextParagraphs().get(0).getTextRuns().get(0);
        assertEquals(0, pr1.getParagraph().getIndentLevel());
        assertEquals("Content with caption", pr1.getRawText());
        assertEquals("Calibri", pr1.getFontFamily());
        assertEquals(14.0, pr1.getFontSize(), 0);

    }

    void verifySlide10(XSLFSlide slide){
        XSLFTextShape footer = (XSLFTextShape)slide.getPlaceholderByType(STPlaceholderType.INT_FTR);

        // now check text properties
        assertEquals("Apache Software Foundation", footer.getText());
        assertEquals(VerticalAlignment.MIDDLE, footer.getVerticalAlignment());

        XSLFTextRun r1 = footer.getTextParagraphs().get(0).getTextRuns().get(0);
        assertEquals(TextAlign.CENTER, r1.getParagraph().getTextAlign());
        assertEquals("Calibri", r1.getFontFamily());
        assertEquals(12.0, r1.getFontSize(), 0);
        assertEquals(new Color(0x898989), getColor(r1.getFontColor()));

        XSLFTextShape dt = (XSLFTextShape)slide.getPlaceholderByType(STPlaceholderType.INT_DT);
        assertEquals("Friday, October 21, 2011", dt.getText());

        XSLFTextShape sldNum = (XSLFTextShape)slide.getPlaceholderByType(STPlaceholderType.INT_SLD_NUM);
        assertEquals("10", sldNum.getText());
    }

    @Test
    void testTitleStyles() throws IOException {
        XMLSlideShow ppt = new XMLSlideShow();

        XSLFSlideMaster master = ppt.getSlideMasters().get(0);
        XSLFTheme theme = master.getTheme();
        XSLFSlideLayout layout = master.getLayout(SlideLayout.TITLE);
        XSLFSlide slide = ppt.createSlide(layout) ;
        assertSame(layout, slide.getSlideLayout());
        assertSame(master, slide.getSlideMaster());

        XSLFTextShape titleShape = slide.getPlaceholder(0);
        titleShape.setText("Apache POI");
        XSLFTextParagraph paragraph = titleShape.getTextParagraphs().get(0);
        XSLFTextRun textRun = paragraph.getTextRuns().get(0);

        // level 1 : default title style on the master slide
        // /p:sldMaster/p:txStyles/p:titleStyle/a:lvl1pPr
        CTTextParagraphProperties lv1PPr = master.getXmlObject().getTxStyles().getTitleStyle().getLvl1PPr();
        CTTextCharacterProperties lv1CPr = lv1PPr.getDefRPr();
        assertEquals(4400, lv1CPr.getSz());
        assertEquals(44.0, textRun.getFontSize(), 0);
        assertEquals("+mj-lt", lv1CPr.getLatin().getTypeface());
        assertEquals("Calibri", theme.getMajorFont());
        assertEquals("Calibri", textRun.getFontFamily());
        lv1CPr.setSz(3200);
        assertEquals(32.0, textRun.getFontSize(), 0);
        lv1CPr.getLatin().setTypeface("Arial");
        assertEquals("Arial", textRun.getFontFamily());
        assertEquals(STTextAlignType.CTR, lv1PPr.getAlgn());
        assertEquals(TextAlign.CENTER, paragraph.getTextAlign());
        lv1PPr.setAlgn(STTextAlignType.L);
        assertEquals(TextAlign.LEFT, paragraph.getTextAlign());

        // level 2: title placeholder on the master slide
        // /p:sldMaster/p:cSld/p:spTree/p:sp/p:nvPr/p:ph[@type="title"]
        XSLFTextShape tx2 = master.getPlaceholder(0);
        CTTextParagraphProperties lv2PPr = tx2.getTextBody(true).getLstStyle().addNewLvl1PPr();
        CTTextCharacterProperties lv2CPr = lv2PPr.addNewDefRPr();
        lv2CPr.setSz(3300);
        assertEquals(33.0, textRun.getFontSize(), 0);
        lv2CPr.addNewLatin().setTypeface("Times");
        assertEquals("Times", textRun.getFontFamily());
        lv2PPr.setAlgn(STTextAlignType.R);
        assertEquals(TextAlign.RIGHT, paragraph.getTextAlign());


        // level 3: title placeholder on the slide layout
        // /p:sldLayout /p:cSld/p:spTree/p:sp/p:nvPr/p:ph[@type="ctrTitle"]
        XSLFTextShape tx3 = layout.getPlaceholder(0);
        CTTextParagraphProperties lv3PPr = tx3.getTextBody(true).getLstStyle().addNewLvl1PPr();
        CTTextCharacterProperties lv3CPr = lv3PPr.addNewDefRPr();
        lv3CPr.setSz(3400);
        assertEquals(34.0, textRun.getFontSize(), 0);
        lv3CPr.addNewLatin().setTypeface("Courier New");
        assertEquals("Courier New", textRun.getFontFamily());
        lv3PPr.setAlgn(STTextAlignType.CTR);
        assertEquals(TextAlign.CENTER, paragraph.getTextAlign());

        // level 4: default text properties in the shape itself
        // ./p:sp/p:txBody/a:lstStyle/a:lvl1pPr
        CTTextParagraphProperties lv4PPr = titleShape.getTextBody(true).getLstStyle().addNewLvl1PPr();
        CTTextCharacterProperties lv4CPr = lv4PPr.addNewDefRPr();
        lv4CPr.setSz(3500);
        assertEquals(35.0, textRun.getFontSize(), 0);
        lv4CPr.addNewLatin().setTypeface("Arial");
        assertEquals("Arial", textRun.getFontFamily());
        lv4PPr.setAlgn(STTextAlignType.L);
        assertEquals(TextAlign.LEFT, paragraph.getTextAlign());

        // level 5: text properties are defined in the text run
        CTTextParagraphProperties lv5PPr = paragraph.getXmlObject().addNewPPr();
        CTTextCharacterProperties lv5CPr = textRun.getRPr(false);
        lv5CPr.setSz(3600);
        assertEquals(36.0, textRun.getFontSize(), 0);
        lv5CPr.addNewLatin().setTypeface("Calibri");
        assertEquals("Calibri", textRun.getFontFamily());
        lv5PPr.setAlgn(STTextAlignType.CTR);
        assertEquals(TextAlign.CENTER, paragraph.getTextAlign());

        ppt.close();
    }

    @Test
    void testBodyStyles() throws IOException {
        XMLSlideShow ppt = new XMLSlideShow();

        XSLFSlideMaster master = ppt.getSlideMasters().get(0);
        XSLFTheme theme = master.getTheme();
        XSLFSlideLayout layout = master.getLayout(SlideLayout.TITLE_AND_CONTENT);
        XSLFSlide slide = ppt.createSlide(layout) ;
        assertSame(layout, slide.getSlideLayout());
        assertSame(master, slide.getSlideMaster());

        XSLFTextShape tx1 = slide.getPlaceholder(1);
        tx1.clearText();

        XSLFTextParagraph p1 = tx1.addNewTextParagraph();
        assertEquals(0, p1.getIndentLevel());
        XSLFTextRun r1 = p1.addNewTextRun();
        r1.setText("Apache POI");

        XSLFTextParagraph p2 = tx1.addNewTextParagraph();
        p2.setIndentLevel(1);
        assertEquals(1, p2.getIndentLevel());
        XSLFTextRun r2 = p2.addNewTextRun();
        r2.setText("HSLF");

        XSLFTextParagraph p3 = tx1.addNewTextParagraph();
        p3.setIndentLevel(2);
        assertEquals(2, p3.getIndentLevel());
        XSLFTextRun r3 = p3.addNewTextRun();
        r3.setText("XSLF");

        // level 1 : default title style on the master slide
        // /p:sldMaster/p:txStyles/p:bodyStyle/a:lvl1pPr
        CTTextParagraphProperties lv1PPr = master.getXmlObject().getTxStyles().getBodyStyle().getLvl1PPr();
        CTTextCharacterProperties lv1CPr = lv1PPr.getDefRPr();
        CTTextParagraphProperties lv2PPr = master.getXmlObject().getTxStyles().getBodyStyle().getLvl2PPr();
        CTTextCharacterProperties lv2CPr = lv2PPr.getDefRPr();
        CTTextParagraphProperties lv3PPr = master.getXmlObject().getTxStyles().getBodyStyle().getLvl3PPr();
        CTTextCharacterProperties lv3CPr = lv3PPr.getDefRPr();
        // lv1
        assertEquals(3200, lv1CPr.getSz());
        assertEquals(32.0, r1.getFontSize(), 0);
        assertEquals("+mn-lt", lv1CPr.getLatin().getTypeface());
        assertEquals("Calibri", theme.getMinorFont());
        assertEquals("Calibri", r1.getFontFamily());
        lv1CPr.setSz(3300);
        assertEquals(33.0, r1.getFontSize(), 0);
        lv1CPr.getLatin().setTypeface("Arial");
        assertEquals("Arial", r1.getFontFamily());
        assertEquals(STTextAlignType.L, lv1PPr.getAlgn());
        assertEquals(TextAlign.LEFT, p1.getTextAlign());
        lv1PPr.setAlgn(STTextAlignType.R);
        assertEquals(TextAlign.RIGHT, p1.getTextAlign());
        //lv2
        assertEquals(2800, lv2CPr.getSz());
        assertEquals(28.0, r2.getFontSize(), 0);
        lv2CPr.setSz(3300);
        assertEquals(33.0, r2.getFontSize(), 0);
        lv2CPr.getLatin().setTypeface("Times");
        assertEquals("Times", r2.getFontFamily());
        assertEquals(STTextAlignType.L, lv2PPr.getAlgn());
        assertEquals(TextAlign.LEFT, p2.getTextAlign());
        lv2PPr.setAlgn(STTextAlignType.R);
        assertEquals(TextAlign.RIGHT, p2.getTextAlign());
        //lv3
        assertEquals(2400, lv3CPr.getSz());
        assertEquals(24.0, r3.getFontSize(), 0);
        lv3CPr.setSz(2500);
        assertEquals(25.0, r3.getFontSize(), 0);
        lv3CPr.getLatin().setTypeface("Courier New");
        assertEquals("Courier New", r3.getFontFamily());
        assertEquals(STTextAlignType.L, lv3PPr.getAlgn());
        assertEquals(TextAlign.LEFT, p3.getTextAlign());
        lv3PPr.setAlgn(STTextAlignType.R);
        assertEquals(TextAlign.RIGHT, p3.getTextAlign());


        // level 2: body placeholder on the master slide
        // /p:sldMaster/p:cSld/p:spTree/p:sp/p:nvPr/p:ph[@type="body"]
        XSLFTextShape tx2 = master.getPlaceholder(1);
        assertEquals(Placeholder.BODY, tx2.getTextType());

        lv1PPr = tx2.getTextBody(true).getLstStyle().addNewLvl1PPr();
        lv1CPr = lv1PPr.addNewDefRPr();
        lv2PPr = tx2.getTextBody(true).getLstStyle().addNewLvl2PPr();
        lv2CPr = lv2PPr.addNewDefRPr();
        lv3PPr = tx2.getTextBody(true).getLstStyle().addNewLvl3PPr();
        lv3CPr = lv3PPr.addNewDefRPr();

        lv1CPr.setSz(3300);
        assertEquals(33.0, r1.getFontSize(), 0);
        lv1CPr.addNewLatin().setTypeface("Times");
        assertEquals("Times", r1.getFontFamily());
        lv1PPr.setAlgn(STTextAlignType.L);
        assertEquals(TextAlign.LEFT, p1.getTextAlign());

        lv2CPr.setSz(3300);
        assertEquals(33.0, r2.getFontSize(), 0);
        lv2CPr.addNewLatin().setTypeface("Times");
        assertEquals("Times", r2.getFontFamily());
        lv2PPr.setAlgn(STTextAlignType.L);
        assertEquals(TextAlign.LEFT, p2.getTextAlign());

        lv3CPr.setSz(3300);
        assertEquals(33.0, r3.getFontSize(), 0);
        lv3CPr.addNewLatin().setTypeface("Times");
        assertEquals("Times", r3.getFontFamily());
        lv3PPr.setAlgn(STTextAlignType.L);
        assertEquals(TextAlign.LEFT, p3.getTextAlign());

        // level 3: body placeholder on the slide layout
        // /p:sldLayout /p:cSld/p:spTree/p:sp/p:nvPr/p:ph[@type="ctrTitle"]
        XSLFTextShape tx3 = layout.getPlaceholder(1);
        assertEquals(Placeholder.BODY, tx2.getTextType());
        lv1PPr = tx3.getTextBody(true).getLstStyle().addNewLvl1PPr();
        lv1CPr = lv1PPr.addNewDefRPr();
        lv2PPr = tx3.getTextBody(true).getLstStyle().addNewLvl2PPr();
        lv2CPr = lv2PPr.addNewDefRPr();
        lv3PPr = tx3.getTextBody(true).getLstStyle().addNewLvl3PPr();
        lv3CPr = lv3PPr.addNewDefRPr();

        lv1CPr.setSz(3400);
        assertEquals(34.0, r1.getFontSize(), 0);
        lv1CPr.addNewLatin().setTypeface("Courier New");
        assertEquals("Courier New", r1.getFontFamily());
        lv1PPr.setAlgn(STTextAlignType.CTR);
        assertEquals(TextAlign.CENTER, p1.getTextAlign());

        lv2CPr.setSz(3400);
        assertEquals(34.0, r2.getFontSize(), 0);
        lv2CPr.addNewLatin().setTypeface("Courier New");
        assertEquals("Courier New", r2.getFontFamily());
        lv2PPr.setAlgn(STTextAlignType.CTR);
        assertEquals(TextAlign.CENTER, p2.getTextAlign());

        lv3CPr.setSz(3400);
        assertEquals(34.0, r3.getFontSize(), 0);
        lv3CPr.addNewLatin().setTypeface("Courier New");
        assertEquals("Courier New", r3.getFontFamily());
        lv3PPr.setAlgn(STTextAlignType.CTR);
        assertEquals(TextAlign.CENTER, p3.getTextAlign());

        // level 4: default text properties in the shape itself
        // ./p:sp/p:txBody/a:lstStyle/a:lvl1pPr
        lv1PPr = tx1.getTextBody(true).getLstStyle().addNewLvl1PPr();
        lv1CPr = lv1PPr.addNewDefRPr();
        lv2PPr = tx1.getTextBody(true).getLstStyle().addNewLvl2PPr();
        lv2CPr = lv2PPr.addNewDefRPr();
        lv3PPr = tx1.getTextBody(true).getLstStyle().addNewLvl3PPr();
        lv3CPr = lv3PPr.addNewDefRPr();

        lv1CPr.setSz(3500);
        assertEquals(35.0, r1.getFontSize(), 0);
        lv1CPr.addNewLatin().setTypeface("Arial");
        assertEquals("Arial", r1.getFontFamily());
        lv1PPr.setAlgn(STTextAlignType.L);
        assertEquals(TextAlign.LEFT, p1.getTextAlign());

        lv2CPr.setSz(3500);
        assertEquals(35.0, r2.getFontSize(), 0);
        lv2CPr.addNewLatin().setTypeface("Arial");
        assertEquals("Arial", r2.getFontFamily());
        lv2PPr.setAlgn(STTextAlignType.L);
        assertEquals(TextAlign.LEFT, p2.getTextAlign());

        lv3CPr.setSz(3500);
        assertEquals(35.0, r3.getFontSize(), 0);
        lv3CPr.addNewLatin().setTypeface("Arial");
        assertEquals("Arial", r3.getFontFamily());
        lv3PPr.setAlgn(STTextAlignType.L);
        assertEquals(TextAlign.LEFT, p3.getTextAlign());

        // level 5: text properties are defined in the text run
        lv1PPr = p1.getXmlObject().isSetPPr() ? p1.getXmlObject().getPPr() : p1.getXmlObject().addNewPPr();
        lv1CPr = r1.getRPr(false);
        lv2PPr = p2.getXmlObject().isSetPPr() ? p2.getXmlObject().getPPr() : p2.getXmlObject().addNewPPr();
        lv2CPr = r2.getRPr(false);
        lv3PPr = p3.getXmlObject().isSetPPr() ? p3.getXmlObject().getPPr() : p3.getXmlObject().addNewPPr();
        lv3CPr = r3.getRPr(false);

        lv1CPr.setSz(3600);
        assertEquals(36.0, r1.getFontSize(), 0);
        lv1CPr.addNewLatin().setTypeface("Calibri");
        assertEquals("Calibri", r1.getFontFamily());
        lv1PPr.setAlgn(STTextAlignType.CTR);
        assertEquals(TextAlign.CENTER, p1.getTextAlign());

        lv2CPr.setSz(3600);
        assertEquals(36.0, r2.getFontSize(), 0);
        lv2CPr.addNewLatin().setTypeface("Calibri");
        assertEquals("Calibri", r2.getFontFamily());
        lv2PPr.setAlgn(STTextAlignType.CTR);
        assertEquals(TextAlign.CENTER, p2.getTextAlign());

        lv3CPr.setSz(3600);
        assertEquals(36.0, r3.getFontSize(), 0);
        lv3CPr.addNewLatin().setTypeface("Calibri");
        assertEquals("Calibri", r3.getFontFamily());
        lv3PPr.setAlgn(STTextAlignType.CTR);
        assertEquals(TextAlign.CENTER, p3.getTextAlign());

        ppt.close();
    }

    @Test
    void metroBlob() throws IOException, ReflectiveOperationException {
        assumeFalse(xslfOnly);
        File f = POIDataSamples.getSlideShowInstance().getFile("bug52297.ppt");
        SlideShow<?,?> ppt = SlideShowFactory.create(f);
        Shape<?, ?> sh = ppt.getSlides().get(1).getShapes().get(3);
        XSLFAutoShape xsh = (XSLFAutoShape)sh.getClass().getMethod("getMetroShape").invoke(sh);
        String textExp = " ___ ___ ___ ________ __  _______ ___  ___________  __________ __ _____ ___ ___ ___ _______ ____ ______ ___________  _____________ ___ _______ ______  ____ ______ __ ___________  __________ ___ _________  _____ ________ __________  ___ _______ __________ ";
        String textAct = xsh.getText();
        ppt.close();
        assertEquals(textExp, textAct);
    }
}