/* 
* Copyright 2016 Agencia Estatal de Administración Tibutaria
*
* Licencia con arreglo a la EUPL, Versión 1.1 o –en cuanto
* sean aprobadas por la Comisión Europea– versiones
* posteriores de la EUPL (la «Licencia»);
* Solo podrá usarse esta obra si se respeta la Licencia.
* Puede obtenerse una copia de la Licencia en:
*  
* https://joinup.ec.europa.eu/software/page/eupl
*  
* Salvo cuando lo exija la legislación aplicable o se acuerde
* por escrito, el programa distribuido con arreglo a la
* Licencia se distribuye «TAL CUAL», SIN GARANTÍAS NI CONDICIONES
* DE NINGÚN TIPO, ni expresasni implícitas.
*
* Véase la Licencia en el idioma concreto que rige los permisos y 
* limitaciones que establece la Licencia.
*/ 

package gestor.datos;

import gestor.utiles.*;
import java.sql.Timestamp;
import java.util.*;
import gestor.Configuracion;
import gestor.DlgMensajeGenerico;

public class TablaCandidatos {

    protected ArrayList<RegistroCandidatos> datos;
    protected ArrayList<RegistroCandidatos> datosTotal;
    private static TablaCandidatos yo = null;
    public boolean cargada = false;
    Configuracion conf;
    TablaColas Colas;
    public int malas = 0;

    public TablaCandidatos() {
        datos = new ArrayList<>();
        datosTotal = new ArrayList<>();
        conf = Configuracion.instanciaUnica();
        Colas = TablaColas.getTablaColas();
    }

    public static TablaCandidatos getTablaCandidatos() {
        if (yo == null) {
            yo = new TablaCandidatos();
        }
        return yo;
    }

    public void vaciar() {
        datos.clear();
        datosTotal.clear();
    }

    public int recordsCount() {
        return datos.size();
    }

    public void ordena() {
        Collections.sort(datos);
    }

    public RegistroCandidatos getRegistro(int id) {
        int n = datos.size();
        for (int i = 0; i < n; i++) {
            RegistroCandidatos rb = datos.get(i);
            if (rb.id == id) {
                return rb;
            }
        }
        return null;
    }

    public void cabiaEstadoVinculados(String codigoCita, String nuevoEstado, Timestamp horaPresente, Timestamp horaCalculada) {
        int n = datos.size();
        for (int i = 0; i < n; i++) {
            RegistroCandidatos r = datos.get(i);
            if (r.citaVinculada.equals(codigoCita) && !r.estado.equals("P") && r.citaMultiple > 1) {
                r.cambiaEstado(nuevoEstado, horaPresente, horaCalculada);
            }
        }
    }

    public String getnifVinculados(String codigoCita) {
        String cad = "";
        int n = datos.size();
        for (int i = 0; i < n; i++) {
            RegistroCandidatos r = datos.get(i);
            if (r.citaVinculada.equals(codigoCita)) {
                cad += r.nif + "  " + r.nombre + "<br/>";
            }
        }
        return cad;
    }

    public String getnifVinculados(String codigoCita, TablaCandidatos copia) {
        String cad;
        cad = "";
        HashSet<String> repes = new HashSet<>();
        for (RegistroCandidatos r : datos) {
            if (r.citaVinculada.equals(codigoCita) && r.citaMultiple > 1) {
                if (!repes.contains(r.nif)) {
                    cad = cad + r.nif + "  " + r.nombre + "<br>";
                    repes.add(r.nif);
                }
                if (copia != null) {
                    copia.copiaRegistro(r);
                }
            }
        }
        if (copia != null) {
            copia.ordena();
        }
        return cad;
    }

    public void copiaRegistro(RegistroCandidatos nr) {
        datos.add(nr);
    }

    public RegistroCandidatos buscarPorId(int id) {
        for (RegistroCandidatos rb : datos) {
            if (rb.id == id) {
                return rb;
            }
        }
        return null;
    }

    public RegistroCandidatos buscarPorIdSinMover(int id) {
        for (RegistroCandidatos rb : datos) {
            if (rb.id == id) {
                return rb;
            }
        }
        return null;
    }

    // Para evitar las citas dobles (vinculadas con el mismo nif)
    boolean citasNoContiene(ArrayList<RegistroCandidatos> citas, String codigo) {
        if (codigo.equals(" ") || codigo.equals("")) {
            return true;
        }
        for (RegistroCandidatos rb : citas) {
            if (rb.citaVinculada.equals(codigo)) {
                return false;
            }
        }
        return true;
    }

//    public boolean tieneCitaAnterior(ArrayList citas, String cola) {
//        for (Object cita : citas) {
//            RegistroCandidatos rb = (RegistroCandidatos) cita;
//            if (rb.cola.equals(cola)) {
//                return true;
//            }
//        }
//        return false;
//    }
    public RegistroCandidatos primerRegistro() {
        return datos.get(0);
    }

