package sac.bibliografia;

import java.text.SimpleDateFormat;
import java.text.ParseException;

import java.io.IOException;

import java.util.Map;
import java.util.Hashtable;
import java.util.List;
import java.util.LinkedList;
import java.util.Iterator;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletException;

import java.util.Date;

import sac.exception.ItemJaCadastradoException;
import sac.exception.NullArgumentException;
import sac.exception.InvalidArgumentException;
import sac.persistencia.PersistenceException;
import sac.exception.NomeInvalidoException;

import sac.gui.handler.SACHandler;

import sac.persistencia.OID;

import sac.fachada.SACFachada;

/**
 * Handler para o formulário de login no sistema.
 *
 */
public class CadastroReferenciaBibliograficaHandler extends SACHandler {

    /** Constante que define o Name do Hidden de um Form que
     * identifica unicamente o Handler que tratará a operação
     * de logar.
     */
    // FIXME - deve estar num arquivo de propriedades
    private static final String OPERACAO_CADASTRO = "InsercaoOperation";
    private static final String OPERACAO_LOOKUP = "LookupOperation";
    private static final String OPERACAO_ALTERACAO = "AlteracaoOperation";
    private static final String OPERACAO_LISTAGEM = "ListaOperation";
    private static final String OPERACAO_FILLFORM = "FillFormOperation";


    private static final String URL_CADASTRO_REFERENCIA_BIBLIOGRAFICA_OK = "/jsp/operacaoOk.jsp";
    private static final String URL_CADASTRO_REFERENCIA_BIBLIOGRAFICA = "/jsp/cadastroReferenciaBibliografica.jsp";
    private static final String URL_LISTA_REFERENCIA_BIBLIOGRAFICA = "/jsp/lista_referencia_bibliografica.jsp";

    /** Constantes utilizadas no Request desse Handler.*/
    private static final String REFERENCIA_BIBLIOGRAFICA_BEAN_REQUEST = "referenciaBean";
    private static final String REFERENCIA_BIBLIOGRAFICA_BEAN_LIST = "referenciasBeanList";



    /** Guarda o mapeamento (operacao, Handler)
     */
    protected Map functionImplementers;

    /** Guarda o último handler solicitado.
     */
    protected SACHandler currentImplementer;

    /** Guarda a última operação solicitada.
     */
    protected String currentFunction;

    /** Creates new MenuHandler */
    public CadastroReferenciaBibliograficaHandler() {
        super();
        this.functionImplementers = new Hashtable();
        this.functionImplementers.put(OPERACAO_CADASTRO, new InsercaoReferenciaBibliograficaHandler());
        this.functionImplementers.put(OPERACAO_LOOKUP, new LookupReferenciaBibliograficaHandler());
        this.functionImplementers.put(OPERACAO_ALTERACAO, new AtualizaReferenciaBibliograficaHandler());
        this.functionImplementers.put(OPERACAO_FILLFORM, new FillFormReferenciaBibliograficaHandler());
        this.functionImplementers.put(OPERACAO_LISTAGEM, new ProcuraReferenciaBibliograficaHandler());
    }

    /** Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
     * @param request servlet request
     * @param response servlet response
     * @param fachada fachada do Sistema
     * @return String a url do form a ser retornado
     */
    public String processRequest(HttpServletRequest request, HttpServletResponse response, SACFachada sacFachada)
    throws ServletException, IOException {
        String functionName = request.getParameter(SACHandler.FUNCTION_ID);
        String res = null;
        Object handler;
        if (functionName.equals(currentFunction)) {
            handler = currentImplementer;
        } else {
            handler = functionImplementers.get(functionName);
        }
        if (handler != null) {
            res = ((SACHandler) handler).processRequest(request, response, sacFachada);
            this.currentFunction = functionName;
            this.currentImplementer = (SACHandler) handler;
        } else {
            System.out.println("Nao conseguiu obter o handler " + functionName);
        }
        return res;
    }

    /**
     * Handler para a operacao de cadastro de Pessoa física no sistema.
     */
    private class InsercaoReferenciaBibliograficaHandler extends SACHandler {


