package lu.tudor.santec.gecamed.formeditor.ejb.entity.beans;

import java.io.Serializable;
import java.util.LinkedList;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.persistence.Transient;

import lu.tudor.santec.gecamed.core.ejb.entity.beans.GECAMedEntityBean;
import lu.tudor.santec.gecamed.core.ejb.entity.beans.Template;
import lu.tudor.santec.gecamed.core.ejb.entity.beans.XSLTemplate;
import lu.tudor.santec.gecamed.core.ejb.session.beans.TemplateManagerBean;
import lu.tudor.santec.gecamed.core.ejb.session.interfaces.TemplateManagerInterface;
import lu.tudor.santec.gecamed.core.utils.ManagerFactory;
import lu.tudor.santec.gecamed.office.ejb.entity.beans.Physician;

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

@Entity
@Table(name = "form_template", schema = "formeditor")
@NamedQueries({
		@NamedQuery(name = FormTemplate.GET_ALL_TEMPLATES, 
				query = "SELECT OBJECT(o) FROM FormTemplate o ORDER BY o.name, o.version"),
		@NamedQuery(name = FormTemplate.GET_TEMPLATES_BY_NAME, 
				query = "SELECT OBJECT(o) FROM FormTemplate o " +
						"WHERE o.name = :name AND o.version LIKE :version ORDER BY o.version DESC"),
		@NamedQuery(name = FormTemplate.GET_TEMPLATES_WITH_JASPER_ID, 
				query = "SELECT OBJECT(o) FROM FormTemplate o " +
						"WHERE o.jasperTemplate.id = :jasperId " +
						"AND o.jasperTemplate.type = '"+FormTemplate.REPORT_TEMPLATE_TYPE+"'"),
		@NamedQuery(name = FormTemplate.GER_TEMPLATES_EXCEPT_SUBFORM_ONLY,
				query = "SELECT OBJECT(o) FROM FormTemplate o " +
						"WHERE o.subFormOnly = false " +
						"ORDER BY o.name, o.version")
})

public class FormTemplate extends GECAMedEntityBean implements Serializable 
{
	/* ======================================== */
	// 		CONSTANTS
	/* ======================================== */
	
	private static final long serialVersionUID = 1L;
	
	/**
	 * the names of the NamedQueries
	 */
	public static final String GET_ALL_TEMPLATES 				 = "getAllTemplates";
	public static final String GET_TEMPLATES_BY_NAME 			 = "getTemplatesByName";
	public static final String GET_TEMPLATES_WITH_JASPER_ID 	 = "getTemplatesWithJasperId";
	public static final String GER_TEMPLATES_EXCEPT_SUBFORM_ONLY = "getTemplatesExceptSubformOnly";
//	public static final String GET_XSL_TEMPLATE_FOR_PRINTING	 = "getXslTemplateForPrinting";
//	public static final String GET_XSL_TEMPLATE_FOR_HISTORY		 = "getXslTemplateForHistory";

	public static final String REPORT_TEMPLATE_TYPE = "form_template";
	
	
	
	/* ======================================== */
	// 		MEMBERS
	/* ======================================== */
	
	/** the logger Object for this class */
	private static Logger logger = Logger.getLogger(FormTemplate.class.getName());
	
	/**
	 * the given name of this template.
	 */
	private String name;
	
	/**
	 * the whole structure of the form as XML
	 */
	private String xml;
	
	/**
	 * the description of the form-template. What is the form for and so on.
	 */
	private String description;
	
	/**
	 * the version number of this template
	 */
	private String version;
	
	/**
	 * The JasperReports-Template entry
	 */
	private Template jasperTemplate;
	
	/**
	 * This defines, if the form is only used as a sub form.
	 * In that case it won't be shown in the list to create a new form.
	 */
	private Boolean subFormOnly = false;
	
	
	private static TemplateManagerInterface templateManager;
	
	private List<XSLTemplate> xslTemplates;
	
	
	
	/* ======================================== */
	// 		GETTER & SETTER
	/* ======================================== */
	
	/**
	 * Getter of the property <tt>version</tt>
	 *
	 * @return Returns the version.
	 * 
	 */
	@Column(name = "version")
	public String getVersion()
	{
		return version;
	}
	
	/**
	 * Setter of the property <tt>version</tt>
	 *
	 * @param version The version to set.
	 *
	 */
	public void setVersion(String version ) {
		this.version = version;
	}
	
	
	@Column(name = "name")
	public String getName() {
		return name;
	}
	
	public void setName(String name) {
		this.name = name;
	}
	
	
	@Column(name = "xml")
	public String getXml() {
		return xml;
	}
	
	public void setXml(String xml) {
		this.xml = xml;
	}
	
	
	@Column(name = "description")
	public String getDescription() {
		return description;
	}
	
	public void setDescription(String description) {
		this.description = description;
	}
	
	
	@ManyToOne(cascade = javax.persistence.CascadeType.ALL, fetch = javax.persistence.FetchType.EAGER)
	@JoinColumn(name = "jasper_template_id")
	public Template getJasperTemplate() {
		return jasperTemplate;
	}
	
	public void setJasperTemplate (Template template) {
		this.jasperTemplate = template;
	}
	
	
	@Column(name = "subform_only")
	public Boolean isSubFormOnly() {
		return subFormOnly;
	}
	
	public void setSubFormOnly (Boolean subFormOnly) {
		this.subFormOnly = subFormOnly;
	}
	
	
	
	/* ======================================== */
	// 		TRANSIENT METHODS
	/* ======================================== */
	
	@Transient
	private static TemplateManagerInterface getTemplateManager ()
	{
		if (templateManager == null)
			templateManager = (TemplateManagerInterface) ManagerFactory.getRemote(TemplateManagerBean.class);
		
		return templateManager;
	}
	
	@Transient
	public List<XSLTemplate> getXslTemplates (Physician physician)
	{
		if (xslTemplates == null)
		{
			try
			{
				Integer physicianId = physician != null ? physician.getId() : null;
				xslTemplates = getTemplateManager().getXSLTemplates(
						XSLTemplate.TYPE_FORM_EDITOR, getId(), physicianId);
			} 
			catch (Exception e)
			{
				logger.log(Level.ERROR, e.getMessage(), e);
			}
		}
		
		return xslTemplates;
	}
	

	@Transient
	public XSLTemplate getHistoryTemplates (Physician physician)
	{
		for (XSLTemplate t : getXslTemplates(physician))
		{
			if (t.getUseForHistory())
				return t;
		}
		
		return null;
	}
	

	@Transient
	public List<XSLTemplate> getEditableTemplates (Physician physician)
	{
		List<XSLTemplate> templates = new LinkedList<XSLTemplate>();
		for (XSLTemplate t : getXslTemplates(physician))
		{
			if (t.getUseToEdit())
				templates.add(t);
		}
		
		return templates;
	}
	

	@Transient
	public List<XSLTemplate> getPrintableTemplates (Physician physician)
	{
		List<XSLTemplate> templates = new LinkedList<XSLTemplate>();
		for (XSLTemplate t : getXslTemplates(physician))
		{
			if (t.getUseToPrint())
				templates.add(t);
		}
		
		return templates;
	}
}