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

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
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;


@NamedQueries(
{
	@NamedQuery(name = ReportParameter.QUERY_DELETE_REFERENCELESS_PARAMETER, 
			query = "SELECT OBJECT(o) FROM ReportParameter o WHERE o.report IS NULL")
})

@Entity
@Table(name = "report_parameter", schema = "reporting")
public class ReportParameter extends GECAMedEntityBean
{
	/* ======================================== */
	// 		CONSTANTS
	/* ======================================== */
	
	private static final long	serialVersionUID	= 1L;
	
	public static final String	QUERY_DELETE_REFERENCELESS_PARAMETER	= "DeleteRefencelessParameter";
	
	public static final String	TYPE_BOOLEAN	= "Boolean";
	public static final String	TYPE_INTEGER	= "Integer";
	public static final String	TYPE_DECIMAL	= "Decimal";
	public static final String	TYPE_STRING		= "String";
	public static final String	TYPE_DATE		= "Date";
	public static final String	TYPE_DATE_TIME	= "Date & Time";
//	public static final String	TYPE_PHYSICIAN	= "Physician";
//	public static final String	TYPE_INSURANCE	= "Insurance";
//	public static final String	TYPE_	= "";
	
	
	
	/* ======================================== */
	// 		MEMBERS
	/* ======================================== */
	
	public static DateFormat	dateFormatter	= new SimpleDateFormat("yyyy-MM-dd");
	
	
	private Report			report;
	
	private ParameterQuery	query;
	
	private String		name			= "";
	
	private String		type			= TYPE_BOOLEAN;
	
	private String		label			= "";
	
	private String		defaultValue	= "";
	
	private Object		value			= null;
	
	private String		comment			= "";
	
	private Boolean		mendatory		= Boolean.TRUE;
	
	private Boolean 	multiSelect		= Boolean.FALSE;
	
	
	
	/* ======================================== */
	// 		CONSTRUCTORS
	/* ======================================== */
	
	public ReportParameter() {}
	
	
	public ReportParameter(Report report)
	{
		this.report	= report;
	}
	
	
	
	/* ======================================== */
	// 		GETTER & SETTER
	/* ======================================== */
	
	@ManyToOne(fetch = javax.persistence.FetchType.EAGER)
	@JoinColumn(name = "report_id")
	public Report getReport ()
	{
		return report;
	}
	
	
	public void setReport (Report report)
	{
		this.report = report;
	}
	
	
	@ManyToOne(fetch = FetchType.EAGER)
	@JoinColumn(name = "query_id", nullable = true)
	public ParameterQuery getQuery ()
	{
		return query;
	}
	
	
	public void setQuery (ParameterQuery query)
	{
		this.query = query;
	}
	
	
	@Column(name = "name")
	public String getName()
	{
		return name;
	}
	
	
	public void setName(String name)
	{
		this.name = name;
	}
	
	
	@Column(name = "type")
	public String getType()
	{
		return type;
	}
	
	
	public void setType(String type)
	{
		this.type = type;
	}
	
	
	@Column(name = "label")
	public String getLabel ()
	{
		return this.label;
	}
	
	
	public void setLabel (String label)
	{
		this.label = label;
	}
	
	
	@Column(name = "default_value")
	public String getDefaultValue()
	{
		return defaultValue;
	}
	
	
	public void setDefaultValue(String defaultValue)
	{
		this.defaultValue = defaultValue;
	}
	
	
	@Column(name = "comment")
	public String getComment()
	{
		return comment;
	}
	
	
	public void setComment(String comment)
	{
		this.comment = comment;
	}
	

	@Column(name = "mendatory")
	public Boolean getMendatory()
	{
		return mendatory;
	}
	
	
	public void setMendatory(Boolean mendatory)
	{
		this.mendatory = mendatory;
	}
	

	@Column(name = "multi_select")
	public Boolean getMultiSelect()
	{
		return multiSelect;
	}
	
	
	public void setMultiSelect(Boolean multiSelect)
	{
		this.multiSelect = multiSelect;
	}
	
	
	@Transient
	public Object getValue ()
	{
		return value;
	}
	
	
	@Transient
	public void setValue (Object value)
	{
		this.value	= value;
	}
	
	
	@Transient
	public String getSqlValue () throws EmptyParameterException
	{
		// NULL
		if (value == null)
			if (getMendatory())
				throw new EmptyParameterException(this);
			else return "NULL";
		// STRING
		else if (value instanceof String)
			return new StringBuilder("\'")
					.append(value)
					.append("\'")
					.toString();
		// DATE
		else if (value instanceof Date)
			return "'"+dateFormatter.format(
					(Date)value)+"'";
		// CALENDAR
		else if (value instanceof Calendar)
			return "'"+dateFormatter.format(
					((Calendar)value).getTime())+"'";
		// ELSE - PRIMITIVES
		else
			return String.valueOf(value);
//		else 
//			throw new RuntimeException(
//					"Unsupported type \"" + 
//					paramValue.getClass() + 
//					"\" of parameter \"" + 
//					paramName + 
//					"\"");
	}
	
	
	@Transient
	@Override
	public String toString ()
	{
//		return this.name + " \t[" + this.className + "]\t desc: " + this.description + "\t def: " + this.defaultValue;
		return new StringBuilder(name)
				.append("\t(")
				.append(type)
				.append(")")
				.toString();
	}
	
	
	public class EmptyParameterException extends Exception
	{
		/* ======================================== */
		// 		CONSTANTS
		/* ======================================== */
		
		private static final long	serialVersionUID	= 1L;
		
		
		
		/* ======================================== */
		// 		MEMBERS
		/* ======================================== */
		
		private ReportParameter	parameter;
		
		
		
		/* ======================================== */
		// 		CONSTRUCTORS
		/* ======================================== */
		
		public EmptyParameterException (ReportParameter p)
		{
			super((p.getValue() == null && p.getMendatory()) 
					? "The value of the parameter "+p.getName()+" is NULL, but must be set to a value."
					: "Empty parameter "+p.getName());
			this.parameter = p;
		}
		
		
		
		/* ======================================== */
		// 		GETTER & SETTER
		/* ======================================== */
		
		public ReportParameter getParameter ()
		{
			return this.parameter;
		}
	}
}
