/*******************************************************************************
 * This file is part of GECAMed.
 * 
 * GECAMed is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License (L-GPL) as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * GECAMed is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License (L-GPL)
 * along with GECAMed.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * GECAMed is Copyrighted by the Centre de Recherche Public Henri Tudor (http://www.tudor.lu)
 * (c) CRP Henri Tudor, Luxembourg, 2008
 *******************************************************************************/
package lu.tudor.santec.gecamed.labo.ejb.session.beans;

import java.util.Collection;
import java.util.Date;
import java.util.Iterator;

import javax.annotation.security.RolesAllowed;
import javax.ejb.Remote;
import javax.ejb.Stateless;
import javax.persistence.NoResultException;
import javax.persistence.Transient;

import lu.tudor.santec.gecamed.core.ejb.session.beans.GECAMedSessionBean;
import lu.tudor.santec.gecamed.labo.ejb.entity.beans.Result;
import lu.tudor.santec.gecamed.labo.ejb.entity.beans.ResultStub;
import lu.tudor.santec.gecamed.labo.ejb.session.interfaces.ResultInterface;
import lu.tudor.santec.gecamed.office.ejb.entity.beans.Physician;
import lu.tudor.santec.gecamed.patient.ejb.entity.beans.Patient;

import org.hibernate.Hibernate;

