/*
 * This file is part of DebGen Biobank Software developed by ASTRID Research.
 * All rights reserved. Reproduction, modification, use or disclosure
 * to third parties without express authority is forbidden.
 *
 * Copyright ASTRID Research Inc., Hungary, 2009-2011.
 *
 * ASTRID Research
 * Headquaters: Csapo utca 42. Debrecen H-4029 HUNGARY
 * Phone: +36-52-533-173        Fax: +36-52-533-174
 * Web: http://www.astrid.hu    E-mail: info@astrid.hu
 *
 * Project name: DebGen Biobank Software project.
 * URLS:
 * Developers: Istvan Zoltan Nagy (istvan.nagy@astrid.hu)
 */
package hu.astrid.debgen.patientmanagement.facade.modules;

import hu.astrid.debgen.authentication.domain.DebGenUser;
import hu.astrid.debgen.patientmanagement.domain.modules.Result;
import hu.astrid.debgen.patientmanagement.domain.Patient;
import hu.astrid.debgen.patientmanagement.domain.modules.Kariogram;
import hu.astrid.debgen.patientmanagement.domain.modules.ResultAcho;
import hu.astrid.debgen.patientmanagement.domain.modules.ResultCitogenetics;
import hu.astrid.debgen.patientmanagement.domain.modules.ResultFISH;
import hu.astrid.debgen.patientmanagement.domain.modules.ResultFmr1;
import hu.astrid.debgen.patientmanagement.domain.modules.ResultHypo;
import hu.astrid.debgen.patientmanagement.domain.modules.requests.AnalysisRequest;
import hu.astrid.debgen.patientmanagement.service.modules.KariogramsManagerService;
import hu.astrid.debgen.patientmanagement.service.modules.PrintManagerService;
import hu.astrid.debgen.patientmanagement.service.modules.ResultManagerService;
import hu.astrid.toucan.control.persistence.DatabaseServiceClass;
import java.net.URI;
import java.util.List;
import java.util.Locale;
import org.hibernate.Session;

/**
 * The facade, which is handling the patients
 * @author inagy
 */
public class ResultManagerFacade extends DatabaseServiceClass {

    // <editor-fold defaultstate="collapsed" desc="Result">
    /**
     * Starts a session, and creates or modifies the given results DB record
     * @param result The new result datas
     * @param old The old AnalysisRequest
     * @throws Exception When DB fails
     */
    public void createOrModifyResult(Result result, AnalysisRequest old) throws Exception {
        Session session;
        try {
            session = startSession();
            session.beginTransaction();
            ResultManagerService service = getResultService(session);
            if (old != null) {
                service.create(old);
            }
//            PatientManagerService ps = getService(session);
            service.create(result);
//            ps.create(result.getPatient());
            session.getTransaction().commit();
        } catch (Exception ex) {
            rollback();
            throw ex;
        } finally {
            closeSession();
        }
    }
    
    public Kariogram saveOrUpdate(Kariogram kariogram) throws Exception{
    	 Session session = null;
         try {
             session = startSession();
             session.beginTransaction();
             KariogramsManagerService service = getKariogramService(session);
            
             service.create(kariogram);
             
             session.getTransaction().commit();
             
             return service.load(kariogram.getId());
           
         } catch (Exception ex) {
             rollback();
             throw ex;
         } finally {
             closeSession();
         }
    }
    
    public void delete(Kariogram kariogram) throws Exception{
    	 Session session = null;
         try {
             session = startSession();
             session.beginTransaction();
             KariogramsManagerService service = getKariogramService(session);
             Kariogram kar = service.load(Kariogram.class, kariogram.getId());
             service.delete(kar);
             session.getTransaction().commit();
         } catch (Exception ex) {
             rollback();
             throw ex;
         } finally {
             closeSession();
         }
    }
    
    

    /**
     * Loads the result by the given id
     * @param id The id of the result
     * @return The result object with the specified id (if there is such thing)
     * @throws Exception When DB fails
     */
    public Result loadResult(Long id) throws Exception {
        Session session = null;
        try {
            session = startSession();
            session.beginTransaction();
            ResultManagerService service = getResultService(session);
            Result resultCommon = service.load(id);
            session.getTransaction().commit();
            return resultCommon;
        } catch (Exception ex) {
            rollback();
            throw ex;
        } finally {
            closeSession();
        }
    }

    /**
     * Deletes the result by the given id
     * @param id The id of the result
     * @throws Exception When DB fails
     */
    public void deleteResult(Long id) throws Exception {
        Session session = null;
        try {
            session = startSession();
            session.beginTransaction();
            ResultManagerService service = getResultService(session);
            Result res = service.load(id);
            service.delete(res);
            session.getTransaction().commit();
        } catch (Exception ex) {
            rollback();
            throw ex;
        } finally {
            closeSession();
        }
    }

