package lu.tudor.santec.gecamed.formeditor.gui;

import java.io.ByteArrayInputStream;
import java.io.ObjectInputStream;
import java.util.HashMap;

import lu.tudor.santec.gecamed.core.ejb.entity.beans.Template;
import lu.tudor.santec.gecamed.core.gui.widgets.PrintPreviewDialog;
import lu.tudor.santec.gecamed.core.gui.widgets.print.PrintParameterFetcher;
import lu.tudor.santec.gecamed.formeditor.gui.component.EditableComponent;
import lu.tudor.santec.gecamed.formeditor.gui.model.FormModel;
import lu.tudor.santec.gecamed.patient.ejb.entity.beans.Incident;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.design.JasperDesign;
import net.sf.jasperreports.engine.xml.JRXmlLoader;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;


/**
 * @author Jens Ferring
 * 
 * The class takes the global iReport and the iReport for the form template,
 * respectively an image of the current form and places it into the header
 * of the global iReport.
 * The report needs to be compiled everytime again, because the form needs
 * to be placed into the global iReport and into the parameter.
 */

public class FormPrinter 
{
	/* ======================================== */
	// 		CONSTANTS
	/* ======================================== */
	
	public  static final String DEFAULT_TEMPLATE_NAME 		= "FormPrintTemplate.jrxml";
	public  static final String FORM_PRINT_TEMPLATE_TYPE 	= "form_template_def"; 
//	private static final String SUBREPORT_KEY 				= "SUBREPORT";
//	private static final String IMAGE_KEY 					= "FORMIMAGE";
	
	
	
	/* ======================================== */
	// 		MEMBERS
	/* ======================================== */
	
	/** the logger Object for this class */
	private static Logger logger = Logger.getLogger(FormPrinter.class.getName());
	
//	private static UtilFormatter 		templateFormatter 	= new UtilFormatter();
	private static PrintPreviewDialog 	printPreviewDialog 	= new PrintPreviewDialog();
	
	private FormModel model;
	
	
	
	/* ======================================== */
	// 		CONSTRUCTORS
	/* ======================================== */
	
	public FormPrinter (FormModel formModel) 
	{
		this.model = formModel;
	}
	
	
	