        /** Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
         * @param request servlet request
         * @param response servlet response
         * @param fachada fachada do Sistema
         * @return String a url do form a ser retornado
         */
         public String processRequest(HttpServletRequest request, HttpServletResponse response,
                 SACFachada fachada) throws ServletException, IOException{

            String res = null;
            ReferenciaBibliograficaBean referenciaBean = null;

            try {
              String oid = request.getParameter("OID");
              referenciaBean = new ReferenciaBibliograficaBean(request);
              referenciaBean.validaBean();
              if (oid==null || oid.equals("")) {
                fachada.cadastraReferenciaBibliografica(referenciaBean.getReferenciaBibliografica());
              }
              else {
                System.out.println("oid="+oid+".");
                OID oidObj = new OID(Long.parseLong(oid));
                ReferenciaBibliografica oldRef = new ReferenciaBibliografica();
                ReferenciaBibliografica newRef = referenciaBean.getReferenciaBibliografica();
                oldRef.setID(oidObj);
                fachada.alterarReferenciaBibliografica(oldRef,newRef);
              }
              res = URL_CADASTRO_REFERENCIA_BIBLIOGRAFICA_OK;
            }
            catch (CampoInvalidoException exc) {
              request.setAttribute(REFERENCIA_BIBLIOGRAFICA_BEAN_REQUEST, referenciaBean);
              res = URL_CADASTRO_REFERENCIA_BIBLIOGRAFICA;
            }
            catch (ItemJaCadastradoException ijce) {
                String erro = "Item já cadastrado";
                String mensagem = "";
                String oldMessage = referenciaBean.getMensagemErro();
                if (oldMessage!=null && !oldMessage.equals("null")) {
                  mensagem = oldMessage;
                }
                mensagem = mensagem +"\nJa existe uma referencia com esse autor/titulo";
                referenciaBean.setMensagemErro(mensagem);
                request.setAttribute(REFERENCIA_BIBLIOGRAFICA_BEAN_REQUEST, referenciaBean);
                res = URL_CADASTRO_REFERENCIA_BIBLIOGRAFICA;
            }
            catch (ReferenciaBibliograficaNaoCadastradaException exc) {
                String erro = "Item nao cadastrado";
                request.setAttribute(REFERENCIA_BIBLIOGRAFICA_BEAN_REQUEST, referenciaBean);
                res = URL_CADASTRO_REFERENCIA_BIBLIOGRAFICA;
            }
            catch (NomeInvalidoException exc) {
                String erro = "Problemas com algum campo";
                request.setAttribute(REFERENCIA_BIBLIOGRAFICA_BEAN_REQUEST, referenciaBean);
                res = URL_CADASTRO_REFERENCIA_BIBLIOGRAFICA;
            }

            catch (NullArgumentException exc) {
              throw new ServletException(exc);
            }
            catch (PersistenceException exc) {
              throw new ServletException(exc);
            }
            catch (InvalidArgumentException exc) {
              throw new ServletException(exc);
            }
            return res;
        }
    }

    private class LookupReferenciaBibliograficaHandler extends SACHandler {
         public String processRequest(HttpServletRequest request, HttpServletResponse response,
                 SACFachada fachada) throws ServletException, IOException {

         String oid = request.getParameter("OID");
         OID oidObj = new OID(Long.parseLong(oid));

         try {
           ReferenciaBibliografica ref = fachada.procuraReferenciaBibliografica(oidObj);
           ReferenciaBibliograficaBean bean = new ReferenciaBibliograficaBean(ref);
           request.setAttribute(REFERENCIA_BIBLIOGRAFICA_BEAN_REQUEST, bean );
           request.setAttribute("alterar", request.getParameter("alterar") );
         }
         catch (Exception exc) {
           throw new ServletException(exc);
         }

         return URL_CADASTRO_REFERENCIA_BIBLIOGRAFICA;
      }
    }

    private class AtualizaReferenciaBibliograficaHandler extends SACHandler {
         public String processRequest(HttpServletRequest request, HttpServletResponse response,
                 SACFachada fachada) throws ServletException, IOException {

//         String oid = request.getParameter("OID");
//         OID oidObj = new OID(Long.parseLong(oid));
//
//         fachada.cadastraReferenciaBibliografica();
//
//
//         request.setAttribute(REFERENCIA_BIBLIOGRAFICA_BEAN_REQUEST, myBean);

         return URL_CADASTRO_REFERENCIA_BIBLIOGRAFICA;
      }

    }

    private class ProcuraReferenciaBibliograficaHandler extends SACHandler {
         public String processRequest(HttpServletRequest request, HttpServletResponse response,
                 SACFachada fachada) throws ServletException, IOException {

         String autor = request.getParameter("Autor");
         String titulo = request.getParameter("Titulo");

         FiltroBuscaReferencia filtro = new FiltroBuscaReferencia();
         filtro.setAutor(autor);
         filtro.setTitulo(titulo);

         List referenciasList = null;
         try {
           referenciasList = fachada.procuraReferenciaBibliografica(filtro);
         }
         catch (ReferenciaBibliograficaNaoCadastradaException exc) {
          referenciasList = new LinkedList();
         }
         catch (Exception exc) {
          throw new ServletException(exc);
         }

         List referenciasBeanList = converterListaReferenciaBibliografica(referenciasList);


         request.setAttribute(REFERENCIA_BIBLIOGRAFICA_BEAN_LIST, referenciasBeanList);
         request.setAttribute("start",request.getParameter("start"));
         request.setAttribute("size",request.getParameter("size"));
         request.setAttribute("autor",autor);
         request.setAttribute("titulo",titulo);


         return URL_LISTA_REFERENCIA_BIBLIOGRAFICA;
      }

      private List converterListaReferenciaBibliografica(List referenciasList) {
        List referenciasBeanList = new LinkedList();
        Iterator iter = referenciasList.iterator();
        while (iter.hasNext()) {
          referenciasBeanList.add(new ReferenciaBibliograficaBean((ReferenciaBibliografica)iter.next()));
        }
        return referenciasBeanList;
      }

    }



    private class FillFormReferenciaBibliograficaHandler extends SACHandler {

         public String processRequest(HttpServletRequest request, HttpServletResponse response,
                 SACFachada fachada) throws ServletException, IOException {

            ReferenciaBibliograficaBean myBean = new ReferenciaBibliograficaBean();
            myBean.inicializaBeanVazio();

            request.setAttribute(REFERENCIA_BIBLIOGRAFICA_BEAN_REQUEST, myBean);

            return URL_CADASTRO_REFERENCIA_BIBLIOGRAFICA;

        }
    }

}