    /**
     * Returns a list of results
     * @param order The ordering attribute to order the results ascending
     * @param pageNumber The number of the resulted page.
     * @param pageSize The number of elements on one page
     * @return The list of records on the current page.
     * @throws Exception When DB fails.
     */
    public List<Result> listResults(String order, int pageNumber, int pageSize) throws Exception {
        Session session = null;
        try {
            session = startSession();
            session.beginTransaction();
            ResultManagerService service = getResultService(session);
            List<Result> found = service.list(order, pageNumber * pageSize, pageSize);
            session.getTransaction().commit();
            return found;
        } catch (Exception ex) {
            rollback();
            throw ex;
        } finally {
            closeSession();
        }
    }

    /**
     * Gets a new ResultManagerService using a Session
     * @param session The session
     * @return the new service
     */
    private ResultManagerService getResultService(Session session) {
        ResultManagerService service = (ResultManagerService) ResultManagerService.getInstance(session);
        return service;
    }
    
    private KariogramsManagerService getKariogramService(Session session) {
        
        return (KariogramsManagerService) KariogramsManagerService.getInstance(session);
    }

    /**
     * Returns the number of result pages when listing results
     * @param size The number of elements on one page
     * @return The number of the pages
     * @throws Exception When DB fails.
     */
    public int getNumberOfListPages(int size) throws Exception {
        Session session = null;
        try {
            session = startSession();
            session.beginTransaction();
            ResultManagerService service = getResultService(session);
            double found = service.countList();
            session.getTransaction().commit();
            return (int) ((found - 0.01) / size);
        } catch (Exception ex) {
            rollback();
            throw ex;
        } finally {
            closeSession();
        }
    }

    /**
     * Lists the list of start matching values of the result result's "field" attribute
     * @param field The Name of an attribute in the result result relation
     * @param query The pattern witch should be found
     * @return The list of results
     * @throws Exception When DB fails
     */
    public List<String> listResultField(String field, String query) throws Exception {
        Session session = null;
        try {
            session = startSession();
            session.beginTransaction();
            ResultManagerService service = getResultService(session);
            List<String> result = null;
            if (field.startsWith("fish")) {
                result = service.listField(ResultFISH.class, field, query);
            } else if (field.startsWith("cit")) {
                result = service.listField(ResultCitogenetics.class, field, query);
            } else if (field.startsWith("acho")) {
                result = service.listField(ResultAcho.class, field, query);
            } else if (field.startsWith("hypo")) {
                result = service.listField(ResultHypo.class, field, query);
            } else if (field.startsWith("fmr")) {
                result = service.listField(ResultFmr1.class, field, query);
            } else {
                result = service.listField(Result.class, field, query);
            }
            session.getTransaction().commit();
            return result;
        } catch (Exception ex) {
            rollback();
            throw ex;
        } finally {
            closeSession();
        }
    }

    /**
     * Lists the Templates using the criterias
     * @param page The index of the current page.
     * @param size The number of elements on one page
     * @return The list of records on the current page.
     */
    public List<Result> listTemplates(int page, int size) throws Exception {
        Session session = null;
        try {
            session = startSession();
            session.beginTransaction();
            ResultManagerService service = getResultService(session);
            List<Result> found = service.listTemplates(page * size, size);
            session.getTransaction().commit();
            return found;
        } catch (Exception ex) {
            rollback();
            throw ex;
        } finally {
            closeSession();
        }
    }

    /**
     * Returns the number of template pages
     * @param size The number of elements on one page
     * @return The number of pages
     */
    public int getNumberOfTemplatePages(int size) throws Exception {
        Session session = null;
        try {
            session = startSession();
            session.beginTransaction();
            ResultManagerService service = getResultService(session);
            double found = service.countTemplateList();
            session.getTransaction().commit();
            return (int) ((found - 0.01) / size);
        } catch (Exception ex) {
            rollback();
            throw ex;
        } finally {
            closeSession();
        }
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="PDF">
    public URI generatePDF(Result result, DebGenUser user, int copies) throws Exception {
        Patient patient = result.getPatient();
        if (patient.isNamed() && !user.isDataRecorder()) {
            patient.setPatientType(1);
        }
        patient.setCopies(copies);
        result.setPatient(patient);
        return (PrintManagerService.getInstance().generatePdfFromModule(result, new Locale(user.getLanguageCode())));
    }// </editor-fold>

}
