au.org.alfred.icu.pdf.services.factories.ICUDischargeSummaryFactory.java Source code

Java tutorial

Introduction

Here is the source code for au.org.alfred.icu.pdf.services.factories.ICUDischargeSummaryFactory.java

Source

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package au.org.alfred.icu.pdf.services.factories;

import au.org.alfred.icu.logging.common.logginglibrary.AbstractLoggingService;
import au.org.alfred.icu.pdf.persistence.TblAntibiotic;
import au.org.alfred.icu.pdf.persistence.TblCarePlan;
import au.org.alfred.icu.pdf.persistence.TblMicroResults;
import au.org.alfred.icu.pdf.persistence.TblNeurology;
import au.org.alfred.icu.pdf.persistence.TblNicotine;
import au.org.alfred.icu.pdf.persistence.TblOtherResults;
import au.org.alfred.icu.pdf.persistence.TblResusPlan;
import au.org.alfred.icu.pdf.persistence.VwSiss;
import java.awt.Color;
import java.io.IOException;
import java.io.InputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.pdfbox.exceptions.COSVisitorException;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDDocumentInformation;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.edit.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.apache.pdfbox.util.PDFTextStripper;

/**
 *
 * @author miguel
 */
public abstract class ICUDischargeSummaryFactory {

    private static final int pageHeight = 842;
    private static final int pageWidth = 595;
    private static final int leftMargin = 30;
    private static final int headerHeight = 127;
    private static final int footerHeight = 57;
    private static final Color darkGreen = new Color(0, 153, 51);
    private static final Color lightGreen = new Color(171, 221, 171);

    public static String loadDischargePDF(InputStream file) throws IOException {
        String pdf_str = null;
        PDDocument doc = PDDocument.load(file);
        int pages = doc.getNumberOfPages();
        //System.out.println(pages);
        PDFTextStripper txt = new PDFTextStripper();
        txt.setStartPage(1);
        txt.setEndPage(1);
        pdf_str = txt.getText(doc);
        /*for(Iterator<COSObject> pdfItr = doc.getDocument().getObjects().iterator(); pdfItr.hasNext();)
         {
         COSObject inner = pdfItr.next();
            
            
         }*/
        //pdf_str = doc.getDocument().getObjects();
        doc.close();
        return pdf_str;
    }

    public static void createDischargeSummaryPDF(PDDocument pdf) {

        PDPage front = new PDPage();
        pdf.addPage(front);

    }

    public static void addDocumentInformation(PDDocument pdf, String title, String subject, String keywords,
            String creator, String author) {

        PDDocumentInformation info = new PDDocumentInformation();

        info.setAuthor(author);
        info.setCreationDate(Calendar.getInstance());
        info.setCreator(creator);
        info.setKeywords(keywords);
        info.setSubject(subject);
        info.setTitle("ICU Discharge Summary");

        pdf.setDocumentInformation(info);

    }

