/*
 * 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.servlet.modules;

import elements.Functions;
import hu.astrid.debgen.authentication.domain.DebGenUser;
import hu.astrid.debgen.authentication.exception.AccessDeniedException;
import hu.astrid.debgen.exception.ServerSideException;
import hu.astrid.debgen.exception.ValidationFailedException;
import hu.astrid.debgen.patientmanagement.domain.Patient;
import hu.astrid.debgen.patientmanagement.domain.modules.*;
import hu.astrid.debgen.patientmanagement.domain.modules.requests.AnalysisRequest;
import hu.astrid.debgen.patientmanagement.domain.modules.requests.AnalysisRequestBornDefect;
import hu.astrid.debgen.patientmanagement.domain.modules.requests.AnalysisRequestConst;
import hu.astrid.debgen.patientmanagement.domain.modules.requests.AnalysisRequestOnkohaematology;
import hu.astrid.debgen.patientmanagement.facade.PatientManagerFacade;
import hu.astrid.debgen.patientmanagement.facade.modules.ResultManagerFacade;
import hu.astrid.debgen.patientmanagement.facade.modules.requests.RequestManagerFacade;
import hu.astrid.debgen.patientmanagement.facade.sample.SampleManagerFacade;
import hu.astrid.debgen.server.requestprocessor.ActionParameter;
import hu.astrid.debgen.server.requestprocessor.RequestTokenizer;
import hu.astrid.debgen.server.requestprocessor.facade.RequestProcessorFacade;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.log4j.Logger;
import org.hibernate.exception.ConstraintViolationException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * Handles the operations with moduless
 *
 * @author inagy
 */
public class ResultManagerServlet extends HttpServlet {

    private static final long serialVersionUID = 1L;
    static Logger logger = Logger.getLogger(ResultManagerServlet.class);

    private ResultManagerFacade facade;
    private Result result;

    protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        logger.debug("doPost() called.");
        ActionParameter actionParameter = ActionParameter.getActionParameter(request);
        logger.debug(actionParameter);
        logger.debug(RequestTokenizer.getRequestData(request));
        String action = actionParameter.getAction();
        try {
            DebGenUser user = RequestProcessorFacade.getDebGenUser(request);
            if (!user.isDataRecorder() && !user.isResearcher()) {
                throw new AccessDeniedException();
            }
            if (action.equals("createmodule") || action.equals("showrequests")) {
                createResult(request, response);
            } else if (action.equals("savemodule")) {
                saveResult(request, response);
            } else if (action.equals("showmodule")) {
                showResult(request, response);
            } else if (action.equals("createtemplate")) {
                createResult(request, response);
            } else if (action.equals("savetemplate")) {
                saveResult(request, response);
            } else if (action.equals("showtemplate")) {
                showResult(request, response);
            } else if (action.equals("listtemplates")) {
                listTemplates(request, response);
            } else if (action.equals("deletetemplate")) {
                deleteTemplate(request, response);
            } else if (action.equals("attachkariogrammodule")) {
                attachKariogram(request, response);
            } else if (action.equals("deletekariogram")) {
                deleteKariogram(request, response);
            } else if (action.equals("displaykariogram")) {
                displayKariogram(request, response);
            } else {
                request.setAttribute("answer", true);
                request.getRequestDispatcher("index.jsp").forward(request, response);
            }
        } catch (AccessDeniedException ex) {
            request.setAttribute("answer", true);
            request.setAttribute("globalexception", new ServerSideException("Nincs jogosultsága a kérés befejezéséhez."));
            request.getRequestDispatcher("index.jsp").forward(request, response);
        } catch (Exception ex) {
            request.setAttribute("answer", true);
            request.setAttribute("globalexception", new ServerSideException("A kért erőforrás nem található, vagy a hivatkozás hibás."));
            request.getRequestDispatcher("index.jsp").forward(request, response);
        }

    }

    private void displayKariogram(HttpServletRequest request,
                                  HttpServletResponse response) throws IOException {
        logger.info(">> Display kariogram");

        OutputStream out = null;

        try {
            Kariogram displayable = getKariogram(request);

            // Set content type
            response.setContentType("image/gif");

            //find the string content
            byte[] imageAsArray = displayable.getKariogramImage();

            out = response.getOutputStream();
            out.write(imageAsArray);

            out.flush();
            request.setAttribute("answer", true);
        } catch (Exception e) {
            logger.error(e);
        } finally {
            out.close();
        }

    }

    private Kariogram getKariogram(HttpServletRequest request) throws Exception {
        Long moduleId = new Long(request.getParameter("module"));
        Long kariogramId = new Long(request.getParameter("kariogram"));
        facade = new ResultManagerFacade();
        result = facade.loadResult(moduleId);
        request.setAttribute("module", result);
        request.setAttribute("patient", result.getPatient());


        Set<Kariogram> kariograms = result.getKariograms();

        Kariogram kariogram = null;

        for (Kariogram k : kariograms) {
            if (k.getId().equals(kariogramId)) {
                kariogram = k;
            }
        }
        return kariogram;
    }

    private void deleteKariogram(HttpServletRequest request,
                                 HttpServletResponse response) {
        logger.info(">> delete kariogram");

        try {
            Kariogram deletable = getKariogram(request);

            Set<Kariogram> kariograms = result.getKariograms();

            if (deletable != null) {
                kariograms.remove(deletable);
            }

            result.setKariograms(kariograms);

            facade.createOrModifyResult(result, null);

            request.setAttribute("answer", true);
            response.sendRedirect("showmodule.html?module=" + result.getId());
        } catch (Exception e) {
            logger.error(e);
        }

    }

    private void attachKariogram(HttpServletRequest request,
                                 HttpServletResponse response) {
        logger.info(">> Attach kariograms");

        try {

            Long id = new Long(request.getParameter("module"));
            ResultManagerFacade facade = new ResultManagerFacade();
            Result result;
            result = facade.loadResult(id);

            Set<Kariogram> kariograms = result.getKariograms();

            ServletFileUpload servletFileUpload = new ServletFileUpload(
                    new DiskFileItemFactory());
            List<FileItem> fileItems = servletFileUpload.parseRequest(request);


            Kariogram kariogram;

            //iterate over the number of kario images
            for (FileItem item : fileItems) {

                if (!item.isFormField() && item.getSize() != 0) {

                    kariogram = new Kariogram();
                    kariogram.setKariogramImage(item.get());
                    kariogram.setResult(result);

                    kariogram = facade.saveOrUpdate(kariogram);

                    kariograms.add(kariogram);
                }
            }


            result.setKariograms(new HashSet<Kariogram>(kariograms));

            facade.createOrModifyResult(result, null);

            request.setAttribute("module", result);
            request.setAttribute("patient", result.getPatient());
            request.setAttribute("answer", true);
            response.sendRedirect("showmodule.html?module=" + result.getId());

        } catch (Exception e) {
            logger.error(e);
        }
    }

    // <editor-fold defaultstate="collapsed" desc="Modules">

    /**
     * Tries to load an existing result object from the DB if necessary, or does nothing
     *
     * @param request
     * @param response
     * @throws Exception When DB fails or other failure occures
     */
    private void createResult(HttpServletRequest request, HttpServletResponse response) throws Exception {
        logger.debug("createResult() called.");
        ResultManagerFacade facade = new ResultManagerFacade();
        RequestManagerFacade reqFacade = new RequestManagerFacade();
        String req = request.getParameter("request");
        List<Result> templateList = facade.listTemplates(0, 10000 + (facade.getNumberOfTemplatePages(10000) * 10000));
        if (req != null) {
            try {
                Long reqId = new Long(req);
                AnalysisRequest testReq = reqFacade.loadRequest(reqId);
                request.setAttribute("request", testReq);
                List<Result> matching = new ArrayList<Result>();
                boolean cit = false;
                boolean fish = false;
                boolean acho = false;
                boolean hypo = false;
                boolean fmr = false;
                for (Result act : templateList) {
                    if (testReq instanceof AnalysisRequestConst) {
                        if (act.isUseAtConst()) {
                            matching.add(act);
                            cit = cit || act instanceof ResultCitogenetics;
                            fish = fish || act instanceof ResultFISH;
                            acho = acho || act instanceof ResultAcho;
                            hypo = hypo || act instanceof ResultHypo;
                            fmr = fmr || act instanceof ResultFmr1;
                        }
                    } else if (testReq instanceof AnalysisRequestBornDefect) {
                        AnalysisRequestBornDefect bd = (AnalysisRequestBornDefect) testReq;
                        if (act.isUseAtBorn()
                                && (bd.isBdCitogenetic() && act.isBdCitogenetic())
                                || (bd.isBdCitogeneticalAnalysis() && act.isBdCitogeneticalAnalysis())
                                || (bd.isBdDNAPreparation() && act.isBdDNAPreparation())
                                //                                || (bd.isBdFish() && act.isBdFish())
                                || (bd.isBdDiGeorge() && act.isBdDiGeorge())
                                || (bd.isBdWilliams() && act.isBdWilliams())
                                || (bd.isBdPraderWilli() && act.isBdPraderWilli())
                                || (bd.isBdSmithMagenis() && act.isBdSmithMagenis())
                                || (bd.isBdSRY() && act.isBdSRY())
                                || (bd.isBdFish() && act.isBdSubtelomericFish())
                                || (bd.isBdTurnerMozaicizm() && act.isBdTurnerMozaicizm())
                                || (bd.isBdTurnerRemainingY() && act.isBdTurnerRemainingY())
                                || (bd.isBdMulticolorFish() && act.isBdMulticolorFish())
                                //                                || (bd.isBdFragX() && act.isBdFragX())
                                || (bd.isBdMolecular() && act.isBdMolecular())
                                || (bd.isBdFGFR2OrFGFR3() && act.isBdFGFR2OrFGFR3())
                                || (bd.isBdSCE() && act.isBdSCE())) {
                            matching.add(act);
                            cit = cit || act instanceof ResultCitogenetics;
                            fish = fish || act instanceof ResultFISH;
                            acho = acho || act instanceof ResultAcho;
                            hypo = hypo || act instanceof ResultHypo;
                            fmr = fmr || act instanceof ResultFmr1;
                        }
                    } else if (testReq instanceof AnalysisRequestOnkohaematology) {
                        AnalysisRequestOnkohaematology on = (AnalysisRequestOnkohaematology) testReq;
                        if (act.isUseAtOncohaem() && ((on.isOnCitBone() && act.isOnCitBone())
                                //                                || (on.isOnCitogenetical() && act.isOnCitogenetical())
                                || (on.isOnCitBlood() && act.isOnCitBlood())
                                || (on.isOnCitTumor() && act.isOnCitTumor())
                                || (on.isOnDNAPreparation() && act.isOnDNAPreparation())
                                || (on.isOnRTPCR() && act.isOnRTPCR())
                                //                                || (on.isOnFish() && act.isOnFish())
                                || (on.isOnFishCML1() && act.isOnFishCML1())
                                || (on.isOnFishCML2() && act.isOnFishCML2())
                                || (on.isOnFishCML3() && act.isOnFishCML3())
                                || (on.isOnFishCML4() && act.isOnFishCML4())
                                || (on.isOnFishCLL1() && act.isOnFishCLL1())
                                || (on.isOnFishCLL2() && act.isOnFishCLL2())
                                || (on.isOnFishCLL3() && act.isOnFishCLL3())
                                || (on.isOnFishCLL4() && act.isOnFishCLL4())
                                || (on.isOnFishMDS1() && act.isOnFishMDS1())
                                || (on.isOnFishMDS2() && act.isOnFishMDS2())
                                || (on.isOnFishMDS3() && act.isOnFishMDS3())
                                || (on.isOnFishMDS4() && act.isOnFishMDS4())
                                || (on.isOnFishMDS5() && act.isOnFishMDS5())
                                || (on.isOnFishMDS6() && act.isOnFishMDS6())
                                || (on.isOnFishMyeloma1() && act.isOnFishMyeloma1())
                                || (on.isOnFishMyeloma2() && act.isOnFishMyeloma2())
                                || (on.isOnFishMyeloma3() && act.isOnFishMyeloma3())
                                || (on.isOnFishMyeloma4() && act.isOnFishMyeloma4())
                                || (on.isOnFishAML1() && act.isOnFishAML1())
                                || (on.isOnFishAML2() && act.isOnFishAML2())
                                || (on.isOnFishAML3() && act.isOnFishAML3())
                                || (on.isOnFishAML4() && act.isOnFishAML4())
                                || (on.isOnFishAML5() && act.isOnFishAML5())
                                || (on.isOnFishAML6() && act.isOnFishAML6())
                                || (on.isOnFishAML7() && act.isOnFishAML7())
                                || (on.isOnFishAML8() && act.isOnFishAML8())
                                || (on.isOnFishALL1() && act.isOnFishALL1())
                                || (on.isOnFishALL2() && act.isOnFishALL2())
                                || (on.isOnFishALL3() && act.isOnFishALL3())
                                || (on.isOnFishALL4() && act.isOnFishALL4())
                                || (on.isOnFishALL5() && act.isOnFishALL5())
                                || (on.isOnFishALL6() && act.isOnFishALL6())
                                || (on.isOnFishALL7() && act.isOnFishALL7()))) {
                            matching.add(act);
                            cit = cit || act instanceof ResultCitogenetics;
                            fish = fish || act instanceof ResultFISH;
                            acho = acho || act instanceof ResultAcho;
                            hypo = hypo || act instanceof ResultHypo;
                            fmr = fmr || act instanceof ResultFmr1;
                        }
                    }
                }

                request.setAttribute("cit", cit);
                request.setAttribute("fish", fish);
                request.setAttribute("acho", acho);
                request.setAttribute("hypo", hypo);
                request.setAttribute("fmr", fmr);
                request.setAttribute("matching", matching);
                request.setAttribute("templates", templateList);
            } catch (Exception ex) {
                //Request id was empty!
                logger.error(ex);
            }
        } else {
            request.setAttribute("templates", templateList);
        }
        try {
            Long id = new Long(request.getParameter("module"));
            Result result = facade.loadResult(id);
            request.setAttribute("module", result);
            request.setAttribute("patient", result.getPatient());
            request.setAttribute("answer", true);
            request.getRequestDispatcher("index.jsp").forward(request, response);
        } catch (Exception ex) {
            try {
                Long id = new Long(request.getParameter("patient"));
                Patient patient = new PatientManagerFacade().loadPatient(id);
                request.setAttribute("patient", patient);
                request.setAttribute("answer", true);
                request.getRequestDispatcher("index.jsp").forward(request, response);
            } catch (Exception e) {
                request.setAttribute("answer", true);
                request.getRequestDispatcher("index.jsp").forward(request, response);
            }
        }
    }

    /**
     * Tries to load an existing result object from the DB and deletes it
     *
     * @param request
     * @param response
     * @throws Exception When DB fails or other failure occures
     */
    private void deleteTemplate(HttpServletRequest request, HttpServletResponse response) throws Exception {
        logger.debug("deleteTemplate() called.");
        ResultManagerFacade facade = new ResultManagerFacade();
        try {
            Long id = new Long(request.getParameter("module"));
            facade.deleteResult(id);
            listTemplates(request, response);
        } catch (Exception ex) {
            logger.error(ex);
            throw ex;
        }
    }

    /**
     * Saves an Result object to the DB if possible
     *
     * @param request
     * @param response
     * @throws Exception When DB fails or other failure occures
     */
    private void saveResult(HttpServletRequest request, HttpServletResponse response) throws Exception {
        logger.debug("saveResult() called.");
        request.setAttribute("answer", true);
        try {
            Long id = 0L;
            Long patientId = 0L;
            Long requestId = 0L;
            AnalysisRequest old = null;
            Patient patient = null;
            Result result = null;
            ResultManagerFacade facade = new ResultManagerFacade();
            request.setAttribute("templates", facade.listTemplates(0, 10000 + (facade.getNumberOfTemplatePages(10000) * 10000)));
            boolean newModule = false;
            try {
                id = new Long(request.getParameter("id"));
                result = facade.loadResult(id);
            } catch (Exception ex) {
                //IGNORED, parameters can be empty
                logger.debug("New result found, no problem!");
            }
            try {
                patientId = new Long(request.getParameter("patient"));
                patient = new PatientManagerFacade().loadPatient(patientId);
            } catch (Exception ex) {
                //IGNORED, parameters can be empty
                logger.debug("Using template editing mode!");
            }
            if (result == null) {
                newModule = true;
                result = Result.getInstance(Functions.encodeString(request.getParameter("objectType")));
            }
            if (patient != null) {
                try {
                    requestId = new Long(request.getParameter("requestId"));
//                    if (result.getRequest() != null && !result.getRequest().getId().equals(requestId)) {
//                        result.getRequest().setResult(null);
//                        old = result.getRequest();
//                    }
                    if (!requestId.equals(new Long("0"))) {
                        if (result.getRequest() == null || !result.getRequest().getId().equals(requestId)) {
                            for (AnalysisRequest a : patient.getAnalysisRequests()) {
                                if (requestId.equals(a.getId())) {
                                    result.setRequest(a);
                                    Set<Result> aResults = a.getResults();
                                    aResults.add(result);
                                    a.setResults(aResults);
                                    break;
                                }
                            }
                        }
                    }
                } catch (Exception ex) {
                    //IGNORED, parameters can be empty
                    logger.debug("No request found!");
                }
            }
            result.convert(request);
            if (result instanceof ResultFISH) {
                ResultFISH fish = (ResultFISH) result;
                try {
                    fish.setFishSampleTakenOn(new SimpleDateFormat("yyyy. MM. dd.").parse(Functions.encodeString(request.getParameter("fishSampleTakenOn"))));
                } catch (Exception e) {
                    //IGNORED
                    logger.debug("Unknown date format found! The datepicker is not set correctly, or the field is empty? " + request.getParameter("fishSampleTakenOn"));
                }
            }
            if (result instanceof ResultHypo) {
                ResultHypo hypo = (ResultHypo) result;
                try {
                    hypo.setHypoSampleTakenOn(new SimpleDateFormat("yyyy. MM. dd.").parse(Functions.encodeString(request.getParameter("hypoSampleTakenOn"))));
                } catch (Exception e) {
                    //IGNORED
                    logger.debug("Unknown date format found! The datepicker is not set correctly, or the field is empty? " + request.getParameter("hypoSampleTakenOn"));
                }
            }
            if (result instanceof ResultAcho) {
                ResultAcho acho = (ResultAcho) result;
                try {
                    acho.setAchoSampleTakenOn(new SimpleDateFormat("yyyy. MM. dd.").parse(Functions.encodeString(request.getParameter("achoSampleTakenOn"))));
                } catch (Exception e) {
                    //IGNORED
                    logger.debug("Unknown date format found! The datepicker is not set correctly, or the field is empty? " + request.getParameter("achoSampleTakenOn"));
                }
            }
            if (result instanceof ResultFmr1) {
                ResultFmr1 fmr = (ResultFmr1) result;
                try {
                    fmr.setFmrSampleTakenOn(new SimpleDateFormat("yyyy. MM. dd.").parse(Functions.encodeString(request.getParameter("fmrSampleTakenOn"))));
                } catch (Exception e) {
                    //IGNORED
                    logger.debug("Unknown date format found! The datepicker is not set correctly, or the field is empty? " + request.getParameter("fmrSampleTakenOn"));
                }
            }
            result.setPatient(patient);
            if (newModule && !result.isTemplate()) {
                result.getPatient().addResult(result);
            }
            request.setAttribute("module", result);
            request.setAttribute("patient", result.getPatient());
            result.validate();
            facade.createOrModifyResult(result, old);
            String saveAsTemplate = Functions.encodeString(request.getParameter("saveAsTemplate"));
            if (saveAsTemplate != null && !saveAsTemplate.equals("")) {
                Result template = Result.getInstance(Functions.encodeString(request.getParameter("objectType")));
                template.convert(request);
                if (template instanceof ResultFISH) {
                    ResultFISH templatefish = (ResultFISH) template;
                    try {
                        templatefish.setFishSampleTakenOn(new SimpleDateFormat("yyyy. MM. dd.").parse(Functions.encodeString(request.getParameter("fishSampleTakenOn"))));
                    } catch (Exception e) {
                        //IGNORED
                        logger.debug("Unknown date format found! The datepicker is not set correctly, or the field is empty? " + request.getParameter("fishSampleTakenOn"));
                    }
                }
                if (template instanceof ResultHypo) {
                    ResultHypo templatehypo = (ResultHypo) template;
                    try {
                        templatehypo.setHypoSampleTakenOn(new SimpleDateFormat("yyyy. MM. dd.").parse(Functions.encodeString(request.getParameter("hypoSampleTakenOn"))));
                    } catch (Exception e) {
                        //IGNORED
                        logger.debug("Unknown date format found! The datepicker is not set correctly, or the field is empty? " + request.getParameter("hypoSampleTakenOn"));
                    }
                }
                if (template instanceof ResultAcho) {
                    ResultAcho templateacho = (ResultAcho) template;
                    try {
                        templateacho.setAchoSampleTakenOn(new SimpleDateFormat("yyyy. MM. dd.").parse(Functions.encodeString(request.getParameter("achoSampleTakenOn"))));
                    } catch (Exception e) {
                        //IGNORED
                        logger.debug("Unknown date format found! The datepicker is not set correctly, or the field is empty? " + request.getParameter("achoSampleTakenOn"));
                    }
                }
                if (template instanceof ResultFmr1) {
                    ResultFmr1 templatefmr = (ResultFmr1) template;
                    try {
                        templatefmr.setFmrSampleTakenOn(new SimpleDateFormat("yyyy. MM. dd.").parse(Functions.encodeString(request.getParameter("fmrSampleTakenOn"))));
                    } catch (Exception e) {
                        //IGNORED
                        logger.debug("Unknown date format found! The datepicker is not set correctly, or the field is empty? " + request.getParameter("fmrSampleTakenOn"));
                    }
                }


                template.setId(null);
                template.setTemplate(true);
                template.setTemplateName(saveAsTemplate);
                template.setPatient(null);
                template.setRequest(null);
                facade.createOrModifyResult(template, null);
            }
            if (result.isTemplate()) {
                response.sendRedirect("showtemplate.html?module=" + result.getId());
            } else {
                if (request.getParameter("send").contains(" ")) {
                    response.sendRedirect("printmodule.html?module=" + result.getId());
                } else {
                    response.sendRedirect("showpatient.html?patient=" + patientId);
                }

            }
        } catch (ValidationFailedException ex) {
            logger.error(ex);
            request.setAttribute("exception", new ServerSideException(ex));
            request.getRequestDispatcher("index.jsp").forward(request, response);
        } catch (ConstraintViolationException ex) {
            logger.error(ex);
            request.setAttribute("exception", new ServerSideException("CANT_SAVE_MODULE"));
            request.getRequestDispatcher("index.jsp").forward(request, response);
        } catch (Exception ex) {
            logger.error(ex);
            throw ex;
        }
    }

    /**
     * Loads a result request object from the DB if possible
     *
     * @param request
     * @param response
     * @throws Exception When DB fails or other failure occures
     */
    private void showResult(HttpServletRequest request, HttpServletResponse response) throws Exception {
        logger.debug("showResult() called.");
        try {
            Long id = new Long(request.getParameter("module"));
            ResultManagerFacade facade = new ResultManagerFacade();
            Result result = facade.loadResult(id);
            request.setAttribute("module", result);
            request.setAttribute("patient", result.getPatient());
            request.setAttribute("labels", new SampleManagerFacade().listSampleTypes("oneLetterCode"));
            request.setAttribute("answer", true);
            request.getRequestDispatcher("index.jsp").forward(request, response);
        } catch (Exception ex) {
            logger.error(ex);
            throw ex;
        }
    }// </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">

    /**
     * Handles the HTTP <code>GET</code> method.
     *
     * @param request  servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException      if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Handles the HTTP <code>POST</code> method.
     *
     * @param request  servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException      if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Returns a short description of the servlet.
     *
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>

    private void listTemplates(HttpServletRequest request, HttpServletResponse response) throws Exception {
        logger.debug("listTemplates() called.");
        List<Result> templates = null;
        try {
            int page = 0;
            int size = 25;
            try {
                page = Integer.parseInt(request.getParameter("page"));
                size = Integer.parseInt(request.getParameter("size"));
            } catch (Exception ex) {
                //IGNORED, parameters can be empty
                logger.debug("No page size or page number found, using default.");
            }
            ResultManagerFacade facade = new ResultManagerFacade();
            int maxpage = 0;
            templates = facade.listTemplates(page, size);
            maxpage = facade.getNumberOfTemplatePages(size);
            request.setAttribute("current", page);
            request.setAttribute("size", size);
            request.setAttribute("maxpage", maxpage);
            request.setAttribute("site", "listtemplates.html");
            request.setAttribute("templates", templates);
            request.setAttribute("answer", true);
            request.getRequestDispatcher("index.jsp").forward(request, response);
        } catch (Exception ex) {
            logger.error(ex);
            throw ex;
        }
    }
}
