
// WriteDoc.java
// Andrew Davison, ad@coe.psu.ac.th, Nov. 2022

/* Generate "hamlet.docx", which consists of several paragraphs,
   including an image (hamlet.png) formatted using a Word table.

  Usage:
    > compile WriteDoc.java
    > run WriteDoc
*/


import java.io.*;
import java.awt.*;

import org.apache.poi.common.usermodel.*;
import org.apache.poi.util.*;
import org.apache.poi.xwpf.usermodel.*;


public class WriteDoc
{  
  private static final String WORD_FNM = "hamlet.docx";


  public static void main(String[] args)
  {
    XWPFDocument doc = new XWPFDocument();

    // ------- paragraph 1 --------------
    System.out.println("Writing paragraph 1");
    XWPFParagraph p1 = doc.createParagraph();
    p1.setAlignment(ParagraphAlignment.CENTER);
    XWPFRun r1 = p1.createRun();
    r1.setBold(true);
    r1.setFontSize(20);
    r1.setFontFamily("Times New Roman");
    r1.setUnderline(UnderlinePatterns.SINGLE);
    r1.setColor("0000ff");
    r1.setText("Hamlet");


    // ------- picture paragraph/table --------------
/*
    System.out.println("Loading image into a paragraph");

    XWPFParagraph imPara = doc.createParagraph();
    imPara.setAlignment(ParagraphAlignment.CENTER);

    XWPFRun imRun = imPara.createRun();
    imRun.setTextPosition(40);   // distance between image and text below
    insertPic("hamlet.png", imRun, 0.5);
*/

    System.out.println("Loading image into a table");
    // put picture in a 1x2 table
    XWPFTable picTable = doc.createTable(1, 2);   // no. rows and cols
    picTable.removeBorders();
    picTable.setWidth("100%");

    // add text to the left hand side of the 2-cell table
    XWPFTableCell cell = picTable.getRow(0).getCell(0);
    XWPFParagraph para = cell.getParagraphs().get(0); 

    // text alignment
    cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
    para.setAlignment(ParagraphAlignment.CENTER);

    XWPFRun prun = para.createRun();
    prun.setText("The text under consideration:");

    // add image to the right hand side of the 2-cell table
    para = picTable.getRow(0).getCell(1).
                               getParagraphs().get(0); 
    prun = para.createRun();
    prun.setTextPosition(40);   // distance between image and text below
    insertPic("hamlet.png", prun, 0.5);


    // ------- paragraph 2 --------------
    System.out.println("Writing paragraph 2");
    XWPFParagraph p2 = doc.createParagraph();
    XWPFRun r2a = p2.createRun();
    r2a.setFontSize(12);
    r2a.setFontFamily("Times New Roman");
    r2a.setText("The text of ");

    XWPFRun r2b = p2.createRun();
    r2b.setFontSize(12);
    r2b.setFontFamily("Times New Roman");
    r2b.setItalic(true);
    r2b.setText("Hamlet");

    XWPFRun r2c = p2.createRun();
    r2c.setFontSize(12);
    r2c.setFontFamily("Times New Roman");
    r2c.setText(" presents great difficulties, and any discussion of it affects and is affected by our understanding of the play. I have not therefore been able to separate my account of the text from the main part of the introduction, as is the custom in this series. In trying to offer help towards the understanding of this great and perplexing play, it is essential to make clear at the outset that there is more than one Hamlet we might be talking about.");

    // ------- paragraph 3 --------------
    System.out.println("Writing paragraph 3");
    XWPFParagraph p3 = doc.createParagraph();
    XWPFRun r3 = p3.createRun();
    r3.setFontSize(12);
    r3.setFontFamily("Lucida Handwriting");

    r3.setText("To be, or not to be: that is the question \u2013");  // dash
    r3.addBreak();
    r3.setText("Whether 'tis nobler in the mind to suffer");
    r3.addBreak();
    r3.setText("The slings and arrows of outrageous fortune,");
    r3.addBreak();
    r3.setText("Or to take arms against a sea of troubles,");
    r3.addBreak();
    r3.setText("And by opposing end them. To die, to sleep \u2013");
    r3.addBreak();
    r3.setText("No more; and by a sleep to say we end");
    r3.addBreak();
    r3.setText("The heart-ache and the thousand natural shocks");
    r3.addBreak();
    r3.setText("That flesh is heir to \u2013 'tis a consummation");
    r3.addBreak();
    r3.setText("Devoutly to be wished. To die, to sleep \u2013");
    r3.addBreak();
    r3.setText("To sleep, perchance to dream.");
    r3.addBreak();

    // ------- save doc --------------
    try (FileOutputStream out = new FileOutputStream(WORD_FNM)) {
      System.out.println("Writing document to " + WORD_FNM);
      doc.write(out);
    }
    catch(Exception e) {
      System.out.println(e);
    }
  } /* main */



  private static void insertPic(String fnm, XWPFRun imRun)
  {  insertPic(fnm, imRun, 1.0);  }


  private static void insertPic(String fnm, XWPFRun imRun, double scale)
  // insert fnm's image in the paragraph
  {
    PictureType type = extToPicType( POIUtils.getExt(fnm));
    Dimension imDim = POIUtils.getImageSize(fnm);
    try {
      imRun.addPicture( new FileInputStream( new File(fnm)),
                       type, fnm,
                       Units.toEMU(imDim.width*scale), 
                       Units.toEMU(imDim.height*scale));  // points -> emu
    }
    catch(Exception e)
    {  System.out.println("Could not insert " + fnm);  }
  }  // end of insertPic()


  public 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 WriteDoc class