    public static String createContent(PDDocument pdf, String icuVisitNumber, String visitNumber, String patientId,
            String userName, String userId) {
        InputStream is = null;
        int yCursor = 137;
        int temp = yCursor;

        DischargeSummaryData data = new DischargeSummaryData();
        PDPage pg_content;
        PDPageContentStream cs;
        String pdfName = DischargeSummaryDataBuilder.buildData(icuVisitNumber, visitNumber, patientId, userName,
                userId, data);
        try {

            pg_content = new PDPage(new PDRectangle(pageWidth, pageHeight));
            cs = new PDPageContentStream(pdf, pg_content);
            yCursor = createNewPage(pdf, pg_content, cs, yCursor, data);
            Paragraph para = new Paragraph(leftMargin + 5, pageHeight - yCursor - 15, data.getFinalDiagnosis());
            para.withColor(Color.BLACK);
            para.withFont(PDType1Font.TIMES_ROMAN, 12);
            para.withWidth(500);
            temp += para.getParaHeight();

            cs.beginText();
            cs.setFont(PDType1Font.TIMES_BOLD, 14);
            cs.moveTextPositionByAmount(leftMargin, pageHeight - yCursor);
            cs.setNonStrokingColor(darkGreen);
            cs.drawString("Final Diagnosis");
            cs.endText();

            yCursor += para.getFontHeight() * para.getLines().size();

            if (yCursor > (pageHeight - footerHeight)) {
                pg_content = newPageBuilder(pdf, pg_content, cs, data, yCursor);
                cs = new PDPageContentStream(pdf, pg_content);
                yCursor = createNewPage(pdf, pg_content, cs, yCursor, data);
            }

            write(cs, para);

            yCursor += 25;
            para = new Paragraph(leftMargin + 5, pageHeight - yCursor - 15, data.getPresentingHx());
            para.withColor(Color.BLACK);
            para.withFont(PDType1Font.TIMES_ROMAN, 12);
            para.withWidth(500);
            temp = yCursor;
            temp += para.getParaHeight();
            if (temp > (pageHeight - footerHeight)) {
                pg_content = newPageBuilder(pdf, pg_content, cs, data, yCursor);
                cs = new PDPageContentStream(pdf, pg_content);
                yCursor = createNewPage(pdf, pg_content, cs, yCursor, data);
                para = new Paragraph(leftMargin + 5, pageHeight - yCursor - 15, data.getPresentingHx());
                para.withColor(Color.BLACK);
                para.withFont(PDType1Font.TIMES_ROMAN, 12);
                para.withWidth(500);

            }

            cs.beginText();
            cs.setFont(PDType1Font.TIMES_BOLD, 14);
            cs.moveTextPositionByAmount(leftMargin, pageHeight - yCursor);
            cs.setNonStrokingColor(darkGreen);
            cs.drawString("Presenting History");
            cs.endText();
            yCursor += para.getFontHeight() * para.getLines().size();
            write(cs, para);

            yCursor += 25;
            para = new Paragraph(leftMargin + 5, pageHeight - yCursor - 15, data.getPastHx());
            para.withColor(Color.BLACK);
            para.withFont(PDType1Font.TIMES_ROMAN, 12);
            para.withWidth(500);
            temp = yCursor;
            temp += para.getParaHeight();
            if (temp > (pageHeight - footerHeight)) {
                pg_content = newPageBuilder(pdf, pg_content, cs, data, yCursor);
                cs = new PDPageContentStream(pdf, pg_content);
                yCursor = createNewPage(pdf, pg_content, cs, yCursor, data);
                para = new Paragraph(leftMargin + 5, pageHeight - yCursor - 15, data.getPastHx());
                para.withColor(Color.BLACK);
                para.withFont(PDType1Font.TIMES_ROMAN, 12);
                para.withWidth(500);

            }

            cs.beginText();
            cs.setFont(PDType1Font.TIMES_BOLD, 14);
            cs.moveTextPositionByAmount(leftMargin, pageHeight - yCursor);
            cs.setNonStrokingColor(darkGreen);
            cs.drawString("Past History");
            cs.endText();
            yCursor += para.getFontHeight() * para.getLines().size();
            write(cs, para);

            yCursor += 25;
            para = new Paragraph(leftMargin + 5, pageHeight - yCursor - 15, data.getDisSumm());
            para.withColor(Color.BLACK);
            para.withFont(PDType1Font.TIMES_ROMAN, 12);
            para.withWidth(500);
            temp = yCursor;
            temp += para.getParaHeight();
            if (temp > (pageHeight - footerHeight)) {
                List<String> pages = new ArrayList<String>();
                int hght = para.getParaHeight();
                System.out.println("height " + hght);
                if (hght > pageHeight - footerHeight) {
                    while (hght > pageHeight - footerHeight) {
                        String div = data.getDisSumm().substring(0, data.getDisSumm().length() / 2);
                        Paragraph p = new Paragraph(leftMargin + 5, pageHeight - 147 - 15, div);
                        hght = p.getParaHeight();
                        pages.add(div);
                    }
                }
                System.out.println("Pages: " + pages.size());
                if (pages.size() > 1) {
                    Iterator itr = pages.iterator();
                    while (itr.hasNext()) {
                        String inner = (String) itr.next();
                        pg_content = newPageBuilder(pdf, pg_content, cs, data, yCursor);
                        cs = new PDPageContentStream(pdf, pg_content);
                        yCursor = createNewPage(pdf, pg_content, cs, yCursor, data);
                        para = new Paragraph(leftMargin + 5, pageHeight - yCursor - 15, inner);
                        para.withColor(Color.BLACK);
                        para.withFont(PDType1Font.TIMES_ROMAN, 12);
                        para.withWidth(500);
                        cs.beginText();
                        cs.setFont(PDType1Font.TIMES_BOLD, 14);
                        cs.moveTextPositionByAmount(leftMargin, pageHeight - yCursor);
                        cs.setNonStrokingColor(darkGreen);
                        cs.drawString("ICU Stay Summary");
                        cs.endText();
                        yCursor += para.getFontHeight() * para.getLines().size();
                        write(cs, para);
                    }
                } else {
                    pg_content = newPageBuilder(pdf, pg_content, cs, data, yCursor);
                    cs = new PDPageContentStream(pdf, pg_content);
                    yCursor = createNewPage(pdf, pg_content, cs, yCursor, data);
                    para = new Paragraph(leftMargin + 5, pageHeight - yCursor - 15, data.getDisSumm());
                    para.withColor(Color.BLACK);
                    para.withFont(PDType1Font.TIMES_ROMAN, 12);
                    para.withWidth(500);
                }

            }

            cs.beginText();
            cs.setFont(PDType1Font.TIMES_BOLD, 14);
            cs.moveTextPositionByAmount(leftMargin, pageHeight - yCursor);
            cs.setNonStrokingColor(darkGreen);
            cs.drawString("ICU Stay Summary");
            cs.endText();
            yCursor += para.getFontHeight() * para.getLines().size();
            write(cs, para);

            yCursor += 25;
            para = new Paragraph(leftMargin + 5, pageHeight - yCursor - 15, data.getPendingInvestigations());
            para.withColor(Color.BLACK);
            para.withFont(PDType1Font.TIMES_ROMAN, 12);
            para.withWidth(500);
            temp = yCursor;
            temp += para.getParaHeight();
            if (temp > (pageHeight - footerHeight)) {
                pg_content = newPageBuilder(pdf, pg_content, cs, data, yCursor);
                cs = new PDPageContentStream(pdf, pg_content);
                yCursor = createNewPage(pdf, pg_content, cs, yCursor, data);
                para = new Paragraph(leftMargin + 5, pageHeight - yCursor - 15, data.getPendingInvestigations());
                para.withColor(Color.BLACK);
                para.withFont(PDType1Font.TIMES_ROMAN, 12);
                para.withWidth(500);

            }

            cs.beginText();
            cs.setFont(PDType1Font.TIMES_BOLD, 14);
            cs.moveTextPositionByAmount(leftMargin, pageHeight - yCursor);
            cs.setNonStrokingColor(darkGreen);
            cs.drawString("Current Pending Investigations");
            cs.endText();
            yCursor += para.getFontHeight() * para.getLines().size();
            write(cs, para);

            yCursor += 25;

            if (yCursor > (pageHeight - footerHeight)) {
                pg_content = newPageBuilder(pdf, pg_content, cs, data, yCursor);
                cs = new PDPageContentStream(pdf, pg_content);
                yCursor = createNewPage(pdf, pg_content, cs, yCursor, data);
            }

            if (data.getMicro() != null) {
                int k = 0;
                String[][] table = new String[data.getMicro().size() + 1][6];
                table[k][0] = "Date";
                table[k][1] = "Site";
                table[k][2] = "Organism";
                table[k][3] = "Sensitivity";
                table[k][4] = "";
                table[k][5] = "";
                k++;
                for (Iterator<TblMicroResults> i = data.getMicro().iterator(); i.hasNext();) {
                    TblMicroResults m = i.next();
                    table[k][0] = m.getMTime() == null ? "N/A"
                            : new SimpleDateFormat("dd/MM/yy").format(m.getMTime());
                    table[k][1] = m.getMSite() == null ? "N/A" : m.getMSite();
                    table[k][2] = m.getMOrg() == null ? "N/A" : m.getMOrg();
                    table[k][3] = m.getMSens() == null ? "N/A" : m.getMSens();
                    table[k][4] = "";
                    table[k][5] = "";
                    k++;
                }

                //System.out.println(yCursor);
                temp = getTableHeight(pg_content, cs, pageHeight - yCursor, leftMargin, table,
                        PDType1Font.TIMES_BOLD, PDType1Font.TIMES_ROMAN, 10);
                if ((yCursor + temp + 30) > (pageHeight - footerHeight)) {
                    pg_content = newPageBuilder(pdf, pg_content, cs, data, yCursor);
                    cs = new PDPageContentStream(pdf, pg_content);
                    yCursor = createNewPage(pdf, pg_content, cs, yCursor, data);
                }
                yCursor += 25;
                cs.beginText();
                cs.setFont(PDType1Font.TIMES_BOLD, 14);
                cs.moveTextPositionByAmount(leftMargin, pageHeight - yCursor);
                cs.setNonStrokingColor(darkGreen);
                cs.drawString("Microbiology Results");
                cs.endText();

                yCursor += 10;

                yCursor += drawTable(pg_content, cs, pageHeight - yCursor, leftMargin, table,
                        PDType1Font.TIMES_BOLD, PDType1Font.TIMES_ROMAN, 10);

            }

            if (data.getOther() != null) {
                int k = 0;
                String[][] table = new String[data.getOther().size() + 1][6];
                table[k][0] = "Date";
                table[k][1] = "Investigation";
                table[k][2] = "Results";
                table[k][3] = "";
                table[k][4] = "";
                table[k][5] = "";
                k++;
                for (Iterator<TblOtherResults> i = data.getOther().iterator(); i.hasNext();) {
                    TblOtherResults m = i.next();
                    table[k][0] = m.getOTime() == null ? "N/A"
                            : new SimpleDateFormat("dd/MM/yy").format(m.getOTime());
                    table[k][1] = m.getOInv() == null ? "N/A" : m.getOInv();
                    table[k][2] = m.getOResult() == null ? "N/A" : m.getOResult();
                    table[k][3] = "";
                    table[k][4] = "";
                    table[k][5] = "";
                    k++;
                }

                yCursor += 10;
                temp = getTableHeight(pg_content, cs, pageHeight - yCursor, leftMargin, table,
                        PDType1Font.TIMES_BOLD, PDType1Font.TIMES_ROMAN, 10);
                if ((yCursor + temp + 30) > (pageHeight - footerHeight)) {
                    pg_content = newPageBuilder(pdf, pg_content, cs, data, yCursor);
                    cs = new PDPageContentStream(pdf, pg_content);
                    yCursor = createNewPage(pdf, pg_content, cs, yCursor, data);
                }
                yCursor += 25;

                cs.beginText();
                cs.setFont(PDType1Font.TIMES_BOLD, 14);
                cs.moveTextPositionByAmount(leftMargin, pageHeight - yCursor);
                cs.setNonStrokingColor(darkGreen);
                cs.drawString("Other Significant Results");
                cs.endText();
                yCursor += 10;
                yCursor += drawTable(pg_content, cs, pageHeight - yCursor, leftMargin, table,
                        PDType1Font.TIMES_BOLD, PDType1Font.TIMES_ROMAN, 10);

            }

            if (data.getAntibiotics() != null) {
                int k = 0;
                String[][] table = new String[data.getAntibiotics().size() + 1][6];
                table[k][0] = "Start Date";
                table[k][1] = "Suggested End Date";
                table[k][2] = "Antibiotic";
                table[k][3] = "Indication";
                table[k][4] = "";
                table[k][5] = "";

                k++;
                for (Iterator<TblAntibiotic> i = data.getAntibiotics().iterator(); i.hasNext();) {
                    TblAntibiotic m = i.next();
                    table[k][0] = m.getAStart() == null ? "N/A"
                            : new SimpleDateFormat("dd/MM/yy").format(m.getAStart());
                    table[k][1] = m.getAEnd() == null ? "N/A" : m.getAEnd();
                    table[k][2] = m.getAAntibiotic() == null ? "N/A" : m.getAAntibiotic();
                    table[k][3] = m.getAIndication() == null ? "N/A" : m.getAIndication();
                    table[k][4] = "";
                    table[k][5] = "";
                    k++;
                }

                temp = getTableHeight(pg_content, cs, pageHeight - yCursor, leftMargin, table,
                        PDType1Font.TIMES_BOLD, PDType1Font.TIMES_ROMAN, 10);
                if ((yCursor + temp + 30) > (pageHeight - footerHeight)) {
                    pg_content = newPageBuilder(pdf, pg_content, cs, data, yCursor);
                    cs = new PDPageContentStream(pdf, pg_content);
                    yCursor = createNewPage(pdf, pg_content, cs, yCursor, data);
                }
                yCursor += 25;

                cs.beginText();
                cs.setFont(PDType1Font.TIMES_BOLD, 14);
                cs.moveTextPositionByAmount(leftMargin, pageHeight - yCursor);
                cs.setNonStrokingColor(darkGreen);
                cs.drawString("Current Antibiotic Plans");
                cs.endText();
                yCursor += 10;
                yCursor += drawTable(pg_content, cs, pageHeight - yCursor, leftMargin, table,
                        PDType1Font.TIMES_BOLD, PDType1Font.TIMES_ROMAN, 10);

            }

            if (data.getNeuro() != null) {
                int k = 0;
                String[][] table = new String[data.getNeuro().size() + 1][7];
                table[k][0] = "GCS-E";
                table[k][1] = "GCS-V";
                table[k][2] = "GCS-M";
                table[k][3] = "Upper Motor";
                table[k][4] = "Upper Sensation";
                table[k][5] = "Lower Motor";
                table[k][6] = "Lower Sensation";

                k++;
                for (TblNeurology m : data.getNeuro()) {
                    table[k][0] = m.getNGcsE() != null ? m.getNGcsE() : "N/A";
                    table[k][1] = m.getNGcsV() != null ? m.getNGcsV() : "N/A";
                    table[k][2] = m.getNGcsM() != null ? m.getNGcsM() : "N/A";
                    table[k][3] = m.getNUpperMotor() != null ? m.getNUpperMotor() : "N/A";
                    table[k][4] = m.getNUpperSens() != null ? m.getNUpperSens() : "N/A";
                    table[k][5] = m.getNLowerMotor() != null ? m.getNLowerMotor() : "N/A";
                    table[k][6] = m.getNLowerSense() != null ? m.getNLowerSense() : "N/A";
                    k++;
                }

                //System.out.println(table[1][1]);

                temp = getTableHeight(pg_content, cs, pageHeight - yCursor, leftMargin, table,
                        PDType1Font.TIMES_BOLD, PDType1Font.TIMES_ROMAN, 10);
                if ((yCursor + temp + 30) > (pageHeight - footerHeight)) {
                    pg_content = newPageBuilder(pdf, pg_content, cs, data, yCursor);
                    cs = new PDPageContentStream(pdf, pg_content);
                    yCursor = createNewPage(pdf, pg_content, cs, yCursor, data);
                }
                yCursor += 25;

                cs.beginText();
                cs.setFont(PDType1Font.TIMES_BOLD, 14);
                cs.moveTextPositionByAmount(leftMargin, pageHeight - yCursor);
                cs.setNonStrokingColor(darkGreen);
                cs.drawString("Current Neurological Exam");
                cs.endText();
                yCursor += 10;
                yCursor += drawTable(pg_content, cs, pageHeight - yCursor, leftMargin, table,
                        PDType1Font.TIMES_BOLD, PDType1Font.TIMES_ROMAN, 10);

            }

            if (data.getProcs() != null) {
                int k = 0;
                String[][] table = new String[data.getProcs().size() + 1][6];
                table[k][0] = "Start Date";
                table[k][1] = "System";
                table[k][2] = "Intervention";
                table[k][3] = "Type";
                table[k][4] = "Site";
                table[k][5] = "Side";
                k++;
                for (Iterator<VwSiss> i = data.getProcs().iterator(); i.hasNext();) {
                    VwSiss m = i.next();
                    if (m.getSissEndDate() == null) {
                        table[k][0] = new SimpleDateFormat("dd/MM/yy").format(m.getSissStartDate());
                        table[k][1] = m.getSissSystemDesc() == null ? "-" : m.getSissSystemDesc();
                        table[k][2] = m.getSissInterventionDesc() == null ? "-" : m.getSissInterventionDesc();
                        table[k][3] = m.getSissTypeDesc() == null ? "-" : m.getSissTypeDesc();
                        table[k][4] = m.getSissSiteDesc() == null ? "-" : m.getSissSiteDesc();
                        table[k][5] = m.getSissSideDesc() == null ? "-" : m.getSissSideDesc();
                        //System.out.println(table[k][2]);
                        k++;
                    }
                }

                temp = getTableHeight(pg_content, cs, pageHeight - yCursor, leftMargin, table,
                        PDType1Font.TIMES_BOLD, PDType1Font.TIMES_ROMAN, 10);
                if ((yCursor + temp + 30) > (pageHeight - footerHeight)) {
                    pg_content = newPageBuilder(pdf, pg_content, cs, data, yCursor);
                    cs = new PDPageContentStream(pdf, pg_content);
                    yCursor = createNewPage(pdf, pg_content, cs, yCursor, data);
                }

                yCursor += 25;
                cs.beginText();
                cs.setFont(PDType1Font.TIMES_BOLD, 14);
                cs.moveTextPositionByAmount(leftMargin, pageHeight - yCursor);
                cs.setNonStrokingColor(darkGreen);
                cs.drawString("Current In-Situ Devices");
                cs.endText();

                yCursor += 10;

                yCursor += drawTable(pg_content, cs, pageHeight - yCursor, leftMargin, table,
                        PDType1Font.TIMES_BOLD, PDType1Font.TIMES_ROMAN, 10);

            }

            yCursor += 25;
            para = new Paragraph(leftMargin + 5, pageHeight - yCursor - 15, data.getActiveProblems());
            para.withColor(Color.BLACK);
            para.withFont(PDType1Font.TIMES_ROMAN, 12);
            para.withWidth(500);
            temp = yCursor;
            temp += para.getParaHeight();
            if (temp > (pageHeight - footerHeight)) {
                pg_content = newPageBuilder(pdf, pg_content, cs, data, yCursor);
                cs = new PDPageContentStream(pdf, pg_content);
                yCursor = createNewPage(pdf, pg_content, cs, yCursor, data);
                para = new Paragraph(leftMargin + 5, pageHeight - yCursor - 15, data.getActiveProblems());
                para.withColor(Color.BLACK);
                para.withFont(PDType1Font.TIMES_ROMAN, 12);
                para.withWidth(500);

            }

            cs.beginText();
            cs.setFont(PDType1Font.TIMES_BOLD, 14);
            cs.moveTextPositionByAmount(leftMargin, pageHeight - yCursor);
            cs.setNonStrokingColor(darkGreen);
            cs.drawString("Ongoing Issues & Plan");
            cs.endText();
            yCursor += para.getFontHeight() * para.getLines().size();
            write(cs, para);

            // Add Nursing Plan
            pg_content = newPageBuilder(pdf, pg_content, cs, data, yCursor);
            cs = new PDPageContentStream(pdf, pg_content);
            yCursor = createNewPage(pdf, pg_content, cs, yCursor, data);
            cs.beginText();
            cs.setFont(PDType1Font.TIMES_BOLD, 14);
            cs.moveTextPositionByAmount(leftMargin, pageHeight - yCursor);
            cs.setNonStrokingColor(darkGreen);
            cs.drawString("Nursing Plan");
            cs.endText();

            Iterator itr = data.getNursingPlans().keySet().iterator();
            while (itr.hasNext()) {
                String heading = (String) itr.next();
                //System.out.println(heading);
                List<TblCarePlan> plans = (List<TblCarePlan>) data.getNursingPlans().get(heading);
                if (plans.size() > 0) {
                    TblCarePlan plan = plans.get(0);
                    yCursor += 25;
                    para = new Paragraph(leftMargin + 5, pageHeight - yCursor - 15, plan.getCarePlanNote());
                    para.withColor(Color.BLACK);
                    para.withFont(PDType1Font.TIMES_ROMAN, 12);
                    para.withWidth(500);
                    temp = yCursor;
                    temp += para.getParaHeight();
                    if (temp > (pageHeight - footerHeight)) {
                        pg_content = newPageBuilder(pdf, pg_content, cs, data, yCursor);
                        cs = new PDPageContentStream(pdf, pg_content);
                        yCursor = createNewPage(pdf, pg_content, cs, yCursor, data);
                        para = new Paragraph(leftMargin + 5, pageHeight - yCursor - 15, plan.getCarePlanNote());
                        para.withColor(Color.BLACK);
                        para.withFont(PDType1Font.TIMES_ROMAN, 12);
                        para.withWidth(500);

                    }

                    cs.beginText();
                    cs.setFont(PDType1Font.TIMES_BOLD, 14);
                    cs.moveTextPositionByAmount(leftMargin, pageHeight - yCursor);
                    cs.setNonStrokingColor(darkGreen);
                    cs.drawString(heading + " [" + DateFormat.getInstance().format(plan.getUpdateDate()) + "]");
                    cs.endText();
                    yCursor += para.getFontHeight() * para.getLines().size();
                    write(cs, para);
                }

            }
            cs.close();
            pdf.addPage(pg_content);
        } catch (IOException ex) {
            java.util.logging.Logger.getLogger(ICUDischargeSummaryFactory.class.getName()).log(Level.SEVERE, null,
                    ex);
        } finally {
            try {
                if (is != null) {
                    is.close();
                }
            } catch (IOException ex) {
                java.util.logging.Logger.getLogger(ICUDischargeSummaryFactory.class.getName()).log(Level.SEVERE,
                        null, ex);
            }
        }

        return pdfName;

    }