	/* ======================================== */
	// 		PRINT
	/* ======================================== */
	
//	@SuppressWarnings("unchecked")
	public void print () 
	{
		try {
			ByteArrayInputStream bais;
			JasperReport	subreportData;
			JasperDesign	jasperDesign;
			JasperPrint		jasperPrint;
			String			keyName;
			Incident		incident		= model.getForm().getIncidentEntry().getIncident();
			Template 		reportTemplate	= model.getTemplate().getJasperTemplate();
			
//			TemplateManagerInterface templateManager = (TemplateManagerInterface)ManagerFactory
//					.getRemote(TemplateManagerBean.class);
			HashMap<String, Object> parameter = PrintParameterFetcher.createDefaultPrintParameter(incident);
			
			
//			JasperDesign design = null;
//			try {
//				Template printTemplate = templateManager.getTemplate(FORM_PRINT_TEMPLATE_TYPE, 
//						MainFrame.getCurrentPhysician().getId(), model.getDateCreated());
//				
//				if (printTemplate != null) 
//				{
//					try {
//						design = JRXmlLoader.load(new ByteArrayInputStream(printTemplate.getJrxml()));
//					} 
//					catch (JRException jre) 
//					{
//						logger.log(Level.ERROR, jre.getMessage(), jre);
//					}
//				} 
//				if (design == null) 
//					design = JRXmlLoader.load(FormWidgets.getFileAsStream(FormEditorModule.class, "templates/", DEFAULT_TEMPLATE_NAME));
//			} 
//			catch (Exception e) 
//			{
//				logger.log(Level.ERROR, e.getMessage(), e);
//			}
//			if (design == null) 
//				return;
//			
//			// the form is supposed to be printed into the column header
//			JRBand pageHeader = design.getPageHeader();
//			
//			if (pageHeader.getHeight() <= 0) 
//			{
//				return;
//			}
//			
//			// the list to add the subreport or image, when created
//			List<Object> children = pageHeader.getChildren();
			
			
			if (reportTemplate != null
					&& (reportTemplate.getJasper() != null
							|| reportTemplate.getJrxml() != null)) 
			{
				// a report template exists: add it to the page header

				/* **********  load the stored report  ********** */
				
				byte[] jasper = reportTemplate.getJasper();
				if (jasper != null) 
				{
					ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(jasper));

					// the from the JRXML-file converted subreport data 
					subreportData = (JasperReport)ois.readObject();
				} 
				else 
				{
					// create the design
					bais = null;
					try
					{
						bais = new ByteArrayInputStream(reportTemplate.getJrxml());
						jasperDesign = JRXmlLoader.load(bais);
					}
					catch (Exception e)
					{
						throw e;
					}
					finally
					{
						if (bais != null) bais.close();
					}
							
					
					// create the JasperReport
//					subreportData = compileReport(jasperDesign);
					subreportData = JasperCompileManager.compileReport(jasperDesign);
				}
				
				// Add the JasperReport as parameter with the key of the subreport, 
				// which will be created in the following.
//				parameter.put(SUBREPORT_KEY, subreportData);
				/* **************************************** */
				
				/* **********  create the subreport-tag  ********** */
//				JRDesignSubreport subreportTag = new JRDesignSubreport(design);
//				subreportTag.setX(0);
//				subreportTag.setY(0);
//				subreportTag.setHeight(pageHeader.getHeight());
//				subreportTag.setWidth(design.getPageWidth());
				/* **************************************** */
				
				/* **********  create the sub-report-expression  ********** */
//				JRDesignExpression expression = new JRDesignExpression();
//				expression.addParameterChunk(SUBREPORT_KEY);
//				expression.setValueClass(subreportData.getClass());
//				subreportTag.setExpression(expression);
				/* **************************************** */
				
				/* **********  create the sub-report-parameter  ********** */
//				JRDesignParameter subreportParameter = new JRDesignParameter();
//				subreportParameter.setName(SUBREPORT_KEY);
//				subreportParameter.setValueClass(subreportData.getClass());
//				design.addParameter(subreportParameter);
				/* **************************************** */

				/* **********  add the EditableComponents as parameter  ********** */
//				JRDesignSubreportParameter srParameter;
//				JRDesignParameter reportParameter;
				
				if (model.getEditableComponents() != null
						&& model.getEditableComponents().values() != null) 
				{
					for (EditableComponent c : model.getEditableComponents().values()) 
					{
						keyName	= c.getKey();
						keyName	= keyName.substring(0, 1).toUpperCase() + keyName.substring(1);
						parameter.put("var" + keyName, c);
						parameter.put("com" + keyName, c.getComponent());
						parameter.put("str" + keyName, c.print());
						
//						reportParameter = new JRDesignParameter();
//						reportParameter.setName(c.getKey());
//						reportParameter.setValueClass(String.class);
//						reportParameter.setForPrompting(true);
//						design.addParameter(reportParameter);
						
//						srParameter = new JRDesignSubreportParameter();
//						srParameter.setName(c.getKey());
//						expression = new JRDesignExpression();
//						expression.setValueClass(String.class);
//						expression.addParameterChunk(c.getKey());
//						srParameter.setExpression(expression);
//						subreportTag.addParameter(srParameter);
					}
				}
				/* **************************************** */
				
//				design.addImport("java.io.*");

				// add the subreport as child of the pageHeader
//				children.add(subreportTag);
			}
			else 
			{
				return;
//				// no report template exists: create an image of the panel and add it to the page header
//				
//				/* **********  create the design of the image  ********** */
//				JRDesignImage jrImage = new JRDesignImage(design);
//				jrImage.setScaleImage(ScaleImageEnum.RETAIN_SHAPE);
////				jrImage.setScaleImage(JRImage.SCALE_IMAGE_RETAIN_SHAPE);
//				jrImage.setX(0);
//				jrImage.setY(0);
//				jrImage.setWidth(design.getPageWidth());
//				jrImage.setHeight(pageHeader.getHeight());
//				/* **************************************** */
//				
//				/* **********  create the expression of the image  ********** */
//				JRDesignExpression expression = new JRDesignExpression();
//				expression.addParameterChunk(IMAGE_KEY);
//				expression.setValueClass(java.awt.Image.class);
//				jrImage.setExpression(expression);
//				/* **************************************** */
//				
//				/* **********  add the parameter for the image  ********** */
//				JRDesignParameter formImageParameter = new JRDesignParameter();
//				formImageParameter.setName(IMAGE_KEY);
//				formImageParameter.setValueClass(java.awt.Image.class);
//				design.addParameter(formImageParameter);
//				/* **************************************** */
//				
//				design.addImport("java.awt.*");
//				
//				// add the image as child of the pageHeader
//				children.add(jrImage);
//				
//				BackgroundPanel panel = model.getPanel();
//				
//				Image image = getFormImage(panel, 
//						design.getPageHeader().getHeight(), design.getPageWidth());
//				
//				parameter.put(IMAGE_KEY, image);
//				/* ---------------------------------------- */
			}
			
			/* **********  create the report and print it  ********** */
//			JasperReport jasperReport = templateManager.compileReport(design);
			
//			JasperPrint jasperPrint = JasperFillManager.fillReport(
//					jasperReport, parameter);
			
			jasperPrint = JasperFillManager.fillReport(
					subreportData, parameter);
			
			printPreviewDialog.doPrint(jasperPrint);
			/* **************************************** */
		} catch (Exception e) {
			logger.log(Level.ERROR, e.getMessage(), e);
		}
		/* ======================================== */
	}
	
	
	/**
	 * This method creates an image of the form
	 * 
	 * @param panel <br> the panel where the form is placed in
	 * @param imageHeight <br> the height of the image
	 * @return
	 */
