package com.agilex.healthcare.schedulingmanager.pdf;

import com.lowagie.text.*;
import com.lowagie.text.Font;
import com.lowagie.text.Image;
import com.lowagie.text.pdf.*;
import org.apache.commons.io.IOUtils;

import java.awt.*;
import java.io.IOException;
import java.io.InputStream;


public class PageEvent extends PdfPageEventHelper {
	private static final org.apache.commons.logging.Log LOGGER = org.apache.commons.logging.LogFactory.getLog(PageEvent.class);
    private String[] header = new String[2];
    private PdfTemplate totalNumberOfPages;
    private PdfTemplate confidentialWatermark;

    public PageEvent() {
    	header[0] = "";
    	header[1] = "CONFIDENTIAL";
    }
    
    public PageEvent(PdfGenerationContext context) {
    	init(context);
    }
    
    private void init(PdfGenerationContext context) {
    	String firstName = context.getPatient().getFirstName();
    	String lastName = context.getPatient().getLastName();
    	header[0] = String.format("%s, %s", convertToUppercase(lastName), convertToUppercase(firstName));
    	header[1] = "CONFIDENTIAL";
    }
    
    private String convertToUppercase(String value) {
    	return value != null ? value.toUpperCase() : null;
    }
    
    public void onOpenDocument(PdfWriter writer, Document document) {
    	PdfContentByte canvas = writer.getDirectContent();
    	
    	totalNumberOfPages = canvas.createTemplate(30, 16);
		confidentialWatermark = canvas.createTemplate(136, 400);
    	
		InputStream inputStream = null;
    	try {
			inputStream = PageEvent.class.getClassLoader().getResourceAsStream("/com/agilex/healthcare/schedulingmanager/pdf/confidential.png");
    		
			byte[] byteArray = IOUtils.toByteArray(inputStream);
    		inputStream.close();
    		inputStream = null;
    		
			Image image = Image.getInstance(byteArray);
    		image.setCompressionLevel(0);
    		image.setAbsolutePosition(0, 0);
    		confidentialWatermark.addImage(image);
    		writer.releaseTemplate(confidentialWatermark);
    	} catch(IOException e) {
    		if (inputStream != null) {
    			try {
    				inputStream.close();
    			} catch (IOException ioException) {
    				LOGGER.error(ioException);
    			}
    		}
            throw new ExceptionConverter(e);
        } catch(BadElementException e) {
            throw new ExceptionConverter(e);
        } catch(DocumentException e) {
            throw new ExceptionConverter(e);
        }
    }

    public void onStartPage(PdfWriter writer, Document document) {
    }
    
    public void onEndPage(PdfWriter writer, Document document) {
        PdfPTable table = new PdfPTable(4);
        try {
            table.setWidths(new int[]{32, 32, 29, 3});
            table.setTotalWidth(527);
            table.setLockedWidth(true);
    		
            table.addCell(createHeaderCell(header[0], Stylesheet.getNormal(), PdfPCell.ALIGN_LEFT));
            table.addCell(createHeaderCell(header[1], Stylesheet.getBoldLarge(), PdfPCell.ALIGN_CENTER));
            table.addCell(createHeaderCell(String.format("Page %d of", writer.getPageNumber()), Stylesheet.getNormal(), PdfPCell.ALIGN_RIGHT));
            PdfPCell cell = new PdfPCell(Image.getInstance(totalNumberOfPages));
            cell.setBorder(0);
            table.addCell(cell);
            table.writeSelectedRows(0, -1, 34, 828, writer.getDirectContent());
        } catch(DocumentException de) {
            throw new ExceptionConverter(de);
        }
    	PdfContentByte canvas = writer.getDirectContent();
    	canvas.addTemplate(confidentialWatermark, 440, 110);
    }
    
	private PdfPCell createHeaderCell(String value, Font font, int alignment) {
		Phrase phrase = new Phrase(new Chunk(value, font));
		PdfPCell cell = new PdfPCell(phrase);
		cell.setHorizontalAlignment(alignment);
		cell.setBorder(0);
		return cell;
	}
    
    public void onCloseDocument(PdfWriter writer, Document document) {
		Font helvetica = FontFactory.getFont(FontFactory.HELVETICA, 10, Font.NORMAL, Color.black);
        ColumnText.showTextAligned(
        		totalNumberOfPages, 
        		Element.ALIGN_LEFT,
                new Phrase(new Chunk(String.valueOf(writer.getPageNumber() - 1), helvetica)), 
                1, 
                4, 
                0);
    }
}
