import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.swing.text.AttributeSet;
/**
 *
 * @author mike
 */
public class PDFwriter {
    
    private Font textFont;
    private Font titleFont;
    private Font unicode;
    static private String progNameAndVersion;
            
    public PDFwriter(String s) {
        progNameAndVersion = s;
        FontFactory.registerDirectories();
        textFont = new Font(Font.FontFamily.TIMES_ROMAN, 12,
                                Font.NORMAL, BaseColor.BLACK);
        titleFont = new Font(Font.FontFamily.TIMES_ROMAN, 14,
                                Font.BOLD, BaseColor.BLACK);
        titleFont.setStyle("underline");
        unicode = FontFactory.getFont("Arial Unicode MS", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
    }


    public String writeFile(String fullPathFileName,
                             int orientation,
                             WrapTextPane contentWindow,
                             WrapTextPane structureWindow) {
        // Construct a file name with date from the full path file name
        DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
        String fileName;
        if (fullPathFileName.lastIndexOf("/") == -1)
            fileName = fullPathFileName + " " + dateFormat.format(new Date());
        else
            fileName = fullPathFileName.substring(fullPathFileName.lastIndexOf("/")+1)
                        + " " + dateFormat.format(new Date());

        // PageSize.A4 (595x842), float margins (left, right, top, bottom)
        // Note that the origin is the lower left corner
        Document outDoc = new Document(PageSize.A4, 50, 50, 50, 50);

        try {
            // Create a pdf writer object to write to a file
            PdfWriter writer = PdfWriter.getInstance(outDoc, new FileOutputStream(fullPathFileName));

            // Set the page block size from 36,54 to 559,788
            writer.setBoxSize("art", new Rectangle(36, 54, 559, 788));
            
            HeaderFooter event = new HeaderFooter();
            writer.setPageEvent(event);
            
            outDoc.open();

            // Center the file name and date at the top of the page
            Rectangle rect = writer.getBoxSize("art");
            ColumnText.showTextAligned(writer.getDirectContent(),
                    Element.ALIGN_CENTER, new Phrase(fileName),
                    (rect.getLeft() + rect.getRight()) / 2, rect.getTop()-20, 0);

            if (orientation == 0)
            {
                // Horizontal orientation
                Paragraph subPara = new Paragraph("\n\n");
                subPara.setAlignment(Paragraph.ALIGN_CENTER);
                subPara.add(new Paragraph("Content", titleFont));
                outDoc.add(subPara);

                // degub ++++++++++++++++++++++++++++++++++++
                //subPara = new Paragraph("\n" + contentWindow.getText() + "\n", textFont);
                
                subPara = new Paragraph("\n", textFont);
                // debug ------------------------------------
                AttributeSet attrs;
                int cpos = contentWindow.getCaretPosition();
                for (int i = 0; i < contentWindow.getText().length()-1; ++i)
                {
                    contentWindow.setCaretPosition(i);
                    attrs = contentWindow.getCharacterAttributes();
                    contentWindow.getStyledDocument().setCharacterAttributes(i, 1, attrs, false);
                    outDoc.add(subPara);
                }
                contentWindow.setCaretPosition(cpos);
                subPara = new Paragraph("\n", textFont);
                outDoc.add(subPara);

                subPara = new Paragraph("Structure\n", titleFont);
                subPara.setAlignment(Paragraph.ALIGN_CENTER);
                outDoc.add(subPara);

                subPara = new Paragraph(structureWindow.getText(), unicode);
                outDoc.add(subPara);
            }
            else
            {
                 // Vertical orientation
                MultiColumnText mc = new MultiColumnText(rect.getTop(30), rect.getHeight());
                
                mc.addRegularColumns(rect.getLeft(), rect.getRight(), 20, 2);
                Paragraph subPara = new Paragraph("Content", titleFont);
                subPara.setAlignment(Paragraph.ALIGN_CENTER);
                mc.addElement(subPara);
                outDoc.add(mc);
                subPara = new Paragraph("\n" + contentWindow.getText() + "\n", textFont);
                mc.addElement(subPara);
                outDoc.add(mc);

                mc.nextColumn();
                subPara = new Paragraph("Structure", titleFont);
                subPara.setAlignment(Paragraph.ALIGN_CENTER);
                mc.addElement(subPara);
                outDoc.add(mc);
                subPara = new Paragraph("\n" + structureWindow.getText() + "\n", unicode);
                mc.addElement(subPara);
                outDoc.add(mc);
            }
        } catch (DocumentException ex) {
            return ("File write error");
        } catch (FileNotFoundException ex) {
                return ("File open error");
        }

        if (outDoc != null)
            outDoc.close();
        return null;
    }


    /*
     * This is an inner class to add a header and a footer.
     */
    static class HeaderFooter extends PdfPageEventHelper {

        @Override
        public void onEndPage (PdfWriter writer, Document document) {
            Rectangle rect = writer.getBoxSize("art");

            PdfContentByte b = writer.getDirectContent();
            b.setColorFill(BaseColor.GRAY);
            ColumnText.showTextAligned(b,
                    Element.ALIGN_CENTER, new Phrase(progNameAndVersion),
                    (rect.getLeft() + rect.getRight()) / 2, rect.getTop(), 0);
            ColumnText.showTextAligned(writer.getDirectContent(),
                    Element.ALIGN_RIGHT, new Phrase(String.format("page %d", writer.getPageNumber())),
                    rect.getRight(), rect.getBottom() - 18, 0);
        }
    }
}