    public static PDPage newPageBuilder(PDDocument pdf, PDPage pg_content, PDPageContentStream cs,
            DischargeSummaryData data, int yCursor) throws IOException {
        pdf.addPage(pg_content);
        cs.close();
        PDPage pg = new PDPage(new PDRectangle(pageWidth, pageHeight));
        return pg;
    }

    public static void createPageTemplate(PDPageContentStream cs, int leftMargin, int pageHeight, int pageWidth,
            DischargeSummaryData data) throws IOException {

        //cs.addRect(0, 0, 595, 127);
        cs.setNonStrokingColor(171, 221, 171);
        cs.fillRect(leftMargin, pageHeight - 127, pageWidth - leftMargin, 127);
        cs.setNonStrokingColor(255, 255, 255);
        cs.fillRect(345 + leftMargin, pageHeight - 120, 210, 110);

        cs.setNonStrokingColor(Color.BLACK);
        cs.beginText();
        cs.setFont(PDType1Font.TIMES_BOLD, 14);
        cs.moveTextPositionByAmount(430 + leftMargin + 10, pageHeight - 22);
        cs.drawString("MRN: " + data.getPatientId());
        cs.endText();
        cs.beginText();
        cs.setFont(PDType1Font.TIMES_ROMAN, 8);
        cs.moveTextPositionByAmount(350 + leftMargin, pageHeight - 25);
        cs.drawString("Visit: " + data.getVisitNumber());
        cs.endText();
        cs.beginText();
        cs.setFont(PDType1Font.TIMES_BOLD, 12);
        cs.moveTextPositionByAmount(350 + leftMargin, pageHeight - 50);
        cs.drawString(data.getPatientFamilyName());
        cs.endText();
        cs.beginText();
        cs.moveTextPositionByAmount(350 + leftMargin, pageHeight - 63);
        cs.drawString(data.getPatientGivenName() + " " + (data.getPatientMiddleName()));
        cs.endText();
        cs.beginText();
        cs.setFont(PDType1Font.TIMES_ROMAN, 8);
        cs.moveTextPositionByAmount(350 + leftMargin, pageHeight - 75);
        cs.drawString(new String().concat("DOB: ").concat(data.getBirthDate()).concat("      ")
                .concat(data.getAge()).concat("yr"));
        cs.endText();
        cs.beginText();
        cs.moveTextPositionByAmount(350 + leftMargin, pageHeight - 85);
        cs.drawString(data.getSexDesc().toUpperCase());
        cs.endText();
        cs.beginText();
        cs.moveTextPositionByAmount(350 + leftMargin, pageHeight - 97);
        cs.drawString(data.getPatientAddress());
        cs.endText();
        cs.beginText();
        cs.moveTextPositionByAmount(350 + leftMargin, pageHeight - 107);
        cs.drawString(data.getUnitCode());
        cs.endText();
        cs.beginText();
        cs.moveTextPositionByAmount(350 + leftMargin, pageHeight - 117);
        cs.drawString(new String().concat("ADM: ").concat(data.getAdmDate()).concat("          F/C: ")
                .concat(data.getPayClass().toUpperCase()));
        cs.endText();
        cs.beginText();
        cs.setFont(PDType1Font.TIMES_BOLD, 10);
        cs.setNonStrokingColor(0, 153, 51);
        cs.moveTextPositionByAmount(5 + leftMargin, pageHeight - 25);
        cs.drawString("THE ALFRED");
        cs.endText();
        cs.beginText();
        cs.setFont(PDType1Font.TIMES_BOLD, 16);
        cs.moveTextPositionByAmount(5 + leftMargin, pageHeight - 87);
        cs.drawString("ICU DISCHARGE SUMMARY");
        cs.endText();
        if (data.getDisSumm() == null || data.getDisSumm().isEmpty() || data.getDisSumm().length() < 2) {
            cs.beginText();
            cs.setNonStrokingColor(Color.BLACK);
            cs.setFont(PDType1Font.TIMES_BOLD, 18);
            cs.moveTextPositionByAmount(5 + leftMargin, pageHeight - 107);
            cs.drawString("DISCHARGE SUMMARY INCOMPLETE");
            cs.endText();

        }
        cs.setNonStrokingColor(171, 221, 171);
        cs.fillRect(leftMargin, 0, 595, 42);
        cs.beginText();
        cs.setNonStrokingColor(0, 153, 51);
        cs.setFont(PDType1Font.TIMES_ROMAN, 10);
        cs.moveTextPositionByAmount(5 + leftMargin, pageHeight - 835);
        cs.drawString(new String().concat("This summary was generated ").concat(data.getUpdateDate()));
        cs.endText();
    }