//	private Image getFormImage(JPanel panel, int imageHeight, int pageWidth) 
//	{
//		BufferedImage image = null;
//		try {
//			panel.setOpaque(true);
//			panel.setBackground(Color.WHITE);
//			panel.repaint();
//			
//			int bandHeight 		= imageHeight;
//			int bandWidth 		= pageWidth;
//			
//			int leftSpace 		= -1;
//			int rightmostPoint 	= 0;
//			int topSpace 		= -1;
//			int deepestPoint 	= 0;
//
//			for (Component c : panel.getComponents()) 
//			{
//				if (leftSpace == -1 
//						|| c.getX() < leftSpace) {
//					leftSpace = c.getX();
//				} 
//
//				if (c.getX() + c.getWidth() > rightmostPoint)
//					rightmostPoint = c.getX() + c.getWidth();
//
//				if (topSpace == -1
//						|| c.getY() < topSpace)
//					topSpace = c.getY();
//
//				if (c.getY() + c.getHeight() > deepestPoint)
//					deepestPoint = c.getY() + c.getHeight();
//			}
//
//			int x = leftSpace;
//			int y = topSpace;
//			int width = rightmostPoint - x;
//			int height = deepestPoint - y;
//			
//			image = new BufferedImage(//panel.getWidth(), panel.getHeight(), BufferedImage.TYPE_INT_RGB);
//					rightmostPoint > bandWidth ? rightmostPoint : bandWidth, 
//					deepestPoint > bandHeight ? deepestPoint : bandHeight, 
//					BufferedImage.TYPE_INT_RGB);
//
//			Graphics2D g2 = image.createGraphics();
//			g2.setBackground(Color.WHITE);
//			panel.paint(g2);
//			
//			// cut the left and top border
//			g2.copyArea(x, y, width, height, -x, -y);
//			g2.clearRect(width, 0, image.getWidth(), image.getHeight());
//			g2.clearRect(0, height, image.getWidth(), image.getHeight());
//			
//			image = image.getSubimage(0, 0, 
//					//panel.getWidth(), panel.getHeight());
//					// width > bandWidth ? bandWidth : width,
//					/* if the image needn't be scaled down, take the band width,
//					 * else take the image calculated width
//					 */
//					(width < bandWidth && height < bandHeight ? bandWidth : width),
//					// height > bandHeight ? bandHeight : height);
//					height);	
//			
//			g2.dispose();
//		} 
//		finally 
//		{
//			panel.setOpaque(false);
//		}
//
//		return image;
//	}
}