@Stateless
@Remote (ResultInterface.class)
public class ResultBean extends GECAMedSessionBean implements ResultInterface
	{
//---------------------------------------------------------------------------
//***************************************************************************
//* Constants	                                                            *
//***************************************************************************
//---------------------------------------------------------------------------
	
	@Transient
	public static final String INCIDENT_ENTRY_TYPE = "labo.result";
	
//---------------------------------------------------------------------------
//***************************************************************************
//* Constructor	                                                            *
//***************************************************************************
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//***************************************************************************
//* Primitives	                                                            *
//***************************************************************************
//---------------------------------------------------------------------------

private Result fetchDependency (Result p_Result, Integer p_Dependency)
	{
	switch (p_Dependency)
		{
		case ResultInterface.c_LaboratoryDependency:
			
			if ((p_Result.getLaboratory() != null) && (!Hibernate.isInitialized(p_Result.getLaboratory())) )
				Hibernate.initialize (p_Result.getLaboratory());

			break;		
		
		case ResultInterface.c_PatientDependency:
			
			if ((p_Result.getPatient() != null) && (!Hibernate.isInitialized(p_Result.getPatient())) )
				Hibernate.initialize (p_Result.getPatient());

			break;		

		case ResultInterface.c_PrescriberDependency:
			
			if ((p_Result.getPrescriber() != null) && (!Hibernate.isInitialized(p_Result.getPrescriber())) )
				Hibernate.initialize (p_Result.getPrescriber());

			break;		
		
		case ResultInterface.c_ContactsDependency:
			
			if ((p_Result.getContactPersons() != null) && (!Hibernate.isInitialized(p_Result.getContactPersons())) )
				Hibernate.initialize (p_Result.getContactPersons());

			break;		
		
		case ResultInterface.c_AnalysesDependency:
			
			if ((p_Result.getAnalyses() != null) && (!Hibernate.isInitialized(p_Result.getAnalyses())) )
				Hibernate.initialize (p_Result.getAnalyses());

			break;		
		
		case ResultInterface.c_AntibiogramsDependency:
			
			if ((p_Result.getAntibiograms() != null) && (!Hibernate.isInitialized(p_Result.getAntibiograms())) )
				Hibernate.initialize (p_Result.getAntibiograms());

			break;		
		}
	
	return 	p_Result;		
	}
	
//---------------------------------------------------------------------------
//***************************************************************************
//* Class Body	                                                            *
//***************************************************************************
//---------------------------------------------------------------------------

@RolesAllowed("gecam")
@SuppressWarnings("unchecked")
public Collection <ResultStub> getResultStubsForPhysician (Physician p_Physician, Date p_BeginOfPeriod, Date p_EndOfPeriod) throws Exception
	{
	Collection <ResultStub> l_Results;
	
	if ((p_Physician == null) || (!p_Physician.isPersistent())) return null;
	
	try	{
		if ((p_BeginOfPeriod != null) && (p_EndOfPeriod != null))
			{
			l_Results = this.getEntityManager()
							.createNamedQuery(ResultStub.c_ResultStubsForPhysicianByPeriod)
							.setParameter(ResultStub.c_PhysicianIdParameter, p_Physician.getId())
							.setParameter(ResultStub.c_BeginOfPeriodParameter, p_BeginOfPeriod)
							.setParameter(ResultStub.c_EndOfPeriodParameter, p_EndOfPeriod)
							.getResultList();
			}
		else
			{
			l_Results = this.getEntityManager()
							.createNamedQuery(ResultStub.c_ResultStubsForPhysician)
							.setParameter(ResultStub.c_PhysicianIdParameter, p_Physician.getId())
							.getResultList();	
			}
		}
	catch (NoResultException p_Exception)
		{
		l_Results = null;
		}
	
	return l_Results;
	}
		
//---------------------------------------------------------------------------

@RolesAllowed("gecam")
@SuppressWarnings("unchecked")
public Collection <ResultStub> getResultStubsForPatient (Patient p_Patient) throws Exception
	{
	Collection <ResultStub> l_Results;
	
	if ((p_Patient == null) || (!p_Patient.isPersistent())) return null;
	
	try	{
		l_Results = this.getEntityManager()
						.createNamedQuery(ResultStub.c_ResultStubsForPatient)
						.setParameter(ResultStub.c_PatientIdParameter, p_Patient.getId())
						.getResultList();		
		}
	catch (NoResultException p_Exception)
		{
		l_Results = null;
		}
	
	return l_Results;
	}
		
//---------------------------------------------------------------------------

@RolesAllowed("gecam")
public Result getResultById (Integer p_ResultId) throws Exception
	{
	Result l_Result;
	
	if (p_ResultId == null)  return null;
	
	try	{
		l_Result = (Result) this.getEntityManager()
								.createNamedQuery (Result.c_ResultById)
								.setParameter (Result.c_IdParameter, p_ResultId)
								.getSingleResult();		
		}
	catch (NoResultException p_Exception)
		{
		l_Result = null;
		}
	
	return l_Result;
	}


@RolesAllowed("gecam")
public Result getResultByIdFetchAll (Integer p_ResultId, 
		boolean fetchPatient, boolean fetchPrescriber, boolean fetchLabo) throws Exception
	{
	Result l_Result = getResultById(p_ResultId);
	
	if (l_Result != null)
		{
		if (fetchPatient) 		Hibernate.initialize(l_Result.getPatient());
		if (fetchPrescriber) 	Hibernate.initialize(l_Result.getPrescriber());
		if (fetchLabo) 			Hibernate.initialize(l_Result.getLaboratory());
		}
	
	return l_Result;
	}

//---------------------------------------------------------------------------

@RolesAllowed("gecam")
public Result getResultByIncidentEntryId (Integer p_IncidentEntryId) throws Exception
	{
	Result l_Result;
	
	if (p_IncidentEntryId == null)  return null;
	
	try	{
		l_Result = (Result) this.getEntityManager()
								.createNamedQuery (Result.c_ResultByIncidentEntryId)
								.setParameter (Result.c_IncidentEntryIdParameter, p_IncidentEntryId)
								.getSingleResult();		
		}
	catch (NoResultException p_Exception)
		{
		l_Result = null;
		}
	
	return l_Result;
	}

//---------------------------------------------------------------------------

public Result getAlreadyExistingResult (Integer p_LaboratoyId, Integer p_PhysicianId, Integer p_ResultNumber) throws Exception
	{
	Result l_Result;
	
	if ((p_LaboratoyId == null) || (p_PhysicianId == null) || (p_ResultNumber == null)) return null;
	
	try	{
		l_Result = (Result) this.getEntityManager()
								.createNamedQuery (Result.c_AlreadyExistingResult)
								.setParameter (Result.c_LaboratoryIdParameter, p_LaboratoyId)
								.setParameter (Result.c_PhysicianIdParameter,  p_PhysicianId)
								.setParameter (Result.c_ResultNumberParameter, p_ResultNumber)
								.getSingleResult();		
		}
	catch (NoResultException p_Exception)
		{
		l_Result = null;
		}
	
	return l_Result;
	}

//---------------------------------------------------------------------------

public Result	fetchLazyDependency (Result p_Result, Integer p_Dependency) throws Exception
	{
	if ((p_Result == null) || 
	    (p_Dependency == null) || 
	    !p_Result.isPersistent()) return p_Result;

	p_Result = m_EntityManager.find (Result.class, p_Result.getId());
	p_Result = this.fetchDependency(p_Result, p_Dependency);
	
	return 	p_Result;
	}

//---------------------------------------------------------------------------

public Result	fetchLazyDependencies (Result p_Result, Collection<Integer> p_Dependencies) throws Exception
	{
	Iterator <Integer>	l_DependencyIterator;
		
	if ((p_Result == null) || 
	    (p_Dependencies == null) || 
	    !p_Result.isPersistent()) return p_Result;

	p_Result = m_EntityManager.find (Result.class, p_Result.getId());
	
	l_DependencyIterator = p_Dependencies.iterator();
	while (l_DependencyIterator.hasNext())
		{
		p_Result = this.fetchDependency(p_Result, l_DependencyIterator.next());
		}
	
	return 	p_Result;
	}

//---------------------------------------------------------------------------
//***************************************************************************
//* End of Class                                                            *
//***************************************************************************
//---------------------------------------------------------------------------
	}