    public RegistroCandidatos buscarTodosConNif(String nif, ArrayList<RegistroCandidatos> citas) {
        RegistroCandidatos rEnc = null;
        malas = 0;
        for (RegistroCandidatos r : datos) {
            if (r.nif.equalsIgnoreCase(nif) && !r.estado.equals("B")) {
                if (citasNoContiene(citas, r.citaVinculada.trim())) {
                    if (Colas.contieneCola(r.cola)) {
                        citas.add(r);
                        rEnc = r;
                    } else {
                        malas++;
                    }
                }
            }
        }
        if (malas > 0) {
            DlgMensajeGenerico dlg = new DlgMensajeGenerico(null);
            dlg.setLinea1(Global.trad.valor("AtencionSala"));
            if (citas.size() > 0) {
                dlg.setLinea2(Global.trad.valor("esteservicionosegestiona"));
            }
            dlg.setLinea3(Global.trad.valor("acudaAlGestor"));
            dlg.centrarLineas(true, true, true);
            dlg.setVisible(true);
        }
        return rEnc;
    }

    public int comprobarEstadoCitas(ArrayList<RegistroCandidatos> citas) {
        if (citas.size() == 1) {
            RegistroCandidatos rb = citas.get(0);
            //   Colas.contieneCola(rb.cola);
            if (rb.esEstadoEnBlanco()) {
                if (rb.citaMultiple == 1) {
                    return 1;
                } else {
                    return 2;
                }
            } else {
                return 0;
            }
        }
        if (citas.size() > 1) {
            return 3;
        }
        return -1;
    }

    public ArrayList<RegistroCandidatos> buscarVinculados(String codigoCita, int id) {
        ArrayList<RegistroCandidatos> lista = new ArrayList<>();
        for (RegistroCandidatos r : datos) {
            if (r.citaVinculada.equals(codigoCita) && r.id != id) {
                lista.add(r);
            }
        }
        return lista;
    }

    public boolean algunoEnHora(ArrayList<RegistroCandidatos> citas) {
        long ahora = new Date().getTime();
        for (RegistroCandidatos r : citas) {
            if (r.estado.equals(" ") || r.estado.equals("P") || r.estado.equals("X")) {
                if (Global.compruebaHoraCalculada(ahora, r.horaCita.getTime()) < 3) {
                    return true;
                }
                if (r.citaMultiple > 1) {
                    ArrayList<RegistroCandidatos> vinculados = buscarVinculados(r.citaVinculada, r.id);
                    for (RegistroCandidatos rv : vinculados) {
                        if (Global.compruebaHoraCalculada(ahora, rv.horaCita.getTime()) < 3) {
                            return true;
                        }
                    }
                }
            }
        }
        return false;
    }

    public void cambiaTurno() {
        if (conf.ignorarTurnos) {
            return;
        }
        datos.clear();
        String turno = Global.mainForm.getTurno();
        for (RegistroCandidatos r : datosTotal) {
            if (r.turno.equals(turno)) {
                datos.add(r);
            }
        }
    }

    public RegistroCandidatos nuevoRegistro(String reg) {
        try {
            RegistroCandidatos r = new RegistroCandidatos();
            r.leerRegistroCompleto(reg);
            RegistroCandidatos r2 = buscarPorId(r.id);
            if (r2 != null) {
                r = r2;
                r.leerRegistroCompleto(reg);
            } else {
                datosTotal.add(r);
                if (conf.ignorarTurnos || r.turno.equals(Global.mainForm.getTurno())) {
                    datos.add(r);
                }
            }
            return r;
        } catch (Exception exc) {
            exc.printStackTrace();
            return null;
        }
    }

    public RegistroCandidatos modificaRegistro(String reg) {
        try {
            RegistroCandidatos r = new RegistroCandidatos();
            r.leerRegistroCompleto(reg);
            RegistroCandidatos r2;
            if ((r2 = buscarPorIdSinMover(r.id)) != null) {
                r = r2;
                r.leerRegistroCompleto(reg);
            }
            return r;
        } catch (Exception Exc) {
            //TODO tratar esta excepcion, quizas devolver codigo de error al servidor?
            return null;
        }
    }

    public RegistroCandidatos primeroEnHora() {
        try {
            long ahoraMismo = System.currentTimeMillis();
            for (RegistroCandidatos reg : datos) {
                int r = Global.compruebaHoraCalculada(ahoraMismo, reg.horaCita.getTime());
                if (r < 3) {
                    reg.horaCalculada = Global.calcularHora(r, reg.horaCita, ahoraMismo);
                    reg.horaCalculada2 = reg.horaCalculada;
                    return reg;
                }
            }
        } catch (Exception exc) {
        }
        return null;
    }
}
