/* 
* 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.io.*;
import java.sql.Timestamp;
import java.util.*;
import gestor.utiles.Fecha;
import java.util.logging.Level;

public class TablaHuecos {

    protected ArrayList<RegistroHuecos> datos;
    protected int posActual;
    private static TablaHuecos yo = null;
    public boolean cargada = false;
     HashMap<String, String> rangos;

    protected TablaHuecos() {
        datos = new ArrayList<>();
        rangos = new HashMap<>();
    }

    public static TablaHuecos getTablaHuecos() {
        if (yo == null) {
            yo = new TablaHuecos();
        }
        return yo;
    }
    public void cargarRangoHuecos(String listarango) {
      if (rangos == null) {
         rangos = new HashMap<>();
      }
      rangos.clear();
      String[] lineas = Global.split(listarango, '|');
        for (String linea : lineas) {
            String[] campos = Global.split(linea, '=');
            if (campos.length == 2) {
                rangos.put(campos[0], campos[1]);
            }
        }
   }

   public String buscarRangoHuecos(String cola) {
      if (rangos.containsKey(cola)) {
         return rangos.get(cola);
      }
      return cola;
   }


    public void vaciar() {
        datos.clear();
        cargada = false;
    }

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

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

    public RegistroHuecos getRegistroNum(int i) {
        return datos.get(i);
    }

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

    public void nuevoHueco(Timestamp hora, String cola, String turno) {
        RegistroHuecos r = new RegistroHuecos();
        r.horaCita = hora;
        r.turno = turno;
        r.cola = cola;
        datos.add(r);
    }

    public RegistroHuecos buscarPorHora(Timestamp hora) {
        int n = datos.size();
        if (n == 0) {
            return null;
        }
        for (int i = 0; i < n; i++) {
            RegistroHuecos rb = datos.get(i);
            if (rb.horaCita.equals(hora)) {
                return rb;
            }
        }
        return null;
    }

   public void eliminar(String msg) {
      String[] params = Global.split(msg, '|');
      try {
         String colaR =  buscarRangoHuecos(params[0]);
         Timestamp hora = Timestamp.valueOf(params[1]);
         int cuantos = Integer.parseInt(params[2]);
         for (ListIterator<RegistroHuecos> it = datos.listIterator(); it.hasNext();) {
            RegistroHuecos rb = it.next();
            if (rb.cola.equals(colaR) && rb.horaCita.equals(hora)) {
               it.remove();
               cuantos--;
               if (cuantos == 0) {
                  break;
               }
            }
         }
      } catch (Exception exc) {
         Global.principal.msgBox("Excepción al eliminar registros de hueco:\n" + exc.getMessage());
      }
   }
    public void eliminarTodos(String cola, Timestamp hora) {
      try {
         String colaR =  buscarRangoHuecos(cola);
         for (ListIterator<RegistroHuecos> it = datos.listIterator(); it.hasNext();) {
            RegistroHuecos rb = it.next();
            if (rb.cola.equals(colaR) && rb.horaCita.equals(hora)) {
               it.remove();
            }
         }
      } catch (Exception exc) {
         Global.principal.msgBox("Excepción al eliminar registros de hueco:\n" + exc.getMessage());
      }
   }

    public RegistroHuecos[] buscarDisponibles(String cola, Timestamp hora) {
      int n = datos.size();
      if (n == 0) {
         return null;
      }
      String colaR =  buscarRangoHuecos(cola);
      HashMap<RegistroHuecos, RegistroHuecos> encontrados = new HashMap<>();
      for (int i = 0; i < n; i++) {
         RegistroHuecos rb = datos.get(i);
         if (rb.cola.equals(colaR) && rb.horaCita.compareTo(hora) >= 0) {
            encontrados.put(rb, rb);
         }
      }
      if (encontrados.size() > 0) {
         RegistroHuecos[] regs = new RegistroHuecos[encontrados.size()];
         regs = encontrados.values().toArray(regs);
         Arrays.sort(regs);
         return regs;
      }
      return null;
   }
     public boolean sigueDisponible(String cola, Timestamp hora) {
      String colaR =  buscarRangoHuecos(cola);
        for (RegistroHuecos rb : datos) {
            if (rb.cola.equals(colaR) && rb.horaCita.equals(hora)) {
                return true;
            }
        }
      return false;
   }
    public void incorporarCitas(String cola, String turno, String mapa) {
        Calendar cal = new GregorianCalendar();
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        long lasSeis = cal.getTimeInMillis();
        for (int i = 0; i < mapa.length(); i += 6) {
            String sm = "", sn = "";
            try {
                sm = mapa.substring(i, i + 4);
                long delta = Long.parseLong(sm) * 60000L;
                Timestamp hora = new Timestamp(lasSeis + delta);
                sn = mapa.substring(i + 4, i + 6);
                int numero = Integer.parseInt(sn);
                for (int j = 0; j < numero; j++) {
                    nuevoHueco(hora, cola, turno);
                }
            } catch (Exception ex) {
                gestor.Main.log.log(Level.SEVERE, "Error al incorporar Hueco: {0} {1}\n{2}", new Object[]{sm, sn, ex.getMessage()});
                ex.printStackTrace();
            }
        }
        ordenar();
    }

    public RegistroHuecos nuevoRegistro(String reg) {
        try {
            RegistroHuecos r = new RegistroHuecos();
            r.leerRegistroCompleto(reg);
            datos.add(r);
            return r;
        } catch (Exception exc) {
            exc.printStackTrace();
            return null;
        }
    }

    public void finCarga() {
        cargada = true;
        ordenar();
    }

    // SOLO para comprobacion y depuracion
    public void listarHuecos() {
        try {
            PrintStream salida = new PrintStream(new FileOutputStream("ListadoHuecos.log", true));
            salida.println("Huecos a " + Fecha.ahora().toString());
            salida.println("--------------------------------------------");
            synchronized (datos) {
                for (RegistroHuecos rb : datos) {
                    salida.println(rb.toString());
                }
            }
            salida.close();
        } catch (Exception exc) {
            exc.printStackTrace();
        }
    }
    
    public boolean todosFueraDeTurno(RegistroHuecos[] regs) {
       if(regs == null || regs.length == 0)  return false;
       String turno = Global.main.getTurno();
        for (RegistroHuecos reg : regs) {
            if (reg.turno.equals(turno)) {
                return false;
            }
        }
       return true;       
    }
}

