
// WriteSlides.java
// Andrew Davison, ad@coe.psu.ac.th, Nov. 2022

/* Generate the file slidesExample.pptx which
   consists of a few slides, including one with an 
   image (bench.jpg).

   The layout for TITLE_AND_CONTENT is modified to include
   an image and a blue line.

  Usage:
    > compile WriteSlides.java
    > run WriteSlides
*/


import java.io.*;
import java.awt.*;

import org.apache.poi.xslf.usermodel.*;

import org.apache.poi.sl.usermodel.*;
import org.apache.poi.sl.usermodel.PictureData.*;


public class WriteSlides
{
  private static final String SLIDES_FNM = "sampleSlides.pptx";


  public static void main(String args[])
  {
    XMLSlideShow ppt = new XMLSlideShow();
    XSLFSlideMaster master = ppt.getSlideMasters().get(0);

    XSLFSlideLayout layoutTC = setTCBackground("coeHeader.png", master, ppt);

    // slide 1 -- title slide
    System.out.println("Making slide 1");
    XSLFSlideLayout layout1 = master.getLayout(SlideLayout.TITLE);
    XSLFSlide slide1 = ppt.createSlide(layout1);
    XSLFTextShape title = slide1.getPlaceholder(0);
    title.setText("This is a Title");
    XSLFTextShape subtitle = slide1.getPlaceholder(1);
    subtitle.setText("this is a subtitle");

    // slide 2 ----------------------
    System.out.println("Making slide 2");
    XSLFSlide slide2 = ppt.createSlide(layoutTC);
    title = slide2.getPlaceholder(0);
    title.setText("Another Title");
    XSLFTextShape body = slide2.getPlaceholder(1);
    body.clearText();

    // first bullet
    XSLFTextParagraph p1 = body.addNewTextParagraph();
    p1.setIndentLevel(0);
    p1.setBullet(true);
    p1.addNewTextRun().setText("Level1 text");

    XSLFTextParagraph p2 = body.addNewTextParagraph();
    p2.setIndentLevel(1);
    p2.addNewTextRun().setText("Level2 text");

    XSLFTextParagraph p3 = body.addNewTextParagraph();
    p3.setIndentLevel(2);
    p3.addNewTextRun().setText("Level3 text");

    // second bullet
    XSLFTextParagraph p4 = body.addNewTextParagraph();
    XSLFTextRun r1 = p4.addNewTextRun();
    r1.setFontSize(32d);
    r1.setFontColor(Color.RED);
    r1.setText("A larger point");


    // slide 3 ---------------------------------------
    System.out.println("Making slide 3");
    XSLFSlideLayout layout3 = master.getLayout(SlideLayout.TITLE_ONLY);
    XSLFSlide slide3 = ppt.createSlide(layout3);
    title = slide3.getPlaceholder(0);
    title.setText("Slide with a Picture");

    insertPic("bench.jpg", slide3, ppt);


    // slide 4 ---------------------------------------
    System.out.println("Making slide 4");
    XSLFSlide slide4 = ppt.createSlide(layoutTC);  // reuse title+content layout
    title = slide4.getPlaceholder(0);
    title.setText("Numbered Points");
    body = slide4.getPlaceholder(1);
    body.clearText();

    // 3 numbered bullets
    XSLFTextParagraph p5 = body.addNewTextParagraph();
    p5.setBulletAutoNumber(AutoNumberingScheme.arabicPeriod, 1);   // num.
    p5.addNewTextRun().setText("This is my first point");

    XSLFTextParagraph p6 = body.addNewTextParagraph();
    p6.setBulletAutoNumber(AutoNumberingScheme.arabicPeriod, 2);
    p6.addNewTextRun().setText("This is my second point");

    XSLFTextParagraph p7 = body.addNewTextParagraph();
    p7.setBulletAutoNumber(AutoNumberingScheme.arabicPeriod, 3);
    p7.addNewTextRun().setText("This is my third point");


    // ------- save slides --------------
    try (FileOutputStream out = new FileOutputStream(SLIDES_FNM)) {
      System.out.println("Writing slides to " + SLIDES_FNM);
      ppt.write(out);
    }
    catch(Exception e) {
      System.out.println(e);
    }

  } /* main */


  private static XSLFSlideLayout setTCBackground(
             String fnm, XSLFSlideMaster master, XMLSlideShow ppt)
  // insert image background in the TITLE_AND_CONTENT layout
  // and add a line below the title
  {
    XSLFSlideLayout layout = master.getLayout(SlideLayout.TITLE_AND_CONTENT);
    XSLFPictureData pic = loadPicture(fnm, ppt);
    XSLFPictureShape picShape = layout.createPicture(pic);

    Dimension slideSize = ppt.getPageSize();
    Dimension imDim = pic.getImageDimensionInPixels();

    picShape.setAnchor(new Rectangle(10, 10, imDim.width, imDim.height));   
                                // (x,y), width, height

    // add a line
    XSLFAutoShape line = layout.createAutoShape();
    line.setShapeType(ShapeType.LINE);
    line.setAnchor(new Rectangle(15, 100, slideSize.width-30, 0));
    line.setLineColor(Color.BLUE);
    line.setLineWidth(5);

    return layout;
  }  // end of setTCBackground()



  private static void insertPic(String fnm, XSLFSlide slide, 
                                       XMLSlideShow ppt)
  // insert fnm's image in the center of the slide
  {
    XSLFPictureData pic = loadPicture(fnm, ppt);
    XSLFPictureShape picShape = slide.createPicture(pic);

    Dimension slideSize = ppt.getPageSize();
    Dimension imDim = pic.getImageDimensionInPixels();

    int x = (slideSize.width - imDim.width)/2;
    if (x < 0) {
      System.out.println(fnm + " image is too wide");
      x = 0;
    }

    int y = (slideSize.height - imDim.height)/2;
    if (y < 0) {
      System.out.println(fnm + " image is too tall");
      y = 0;
    }

    picShape.setAnchor(new Rectangle(x, y, imDim.width, imDim.height));   
                                // (x,y), width, height
  }  // end of insertPic()



  private static XSLFPictureData loadPicture(String fnm, XMLSlideShow ppt)
  // load fnm's image as a picture
  {
    PictureType type = extToPicType( POIUtils.getExt(fnm));
    try {
      System.out.println("Loading image from " + fnm);
      return ppt.addPicture( new File(fnm), type);
    }
    catch(IOException e)
    {  System.out.println("Could not insert " + fnm);  }

    return null;
  }  // end of loadPicture()


  private static PictureType extToPicType(String ext)
  {
    ext = ext.toLowerCase().trim();
    switch(ext) {
      case "bmp" : return PictureType.BMP;
      case "dib" : return PictureType.DIB;
      case "emf" : return PictureType.EMF;
      case "eps" : return PictureType.EPS;
      case "gif" : return PictureType.GIF;
      case "jpg": case "jpeg" : return PictureType.JPEG;
      case "pict" : return PictureType.PICT;
      case "png" : return PictureType.PNG;
      case "svg" : return PictureType.SVG;
      case "tiff": return PictureType.TIFF;
      case "wmf": return PictureType.WMF;

      default: System.out.println("Unknown picture type ext: " + ext);
               return PictureType.UNKNOWN;
    }
  } // end of extToPicType



} // end of WriteSlides class