    public static void saveDocument(String path, PDDocument pdf) throws IOException, COSVisitorException {
        //System.out.println(path);
        pdf.save(path);

    }

    private static void drawBox(PDPageContentStream cs, int bottomX, int bottomY, int width, int height,
            int boxWidth, Color border, Color box) {

        try {
            cs.setNonStrokingColor(border);
            cs.fillRect(bottomX, bottomY, width, height);
            cs.setNonStrokingColor(box);
            cs.fillRect(bottomX + boxWidth, bottomY + boxWidth, width - (2 * boxWidth), height - (2 * boxWidth));
        } catch (IOException ex) {
            AbstractLoggingService.logError(ex.getMessage(), ex);
        }

    }

    private static void drawBoxAndText(PDPageContentStream cs, int bottomX, int bottomY, int width, int height,
            int boxWidth, Color border, Color box, Color textColor, String text, PDFont textFont, int textSize) {

        try {
            float textCenterX = 0;
            float textCenterY = 0;
            textCenterX = bottomX + (width - ((textFont.getStringWidth(text) / 1000) * textSize)) / 2;
            textCenterY = bottomY
                    + ((height + (4 * boxWidth)) - ((textFont.getFontBoundingBox().getHeight() / 1000) * textSize))
                            / 2;
            drawBox(cs, bottomX, bottomY, width, height, boxWidth, border, box);
            cs.beginText();
            cs.setNonStrokingColor(textColor);
            cs.setFont(textFont, textSize);
            cs.moveTextPositionByAmount(textCenterX, textCenterY);
            cs.drawString(text);
            cs.endText();
        } catch (IOException ex) {
            Logger.getLogger(ICUDischargeSummaryFactory.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    private static void write(PDPageContentStream out, Paragraph paragraph) throws IOException {
        out.beginText();
        out.appendRawCommands(paragraph.getFontHeight() + " TL\n");
        out.setFont(paragraph.getFont(), paragraph.getFontSize());
        out.moveTextPositionByAmount(paragraph.getX(), paragraph.getY());
        out.setNonStrokingColor(paragraph.getColor());

        List<String> lines = paragraph.getLines();
        for (Iterator<String> i = lines.iterator(); i.hasNext();) {
            out.drawString(i.next().trim());
            if (i.hasNext()) {
                out.appendRawCommands("T*\n");
            }
        }
        out.endText();

    }

    public static int getTableHeight(PDPage page, PDPageContentStream contentStream, float y, float margin,
            String[][] content, PDFont bold, PDFont font, int fontSize) throws IOException {
        final int rows = content.length;
        final int cols = content[0].length;
        final float rowHeight = font.getFontDescriptor().getFontBoundingBox().getHeight() / 1000 * fontSize;
        final float tableWidth = page.findMediaBox().getWidth() - (2 * margin);
        final float colWidth = tableWidth / (float) cols;
        final float cellMargin = 5f;
        int maxRowHeight = (int) rowHeight;
        float textx = margin + cellMargin;
        float texty = y - rowHeight;
        for (int i = 0; i < content.length; i++) {
            for (int j = 0; j < content[i].length; j++) {
                String text = content[i][j];
                Paragraph para = new Paragraph(textx, texty, text);
                para.withColor(Color.BLACK);
                para.withFont(font, fontSize);
                para.withWidth((int) colWidth);
                textx += colWidth;
                if (para.getParaHeight() > maxRowHeight) {
                    maxRowHeight = para.getParaHeight();
                }
            }
            texty -= maxRowHeight + 2;
            textx = margin + cellMargin;

        }
        final float tableHeight = maxRowHeight * rows;

        return Float.valueOf(tableHeight).intValue();
    }

    public static int drawTable(PDPage page, PDPageContentStream contentStream, float y, float margin,
            String[][] content, PDFont bold, PDFont font, int fontSize) throws IOException {
        final int rows = content.length;
        final int cols = content[0].length;
        final float rowHeight = font.getFontDescriptor().getFontBoundingBox().getHeight() / 1000 * fontSize;
        final float tableWidth = page.findMediaBox().getWidth() - (2 * margin);
        final float colWidth = tableWidth / (float) cols;
        final float cellMargin = 5f;
        int maxRowHeight = (int) rowHeight;
        float textx = margin + cellMargin;
        float texty = y - rowHeight;
        for (int i = 0; i < content.length; i++) {
            for (int j = 0; j < content[i].length; j++) {
                String text = content[i][j];
                Paragraph para = new Paragraph(textx, texty, text);
                para.withColor(Color.BLACK);
                para.withFont(font, fontSize);
                para.withWidth((int) colWidth);
                textx += colWidth;
                if (para.getParaHeight() > maxRowHeight) {
                    maxRowHeight = para.getParaHeight();
                }
            }
            texty -= maxRowHeight + 2;
            textx = margin + cellMargin;

        }
        final float tableHeight = maxRowHeight * rows;

        //draw the rows
        float nexty = y;
        for (int i = 0; i <= rows; i++) {
            contentStream.drawLine(margin, nexty, margin + tableWidth, nexty);
            nexty -= maxRowHeight + 2;
        }

        //draw the columns
        float nextx = margin;
        for (int i = 0; i <= cols; i++) {
            contentStream.drawLine(nextx, pageHeight - y, nextx, pageHeight - y);
            nextx += colWidth;
        }

        //now add the text
        contentStream.setNonStrokingColor(Color.BLACK);
        textx = margin + cellMargin;
        texty = y - maxRowHeight;
        for (int i = 0; i < content.length; i++) {
            for (int j = 0; j < content[i].length; j++) {
                String text = content[i][j];
                float textLeftX = 0;
                float textTopY = 0;
                textLeftX = textx;//+ (font.getStringWidth(text)/1000)*fontSize;
                textTopY = texty
                        + ((maxRowHeight) - ((font.getFontBoundingBox().getHeight() / 1000) * fontSize) + 1);
                Paragraph para = new Paragraph(textLeftX, textTopY, text);
                para.withColor(Color.BLACK);
                para.withWidth((int) colWidth);
                if (i == 0) {
                    para.withFont(bold, fontSize);
                } else {
                    para.withFont(font, fontSize);
                }
                write(contentStream, para);
                textx += colWidth;

            }
            texty -= maxRowHeight + 2;
            textx = margin + cellMargin;

        }
        //System.out.println("yCursor: " + tableHeight + " int " + Float.valueOf(tableHeight).intValue());
        return Float.valueOf(tableHeight).intValue();

    }

    private static int createNewPage(PDDocument pdf, PDPage pg_content, PDPageContentStream cs, int yCursor,
            DischargeSummaryData data) throws IOException {
        yCursor = 147;
        int temp = 0;
        createPageTemplate(cs, leftMargin, pageHeight, pageWidth, data);
        if (pdf.getNumberOfPages() == 0) {

            drawBox(cs, leftMargin, pageHeight - (yCursor + 51), 530, 72, 1, darkGreen, Color.WHITE);

            cs.beginText();
            cs.setFont(PDType1Font.TIMES_BOLD, 10);
            cs.setNonStrokingColor(darkGreen);
            cs.moveTextPositionByAmount(5 + leftMargin, pageHeight - yCursor - 1);
            cs.drawString("ICU Admission Date");
            cs.endText();
            //cs.addRect(leftMargin+5, pageHeight-(yCursor+14), 100, 14);
            drawBoxAndText(cs, leftMargin + 5, pageHeight - (yCursor + 17), 100, 14, 1, darkGreen, Color.WHITE,
                    Color.BLACK, data.getWardAdmDate(), PDType1Font.TIMES_ROMAN, 10);

            cs.beginText();
            cs.setFont(PDType1Font.TIMES_BOLD, 10);
            cs.setNonStrokingColor(darkGreen);
            cs.moveTextPositionByAmount(110 + leftMargin, pageHeight - yCursor - 1);
            cs.drawString("ICU Discharge Date");
            cs.endText();
            //cs.addRect(leftMargin+5, pageHeight-(yCursor+14), 100, 14);
            drawBoxAndText(cs, leftMargin + 110, pageHeight - (yCursor + 17), 100, 14, 1, darkGreen, Color.WHITE,
                    Color.BLACK, data.getWardExitDate(), PDType1Font.TIMES_ROMAN, 10);

            cs.beginText();
            cs.setFont(PDType1Font.TIMES_BOLD, 10);
            cs.setNonStrokingColor(darkGreen);
            cs.moveTextPositionByAmount(leftMargin + 215, pageHeight - yCursor - 1);
            cs.drawString("ICU length of stay");
            cs.endText();
            //cs.addRect(leftMargin+5, pageHeight-(yCursor+14), 100, 14);
            drawBoxAndText(cs, leftMargin + 215, pageHeight - (yCursor + 17), 100, 14, 1, darkGreen, Color.WHITE,
                    Color.BLACK, data.getLOSHours().concat(" hours (").concat(data.getLOSDays()).concat(" days)"),
                    PDType1Font.TIMES_ROMAN, 10);

            cs.beginText();
            cs.setFont(PDType1Font.TIMES_BOLD, 10);
            cs.setNonStrokingColor(darkGreen);
            cs.moveTextPositionByAmount(320 + leftMargin, pageHeight - yCursor - 1);
            cs.drawString("Delayed Discharge");
            cs.endText();
            //cs.addRect(leftMargin+5, pageHeight-(yCursor+14), 100, 14);
            drawBoxAndText(cs, leftMargin + 320, pageHeight - (yCursor + 17), 80, 14, 1, darkGreen, Color.WHITE,
                    Color.BLACK, data.getDelayed(), PDType1Font.TIMES_ROMAN, 10);

            cs.beginText();
            cs.setFont(PDType1Font.TIMES_BOLD, 10);
            cs.setNonStrokingColor(darkGreen);
            cs.moveTextPositionByAmount(405 + leftMargin, pageHeight - yCursor - 1);
            cs.drawString("Early Discharge");
            cs.endText();
            //cs.addRect(leftMargin+5, pageHeight-(yCursor+14), 100, 14);
            drawBoxAndText(cs, leftMargin + 405, pageHeight - (yCursor + 17), 80, 14, 1, darkGreen, Color.WHITE,
                    Color.BLACK, data.getEarlyDischarge(), PDType1Font.TIMES_ROMAN, 10);
            cs.beginText();
            cs.setFont(PDType1Font.TIMES_BOLD, 10);
            cs.setNonStrokingColor(darkGreen);
            cs.moveTextPositionByAmount(490 + leftMargin, pageHeight - yCursor - 1);
            cs.drawString("Adm #");
            cs.endText();
            //cs.addRect(leftMargin+5, pageHeight-(yCursor+14), 100, 14);
            drawBoxAndText(cs, leftMargin + 490, pageHeight - (yCursor + 17), 30, 14, 1, darkGreen, Color.WHITE,
                    Color.BLACK, data.getAdmNumber(), PDType1Font.TIMES_ROMAN, 10);

            yCursor += 34;
            cs.beginText();
            cs.setFont(PDType1Font.TIMES_BOLD, 10);
            cs.setNonStrokingColor(darkGreen);
            cs.moveTextPositionByAmount(5 + leftMargin, pageHeight - yCursor - 1 + 7);
            cs.drawString("APACHE III-J Diagnosis");
            cs.endText();
            drawBoxAndText(cs, leftMargin + 120, pageHeight - yCursor - 1, 400, 15, 1, darkGreen, Color.WHITE,
                    Color.BLACK, data.getApacheIII(), PDType1Font.TIMES_ROMAN, 10);

            if (data.getCurrentLocation() != null) {
                yCursor += 15;
                cs.beginText();
                cs.setFont(PDType1Font.TIMES_BOLD, 10);
                cs.setNonStrokingColor(darkGreen);
                cs.moveTextPositionByAmount(5 + leftMargin, pageHeight - yCursor - 1 + 7);
                cs.drawString("Destination");
                cs.endText();

                drawBoxAndText(cs, leftMargin + 120, pageHeight - yCursor - 1, 400, 15, 1, darkGreen, Color.WHITE,
                        Color.BLACK, data.getCurrentLocation().toUpperCase(), PDType1Font.TIMES_ROMAN, 10);
            }

            yCursor += 15;
            if (data.getResus() != null) {
                int k = 0;
                String[][] table = new String[data.getResus().size() + 1][6];
                table[k][0] = "For CPR";
                table[k][1] = "For Intubation";
                table[k][2] = "For Defib";
                table[k][3] = "For ICU Readmit";
                table[k][4] = "Modified MET Criteria?";
                table[k][5] = "";
                k++;
                for (TblResusPlan m : data.getResus()) {
                    table[k][0] = m.getRCpr() ? "Yes" : "No";
                    table[k][1] = m.getRIntub() ? "Yes" : "No";
                    table[k][2] = m.getRDefib() ? "Yes" : "No";
                    table[k][3] = m.getRReadmit() ? "Yes" : "No";
                    table[k][4] = "".equals(m.getRMetReason()) ? "No" : m.getRMetReason();
                    table[k][5] = "";
                    k++;
                }

                //System.out.println(yCursor);
                temp = getTableHeight(pg_content, cs, pageHeight - yCursor, leftMargin, table,
                        PDType1Font.TIMES_BOLD, PDType1Font.TIMES_ROMAN, 10);
                if ((yCursor + temp + 30) > (pageHeight - footerHeight)) {
                    pg_content = newPageBuilder(pdf, pg_content, cs, data, yCursor);
                    cs = new PDPageContentStream(pdf, pg_content);
                    yCursor = createNewPage(pdf, pg_content, cs, yCursor, data);
                }

                yCursor += 10;

                yCursor += drawTable(pg_content, cs, pageHeight - yCursor, leftMargin, table,
                        PDType1Font.TIMES_BOLD, PDType1Font.TIMES_ROMAN, 10);

                yCursor += 20;
            }

            if (data.getNic() != null) {
                int k = 0;
                String[][] table = new String[data.getNic().size() + 1][6];
                table[k][0] = "Assessed Nicotine Dependent";
                table[k][1] = "Management Offered";
                table[k][2] = "Assessment Date";
                table[k][3] = "Pharmacist";
                table[k][4] = "";
                table[k][5] = "";
                k++;
                for (TblNicotine m : data.getNic()) {
                    table[k][0] = m.getNicDependent() == null ? "N/A" : (m.getNicDependent() == 1 ? "Yes" : "No");
                    table[k][1] = m.getNicMgmOffered() == null ? "N/A" : (m.getNicMgmOffered() == 1 ? "Yes" : "No");
                    table[k][2] = m.getNicDateAssess() == null ? "N/A"
                            : new SimpleDateFormat("dd/MM/yy").format(m.getNicDateAssess());
                    table[k][3] = m.getNicPharmacist() == null ? "N/A" : m.getNicPharmacist();
                    table[k][4] = "";
                    table[k][5] = "";
                    k++;
                }

                //System.out.println(yCursor);
                temp = getTableHeight(pg_content, cs, pageHeight - yCursor, leftMargin, table,
                        PDType1Font.TIMES_BOLD, PDType1Font.TIMES_ROMAN, 10);
                if ((yCursor + temp + 30) > (pageHeight - footerHeight)) {
                    pg_content = newPageBuilder(pdf, pg_content, cs, data, yCursor);
                    cs = new PDPageContentStream(pdf, pg_content);
                    yCursor = createNewPage(pdf, pg_content, cs, yCursor, data);
                }

                yCursor += 10;

                yCursor += drawTable(pg_content, cs, pageHeight - yCursor, leftMargin, table,
                        PDType1Font.TIMES_BOLD, PDType1Font.TIMES_ROMAN, 10);

                yCursor += 20;
            }

        }

        return yCursor;

    }

}