/* 
* 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;

import java.awt.*;
import java.awt.Color;
import java.awt.Font;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.*;
import javax.swing.*;
import gestor.datos.*;
import gestor.utiles.Fecha;
import gestor.utiles.PercentLayout;
import gestor.utiles.Global;
import java.util.logging.Level;

public final class FormPrincipal extends javax.swing.JFrame {

    //<editor-fold desc="Constantes y variables ">
    private static final int DESCONECTADO = 0;
    private static final int CONECTADO = 1;
    private static final int LIBRE = 2;
    private static final int EN_TRANSITO = 3;
    private static final int OCUPADO = 4;
    private static final int DESCANSO = 5;
    private static final int ERROR_ESTADO = 6;

    private java.awt.event.MouseListener mesaMouseListener;
    private javax.swing.Timer timerCierraAviso;
    Configuracion conf;
    ImageIcon[] iconos;
    int numeroMesas;
    int anchoBotonMesa = 60;
    boolean modoAutomatico = false;
    BotonMesa botonPulsado = null;
    TablaCandidatos presentes;
    TModelPresentes tmPresentes;
    public FormCandidatos formCandidatos;
    FormNuevoCandidato fichaNuevoCandidato;
    boolean botonSiguiente = false;
    String tituloBase;
    public boolean solicitadaAperturaNuevo = false;
    public boolean solicitadaAperturaRelacion = false;
    HashMap<String, Puesto> puestos;

    //</editor-fold>
    public FormPrincipal(int numeroMesas) {
        conf = Configuracion.instanciaUnica();
        Global.principal = this;
        this.numeroMesas = numeroMesas;
        try {
            setIconImage(new javax.swing.ImageIcon(getClass().getResource("/recursos/ateneo32x32.gif")).getImage());
        } catch (Exception exc) {
            exc.printStackTrace();
        }

        initComponents();
        if (!conf.gestorPrincipal) {
            this.cbxModoAutomatico.setEnabled(false);
            this.btSiguiente.setEnabled(false);
        }
        ponLayout();
        preparaTimerAviso();
        ponerTituloVentana();
        preparaBotones();
        preparaDatosYGrid();
        vaciaListaMensajesPendientes();
        pasoAAutomatico(Global.modoAutomatico);
    }

    String leerVersion() {
        File jar = new File("Gestor.jar");
        Date d = new Date(jar.lastModified());
        SimpleDateFormat timeFormat = new java.text.SimpleDateFormat("dd/MM HH:mm");
        return "- " + timeFormat.format(d) + " - ";
    }

    public void ponerTituloVentana() {
        tituloBase = "Gestor ATENEO " + leerVersion();
        this.setTitle(tituloBase
                + "  Turno: " + (Global.main.getTurno().equals("M") ? "Mañana" : "Tarde"));
        if (formCandidatos != null) {
            formCandidatos.resetComboTurno();
        }
    }

    void preparaTimerAviso() {
        timerCierraAviso = new javax.swing.Timer(conf.tiempoAvisoSiguiente, new java.awt.event.ActionListener() {

            @Override
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                tickCierraAviso();
            }
        });
    }

    void tickCierraAviso() {
        ((java.awt.CardLayout) panelApilado.getLayout()).show(panelApilado, "cardScroll");
        timerCierraAviso.stop();
    }

    void ponLayout() {
        PercentLayout pl = new PercentLayout(PercentLayout.VERTICAL, 0);
        pl.addLayoutComponent(panelDerecho.getComponent(0), "70%");
        pl.addLayoutComponent(panelDerecho.getComponent(1), "30%");
        panelDerecho.setLayout(pl);
    }

    void preparaBotones() {
        mesaMouseListener = new java.awt.event.MouseAdapter() {

            @Override
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                if (conf.gestorPrincipal && !modoAutomatico) {
                    mesaMouseClicked(evt);
                }
            }

            @Override
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                ((JButton) evt.getComponent()).setBorderPainted(true);
            }

            @Override
            public void mouseExited(java.awt.event.MouseEvent evt) {
                ((JButton) evt.getComponent()).setBorderPainted(false);
            }

            @Override
            public void mouseReleased(java.awt.event.MouseEvent evt) {
                botonPulsado = (BotonMesa) evt.getComponent();
                if (evt.getButton() == java.awt.event.MouseEvent.BUTTON3) {
                    mostrarMenuBotonMesa(evt.getPoint().x, evt.getPoint().y);
                }
            }
        };
        iconos = new ImageIcon[7];
        cargarIconos();
        if (numeroMesas > 0) {
            puestos = new HashMap<>(numeroMesas);
            for (int i = 1; i <= numeroMesas; i++) {
                nuevaMesa(String.valueOf(i));
            }
            panelMesas.revalidate();
            panelMesas.repaint();
        } else {
            puestos = new HashMap<>(50);
            Comunicaciones.comm.enviar(Comunicaciones.ENVIAR_TABLA_PUESTOS);
        }
    }

    void puestosCargados() {
        TablaPuestos tpuestos = TablaPuestos.getTablaPuestos();
        int num = tpuestos.numPuestos();
        for (int i = 0; i < num; i++) {
            TablaPuestos.Puesto p = tpuestos.puesto(i);
            if (!puestos.containsKey(p.nombre)) {
                nuevaMesa(p.nombre);
            }
        }
        this.reorganizarBotones();
    }

    void mostrarMenuBotonMesa(int x, int y) {
        int estado = botonPulsado.puesto.estado;
        if (estado == DESCONECTADO) {
            menuitemMensajeMesa.setEnabled(false);
        } else {
            menuitemMensajeMesa.setEnabled(true);
        }
        this.popupMenuMesas.show(botonPulsado, x, y);
    }

    void mensajeAMesa() {
        String mesaPulsada = (String) botonPulsado.puesto.denominacion;
        DlgMensaje dlg = new DlgMensaje(this);
        dlg.setTitle("Mensaje al Operador");
        dlg.setSize(415, 200);
        dlg.setLocationRelativeTo(this);
        dlg.setVisible(true);
        if (dlg.enviar) {
            Comunicaciones.comm.enviar(Comunicaciones.MENSAJE_A_MESA,
                    "gestor" + Global.main.numeroGestor, mesaPulsada, dlg.mensaje);
        }
        dlg.dispose();
    }

    void preparaDatosYGrid() {
        tmPresentes = new TModelPresentes();
        grid.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        grid.getTableHeader().setReorderingAllowed(false);
        grid.setModel(tmPresentes);
        tmPresentes.anchosColumna(grid);
    }

    void preparaFormCandidatos() {
        formCandidatos = new FormCandidatos();
        formCandidatos.setSize(790, 550);
        formCandidatos.setLocationRelativeTo(null);
    }

    void vaciaListaMensajesPendientes() {
        Iterator it = Global.main.mensajesPendientes.iterator();
        while (it.hasNext()) {
            cambioEstadoMesa((String) it.next());
        }
        Global.main.mensajesPendientes.clear();
    }

    void refrescarDatos(boolean reordenar) {
        tmPresentes.recargaDatos();
        grid.revalidate();
        this.repaint();
        if (formCandidatos != null) {
            formCandidatos.refrescarDatos(reordenar);
        }
    }

    public void confirmarModoAutomatico(String msgMonitores) {
        String[] monitores = Global.split(msgMonitores, '|');
        if (monitores.length == 0) {
            Global.principal.monitorDesconectado("NO HAY NINGÚN MONITOR CONECTADO");
            return;
        }
        if (msgMonitores.equals("MONITORES NO")) {
            ponModoAutomatico(true);
        } else {
            String s = "Monitores conectados:\n\n";
            for (String monitor : monitores) {
                s += "   " + monitor + "\n";
            }
            s += "\nConfirme el paso a modo automatico";
            if (JOptionPane.showConfirmDialog(this, s, "CONFIRMACION MODO AUTOMÁTICO", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
                ponModoAutomatico(true);
            } else {
                ponModoAutomatico(false);
            }
        }
    }

    public void solicitarModoAutomatico() {
        boolean auto = cbxModoAutomatico.isSelected();
        if (auto) {
            Comunicaciones.comm.enviar(Comunicaciones.SOLICITO_MONITORES, Global.main.numeroGestor);
        } else {
            ponModoAutomatico(false);
        }
    }

    public void ponModoAutomatico(boolean auto) {
        modoAutomatico = auto;
        btSiguiente.setEnabled(!auto);
        cbxModoAutomatico.setSelected(auto);
        Comunicaciones.comm.enviar(Comunicaciones.SOLICITO_CAMBIO_AUTOMATICO, Global.main.numeroGestor, String.valueOf(auto));
    }

    public void pasoAAutomatico(boolean auto) {
        modoAutomatico = auto;
        cbxModoAutomatico.setSelected(auto);
    }

    public void monitorDesconectado(String texto) {
        pasoAAutomatico(false);
        Global.mensajeUrgente(texto);
    }

    void cargarIconos() {
        try {
            for (int i = 0; i < 7; i++) {
                ImageIcon icono = new ImageIcon(getClass().getResource("/recursos/estado" + (i) + ".gif"));
                iconos[i] = icono;
            }
        } catch (Exception exc) {
            Main.log.log(Level.SEVERE, "Error cargando los BMP de mesa: {0}", exc.getMessage());
        }
    }

    void reorganizarBotones() {
        panelMesas.removeAll();
        TablaPuestos tpuestos = TablaPuestos.getTablaPuestos();
        int num = tpuestos.numPuestos();
        for (int i = 0; i < num; i++) {
            Puesto p = puestos.get(tpuestos.puesto(i).nombre);
            panelMesas.add(p.boton);
        }
        panelMesas.revalidate();
        panelMesas.repaint();
    }

    public void cambioEstadoMesa(String msj) {
        String params[] = msj.split("\\|", 3);
        if (!puestos.containsKey(params[0])) {
            TablaPuestos.getTablaPuestos().nuevoPuesto(params[0]);
            nuevaMesa(params[0]);
            reorganizarBotones();
        }
        try {
            Puesto puesto = puestos.get(params[0]);
            int estado = Integer.parseInt(params[1]);
            puesto.ponerEstado(estado);
            switch (estado) {
                case DESCONECTADO:
                    puesto.borrarTodo();
                    break;
                case EN_TRANSITO:
                    enviaPresenteAMesa(puesto, params[0], params[2]);
                    break;
                case LIBRE:
                case DESCANSO:
                    puesto.borrarTique();
                    break;
            }
            // al conectar el servidor manda mensajes con los operadores en mesa
            // comprobamos el largo para no confundir este caso con EN_TRANSITO
            if (params.length == 3 && params[2].length() < 50) {
                puesto.operador = params[2];
            }
            ponToolTipBotonMesa(puesto);
        } catch (Exception exc) {
            Main.log.log(Level.WARNING, "Error en los par\u00e1metros del mensaje CAMBIO ESTADO MESA:\n{0}", msj);
        }
    }

    public void ponToolTipBotonMesa(Puesto puesto) {
        if (puesto.estado != DESCONECTADO) {
            String tooltip = "<html>" + puesto.operador;
            String ticket = puesto.ticket;
            if (ticket != null) {
                tooltip += "<br>atendiendo " + ticket;
            }
            tooltip += "</html>";
            puesto.boton.setToolTipText(tooltip);
        } else {
            puesto.boton.setToolTipText(null);
        }
    }

    public boolean enviaPresenteAMesa(Puesto puesto, String mesa, String registro) {
        String[] params = Global.split(registro, '|');
        if (params.length < 11) {
            puesto.operador = registro;
            puesto.ticket = null;
            return false;
        }
        String nombre = params[2];
        String ticket = params[11];
        Global.main.cambiaEstadoCandidato(registro);
        String ahora = Fecha.formatoHoraHMS(new Date());
        escribirRecordatorio("Enviado " + ticket + " - " + nombre + " a la mesa " + mesa + "    --  " + ahora);
        mostrarPanelAviso(ticket + " " + nombre + "\nMesa: " + mesa);
        puesto.ticket = ticket + " - " + nombre;
        puesto.hora = ahora;
        return true;
    }

    public void cambioNumeroMesas(String txtNumMesas) {
        int nuevoNumero = Integer.parseInt(txtNumMesas);
        if (numeroMesas < nuevoNumero) {
            while (numeroMesas < nuevoNumero) {
                int nmesa = ++numeroMesas;
                nuevaMesa("" + nmesa);
            }
        }
    }
    
    boolean primeraVez = true;

    void panelMesasResized() {
        try {
            int anchoPanel = jScrollPane3.getWidth();
            if (anchoPanel < 200 && primeraVez) {
                jSplitPane1.setDividerLocation(220);
                primeraVez = false;
            }
            int numColumnas = anchoPanel / 65;
            int numFilas = (numeroMesas + 2) / numColumnas;
            int altoPanel = numFilas * 65;
            int anchoScrollBar = this.jScrollPane3.getVerticalScrollBar().getWidth();
            if (altoPanel < panelPrincipal.getHeight()) {
                altoPanel = panelPrincipal.getHeight() - 20;
            }
            panelMesas.setPreferredSize(new Dimension(jScrollPane3.getWidth() + anchoScrollBar, altoPanel));
            panelMesas.invalidate();
        } catch (Exception exc) {
        }
    }

    void nuevaMesa(String n) {
        Puesto puesto = new Puesto();
        puesto.denominacion = n;
        //int num = panelMesas.getComponentCount() + 1;
        BotonMesa botonMesa = new BotonMesa();
        puesto.boton = botonMesa;
        botonMesa.puesto = puesto;
        botonMesa.setText("Mesa " + n);
        botonMesa.setMargin(new java.awt.Insets(2, 2, 2, 2));
        java.awt.Dimension dimension = new java.awt.Dimension(anchoBotonMesa, anchoBotonMesa);
        botonMesa.setMaximumSize(dimension);
        botonMesa.setMinimumSize(dimension);
        botonMesa.setPreferredSize(dimension);
        botonMesa.setFocusPainted(false);
        botonMesa.setBorderPainted(false);
        botonMesa.setIconTextGap(1);
        botonMesa.setIcon(iconos[0]);
        if (n.length() < 3) {
            botonMesa.setFont(botonMesa.getFont().deriveFont(Font.PLAIN));
        } else {
            float fontSize = botonMesa.getFont().getSize();
            botonMesa.setFont(botonMesa.getFont().deriveFont(Font.PLAIN).deriveFont(fontSize - 1));
        }
        botonMesa.setForeground(Color.BLUE);
        botonMesa.setHorizontalTextPosition(SwingConstants.CENTER);
        botonMesa.setVerticalTextPosition(SwingConstants.BOTTOM);
        botonMesa.addMouseListener(mesaMouseListener);
        panelMesas.add(botonMesa);
        puesto.estado = 0;
        puestos.put(puesto.denominacion, puesto);
    }

    void ponDatosMesa(int numMesa) {
        JButton mesa = (JButton) panelMesas.getComponent(numMesa);
        mesa.putClientProperty("numeroMesa", String.valueOf(numMesa + 1));
        mesa.putClientProperty("estado", 0);
    }

    void pulsadoBotonSiguiente() {
        Comunicaciones.comm.enviar(Comunicaciones.ENVIO_MANUAL_SIGUIENTE, Global.main.numeroGestor);
    }

    public void mostrarPanelAviso(final String texto) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                avisoVisible.setText(texto);
                ((java.awt.CardLayout) panelApilado.getLayout()).show(panelApilado, "cardAviso");
                timerCierraAviso.start();
            }
        });
    }

    private void mesaMouseClicked(java.awt.event.MouseEvent evt) {
        BotonMesa mesa = (BotonMesa) evt.getSource();
        if (evt.getClickCount() < 2) {
            String numeroMesa = mesa.puesto.denominacion;
            int estado = mesa.puesto.estado;
            if (estado != LIBRE) {
                return;
            }
            if (grid.getRowCount() > 0 && grid.getSelectedRowCount() > 0) {
                int id = tmPresentes.getIdFila(grid.getSelectedRow());
                Global.main.comunicaciones.enviar(Comunicaciones.ENVIO_MANUAL_A_MESA, id + "", numeroMesa);
            }
        }
    }

    void cerrandoVentanaPrincipal() {
        int r = JOptionPane.showConfirmDialog(this, "¿ Realmente quiere cerrar la aplicación ?",
                "ATENCIÓN", JOptionPane.YES_NO_OPTION);
        if (r == 0) {
            Global.main.cerrarAplicacion();
            System.exit(0);
        }
    }

    public void eliminaFormNuevoCandidato() {
        if (fichaNuevoCandidato != null) {
            fichaNuevoCandidato.dispose();
            fichaNuevoCandidato = null;
        }
    }

    public void abreFormNuevoCandidato(RegistroCandidatos reg) {
        if (!Global.main.colas.completa()) {
            solicitadaAperturaNuevo = true;
            return;
        }
        if (fichaNuevoCandidato == null) {
            fichaNuevoCandidato = new FormNuevoCandidato();
        }
        fichaNuevoCandidato.setSize(630, 560);
        fichaNuevoCandidato.setLocationRelativeTo(this);
        fichaNuevoCandidato.rellenar(reg);
        fichaNuevoCandidato.setVisible(true);
        if ((fichaNuevoCandidato.getExtendedState() & JFrame.ICONIFIED) != 0) {
            fichaNuevoCandidato.setExtendedState(JFrame.NORMAL);
        }
    }

    public void cambiarEstadoCola(String codCola, boolean cerrada, boolean colaespecial) {
        if (fichaNuevoCandidato != null) {
            fichaNuevoCandidato.cambiarEstadoCola(codCola, cerrada, colaespecial);
        }
    }

    void abrirVentanaCandidatos() {
        TablaCandidatos candidatos = TablaCandidatos.getTablaCandidatos();
        if (!candidatos.cargada) {
            solicitadaAperturaRelacion = true;
            return;
        }
        if (formCandidatos == null) {
            preparaFormCandidatos();
        }
        formCandidatos.setVisible(true);
        if ((formCandidatos.getExtendedState() & JFrame.ICONIFIED) != 0) {
            formCandidatos.setExtendedState(JFrame.NORMAL);
        }
    }

    public void escribirRecordatorio(String txt) {
        areaMensajes.append(txt + "\n");
        limpiaVisorMensajes();
    }

    void limpiaVisorMensajes() {
        final int maxLinea = 1000;
        if (areaMensajes.getLineCount() > maxLinea) {
            try {
                int p = areaMensajes.getLineStartOffset(0);
                int n = areaMensajes.getLineEndOffset(0);
                areaMensajes.replaceRange("", p, n);
            } catch (Exception exc) {
                System.out.println(exc.getMessage());
            }
        }
    }

    void hacerVisible() {
        if (!this.isFocused()) {
            setState(JFrame.ICONIFIED);
            setState(JFrame.NORMAL);
        }
        if (getState() == JFrame.ICONIFIED) {
            setState(JFrame.NORMAL);
        }
        toFront();
    }

    public void mensajeDelAdministrador(String mensaje) {
        hacerVisible();
        java.awt.Toolkit.getDefaultToolkit().beep();
        String[] params = Global.split(mensaje, '|');
        String origen = params[0];
        String texto = params[1].replace('#', '\n');
        JOptionPane.showMessageDialog(null, texto, "MENSAJE DEL ADMINISTRADOR", JOptionPane.PLAIN_MESSAGE);
        Comunicaciones.comm.confirmarLecturaMensaje(origen);
    }

    String averiguaNombreOperador(String numMesa) {
        JButton mesa = (JButton) panelMesas.getComponent(Integer.parseInt(numMesa) - 1);
        Object o = mesa.getClientProperty("nombre");
        if (o != null) {
            return (String) o;
        }
        return "???";
    }

    public void mensajeDelOperador(String mensaje) {
        hacerVisible();
        java.awt.Toolkit.getDefaultToolkit().beep();
        String[] params = Global.split(mensaje, '|');
        String origen = params[0];
        String texto = params[2].replace('#', '\n');
        String nombre = "Operador";
        if (puestos.containsKey(origen)) {
            nombre = puestos.get(origen).operador;
        }
        texto = "-- Mensaje de " + nombre + " --\n" + texto;
        JOptionPane.showMessageDialog(null, texto, "MENSAJE DE LA MESA " + origen, JOptionPane.PLAIN_MESSAGE);
        Comunicaciones.comm.confirmarLecturaMensaje(origen);
    }

    void enviarMensajeAlAdministrador() {
        DlgMensaje dlg = new DlgMensaje(this);
        dlg.setTitle("Mensaje al Administrador");
        dlg.setSize(415, 200);
        dlg.setLocationRelativeTo(this);
        dlg.setVisible(true);
        if (dlg.enviar) {
            Comunicaciones.comm.enviar(Comunicaciones.MENSAJE_A_ADMINISTRADOR,
                    "gestor" + Global.main.numeroGestor, conf.codigoGestor, dlg.mensaje);
        }
        dlg.dispose();
    }

    void enviarMensajeAOperadores() {
        DlgMensaje dlg = new DlgMensaje(this);
        dlg.setTitle("Mensaje a TODOS los operadores");
        dlg.setSize(415, 200);
        dlg.setLocationRelativeTo(this);
        dlg.setVisible(true);
        if (dlg.enviar) {
            Comunicaciones.comm.enviar(Comunicaciones.MENSAJE_A_OPERADORES,
                    "gestor" + Global.main.numeroGestor, conf.codigoGestor, dlg.mensaje);
        }
        dlg.dispose();
    }

    void pedirDatosNif() {
        String nif = JOptionPane.showInputDialog("Introduzca NIF del que se solicitarán datos al servidor");
        if (nif == null) {
            return;
        }
        nif = nif.trim().toUpperCase();
        if (nif.length() > 8) {
            Comunicaciones.comm.enviar(Comunicaciones.SOLICITO_DATOS_TICKET, nif);
        } else {
            msgBox("El NIF debe tener 9 caracteres");
        }
    }

    void mostrarDatosTicket(String datos) {
        if (datos.equals("TIQUE NO ENCONTRADO")) {
            msgBox("El NIF/tique solicitado no está registrado en el servidor");
            return;
        }
        String[] sregs = datos.split("##");
        RegistroCandidatosServidor[] regs = new RegistroCandidatosServidor[sregs.length];
        for (int i = 0; i < sregs.length; i++) {
            regs[i] = new RegistroCandidatosServidor(sregs[i]);
        }
        MostrarFichaInformacion(regs);
    }

    void MostrarFichaInformacion(RegistroCandidatosServidor[] regs) {
        FormInformacionTiket formInformacionT = new FormInformacionTiket();
        formInformacionT.setSize(507, 330);
        formInformacionT.setLocationRelativeTo(this);
        formInformacionT.copiardatos(regs);
        formInformacionT.Rellenardatos(0);
        formInformacionT.setVisible(true);
    }

    public void pedirImpresionListado() {
        if (this.formCandidatos == null) {
            imprimirListado();
            return;
        }
        int res = FormSeleccionTipoListado.ejecutar(this);
        if (res == 0) {
            return;
        }
        if (res == 1) {
            imprimirListado();
        } else {
            int columna;
            int orden = TablaCandidatos.ORDEN_HORACITA;
            boolean ascendente = true;
            if (formCandidatos != null) {
                columna = formCandidatos.columnaOrdenacion();
                switch (columna) {
                    case 0:
                        orden = TablaCandidatos.ORDEN_NOMBRE;
                        break;
                    case 1:
                        orden = TablaCandidatos.ORDEN_NIF;
                        break;
                    case 3:
                        orden = TablaCandidatos.ORDEN_VINCULADA;
                        break;
                    case 4:
                        orden = TablaCandidatos.ORDEN_TICKET;
                        break;
                    case 7:
                        orden = TablaCandidatos.ORDEN_HORACALCULADA;
                        break;
                    default:
                        break;
                }
                ascendente = formCandidatos.ordenAscendente();
            }
            gestor.utiles.ImpresionListadoCita listado = new gestor.utiles.ImpresionListadoCita(true);
            listado.imprimir(orden, ascendente);
        }
    }

    public void imprimirListado() {
        gestor.utiles.ImpresionListadoCita listado = new gestor.utiles.ImpresionListadoCita(false);
        listado.imprimir();
    }

    public void msgBox(String txt) {
        JOptionPane.showMessageDialog(this, txt);
    }

    public void avisoDesconexion() {
        FormDesconexion fdx = new FormDesconexion(this);
        fdx.setSize(420, 300);
        fdx.setLocationRelativeTo(null);
        fdx.setVisible(true);
    }

    public void marcarImprimirTicket(boolean poner) {
        conf.imprimirTicket = poner;
        if (fichaNuevoCandidato != null) {
            fichaNuevoCandidato.ponMarcarImprimir(poner);
        }
        if (formCandidatos != null) {
            formCandidatos.ponMarcarImprimir(poner);
        }
    }

    void cambiarOrden(int columna, int modificadores) {
        grid.guardaPosicion();
        if ((modificadores & java.awt.event.InputEvent.CTRL_DOWN_MASK) == java.awt.event.InputEvent.CTRL_DOWN_MASK) {
            grid.quitarOrden();
        } else {
            grid.ordenar(columna, true);
        }
        grid.recuperarPosicion();
        grid.repaint();
    }

    public void quitarOrdenGrid() {
        grid.quitarOrden();
    }


    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        popupMenuMesas = new javax.swing.JPopupMenu();
        menuitemMensajeMesa = new javax.swing.JMenuItem();
        jPanel1 = new javax.swing.JPanel();
        jPanel2 = new javax.swing.JPanel();
        cbxModoAutomatico = new javax.swing.JCheckBox();
        btSiguiente = new javax.swing.JButton();
        botonNuevoCandidato = new javax.swing.JButton();
        btMarcarPresentes = new javax.swing.JButton();
        status = new javax.swing.JLabel();
        panelPrincipal = new javax.swing.JPanel();
        jSplitPane1 = new javax.swing.JSplitPane();
        jScrollPane3 = new javax.swing.JScrollPane();
        panelMesas = new javax.swing.JPanel();
        panelDerecho = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        grid = new javax.swing.grid.JGrid();
        panelApilado = new javax.swing.JPanel();
        jScrollPane2 = new javax.swing.JScrollPane();
        areaMensajes = new javax.swing.JTextArea();
        avisoVisible = new javax.swing.JTextArea();
        jMenuBar2 = new javax.swing.JMenuBar();
        menuArchivo = new javax.swing.JMenu();
        menuMensajeAdministrador = new javax.swing.JMenuItem();
        menuMensajeTodosOperedores = new javax.swing.JMenuItem();
        menuPedirDatosNif = new javax.swing.JMenuItem();
        menuImprimirListado = new javax.swing.JMenuItem();
        jSeparator1 = new javax.swing.JSeparator();
        menuSalir1 = new javax.swing.JMenuItem();

        menuitemMensajeMesa.setText("Mensaje al Operador");
        menuitemMensajeMesa.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                menuitemMensajeMesaActionPerformed(evt);
            }
        });
        popupMenuMesas.add(menuitemMensajeMesa);

        setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
        setTitle("Gestor ATENEO ");
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                formWindowClosing(evt);
            }
        });

        jPanel1.setDoubleBuffered(false);
        jPanel1.setLayout(new java.awt.BorderLayout());

        jPanel2.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        jPanel2.setDoubleBuffered(false);

        cbxModoAutomatico.setText("Modo automático");
        cbxModoAutomatico.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                cbxModoAutomaticoStateChanged(evt);
            }
        });
        cbxModoAutomatico.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cbxModoAutomaticoActionPerformed(evt);
            }
        });
        jPanel2.add(cbxModoAutomatico);

        btSiguiente.setText("Siguiente");
        btSiguiente.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btSiguienteActionPerformed(evt);
            }
        });
        jPanel2.add(btSiguiente);

        botonNuevoCandidato.setText("Nuevo");
        botonNuevoCandidato.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                botonNuevoCandidatoActionPerformed(evt);
            }
        });
        jPanel2.add(botonNuevoCandidato);

        btMarcarPresentes.setText("Relación");
        btMarcarPresentes.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btMarcarPresentesActionPerformed(evt);
            }
        });
        jPanel2.add(btMarcarPresentes);

        status.setText("  ");
        jPanel2.add(status);

        jPanel1.add(jPanel2, java.awt.BorderLayout.NORTH);

        panelPrincipal.setDoubleBuffered(false);
        panelPrincipal.setLayout(new java.awt.BorderLayout());

        jScrollPane3.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        jScrollPane3.addComponentListener(new java.awt.event.ComponentAdapter() {
            public void componentResized(java.awt.event.ComponentEvent evt) {
                jScrollPane3ComponentResized(evt);
            }
        });

        panelMesas.setBackground(new java.awt.Color(255, 255, 255));
        panelMesas.setAutoscrolls(true);
        panelMesas.setDoubleBuffered(false);
        panelMesas.setMinimumSize(new java.awt.Dimension(200, 300));
        panelMesas.setOpaque(false);
        panelMesas.setPreferredSize(new java.awt.Dimension(200, 300));
        panelMesas.setLayout(new java.awt.FlowLayout(0));
        jScrollPane3.setViewportView(panelMesas);

        jSplitPane1.setLeftComponent(jScrollPane3);

        panelDerecho.setDoubleBuffered(false);
        panelDerecho.setLayout(null);

        jScrollPane1.setPreferredSize(new java.awt.Dimension(454, 500));

        grid.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null}
            },
            new String [] {
                "Title 1", "Title 2", "Title 3", "Title 4"
            }
        ));
        grid.setCabeceraPulsable(true);
        grid.setDoubleBuffered(true);
        grid.addCabeceraPulsadaListener(new javax.swing.grid.CabeceraPulsadaListener() {
            public void cabeceraPulsada(javax.swing.grid.CeldaPulsadaEvent evt) {
                gridCabeceraPulsada(evt);
            }
        });
        jScrollPane1.setViewportView(grid);

        panelDerecho.add(jScrollPane1);
        jScrollPane1.setBounds(0, 0, 270, 126);

        panelApilado.setLayout(new java.awt.CardLayout());

        areaMensajes.setEditable(false);
        areaMensajes.setRows(20);
        areaMensajes.setAutoscrolls(false);
        jScrollPane2.setViewportView(areaMensajes);

        panelApilado.add(jScrollPane2, "cardScroll");

        avisoVisible.setBackground(new java.awt.Color(255, 255, 204));
        avisoVisible.setRows(5);
        avisoVisible.setCaretColor(new java.awt.Color(255, 255, 204));
        panelApilado.add(avisoVisible, "cardAviso");

        panelDerecho.add(panelApilado);
        panelApilado.setBounds(0, 127, 280, 100);

        jSplitPane1.setRightComponent(panelDerecho);

        panelPrincipal.add(jSplitPane1, java.awt.BorderLayout.CENTER);

        jPanel1.add(panelPrincipal, java.awt.BorderLayout.CENTER);

        getContentPane().add(jPanel1, java.awt.BorderLayout.CENTER);

        menuArchivo.setText("Acciones");

        menuMensajeAdministrador.setText("Enviar mensaje al Administrador");
        menuMensajeAdministrador.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                menuMensajeAdministradorActionPerformed(evt);
            }
        });
        menuArchivo.add(menuMensajeAdministrador);

        menuMensajeTodosOperedores.setText("Enviar mensaje a TODOS los operadores");
        menuMensajeTodosOperedores.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                menuMensajeTodosOperedoresActionPerformed(evt);
            }
        });
        menuArchivo.add(menuMensajeTodosOperedores);

        menuPedirDatosNif.setText("Solicitar datos de visitas anteriores");
        menuPedirDatosNif.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                menuPedirDatosNifActionPerformed(evt);
            }
        });
        menuArchivo.add(menuPedirDatosNif);

        menuImprimirListado.setText("Imprimir listado de Cita Previa");
        menuImprimirListado.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                menuImprimirListadoActionPerformed(evt);
            }
        });
        menuArchivo.add(menuImprimirListado);
        menuArchivo.add(jSeparator1);

        menuSalir1.setText("Salir");
        menuSalir1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                menuSalir1ActionPerformed(evt);
            }
        });
        menuArchivo.add(menuSalir1);

        jMenuBar2.add(menuArchivo);

        setJMenuBar(jMenuBar2);

        pack();
    }// </editor-fold>//GEN-END:initComponents
    private void gridCabeceraPulsada(javax.swing.grid.CeldaPulsadaEvent evt) {//GEN-FIRST:event_gridCabeceraPulsada
        cambiarOrden(evt.getColumna(), evt.getModificadores());
    }//GEN-LAST:event_gridCabeceraPulsada

    private void menuImprimirListadoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuImprimirListadoActionPerformed
        pedirImpresionListado();
    }//GEN-LAST:event_menuImprimirListadoActionPerformed

    private void menuPedirDatosNifActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuPedirDatosNifActionPerformed
        pedirDatosNif();
    }//GEN-LAST:event_menuPedirDatosNifActionPerformed

    private void menuMensajeTodosOperedoresActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuMensajeTodosOperedoresActionPerformed
        enviarMensajeAOperadores();
    }//GEN-LAST:event_menuMensajeTodosOperedoresActionPerformed

   private void menuitemMensajeMesaActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuitemMensajeMesaActionPerformed
       mensajeAMesa();
   }//GEN-LAST:event_menuitemMensajeMesaActionPerformed

   private void menuMensajeAdministradorActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuMensajeAdministradorActionPerformed
       enviarMensajeAlAdministrador();
   }//GEN-LAST:event_menuMensajeAdministradorActionPerformed

   private void jScrollPane3ComponentResized(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_jScrollPane3ComponentResized
       panelMesasResized();
   }//GEN-LAST:event_jScrollPane3ComponentResized

   private void botonNuevoCandidatoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_botonNuevoCandidatoActionPerformed
       abreFormNuevoCandidato(null);
   }//GEN-LAST:event_botonNuevoCandidatoActionPerformed

   private void menuSalir1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuSalir1ActionPerformed
       cerrandoVentanaPrincipal();
   }//GEN-LAST:event_menuSalir1ActionPerformed

   private void btSiguienteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btSiguienteActionPerformed
       pulsadoBotonSiguiente();
   }//GEN-LAST:event_btSiguienteActionPerformed

   private void cbxModoAutomaticoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbxModoAutomaticoActionPerformed
       solicitarModoAutomatico();
   }//GEN-LAST:event_cbxModoAutomaticoActionPerformed

   private void btMarcarPresentesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btMarcarPresentesActionPerformed
       abrirVentanaCandidatos();
   }//GEN-LAST:event_btMarcarPresentesActionPerformed

   private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing
       cerrandoVentanaPrincipal();
   }//GEN-LAST:event_formWindowClosing

   private void cbxModoAutomaticoStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_cbxModoAutomaticoStateChanged
       if (panelMesas.getComponentCount() > 0) {
           JButton botonMesa1 = (JButton) panelMesas.getComponent(0);
           botonMesa1.requestFocus();
       }
   }//GEN-LAST:event_cbxModoAutomaticoStateChanged
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JTextArea areaMensajes;
    private javax.swing.JTextArea avisoVisible;
    private javax.swing.JButton botonNuevoCandidato;
    private javax.swing.JButton btMarcarPresentes;
    private javax.swing.JButton btSiguiente;
    private javax.swing.JCheckBox cbxModoAutomatico;
    private javax.swing.grid.JGrid grid;
    private javax.swing.JMenuBar jMenuBar2;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JScrollPane jScrollPane3;
    private javax.swing.JSeparator jSeparator1;
    private javax.swing.JSplitPane jSplitPane1;
    private javax.swing.JMenu menuArchivo;
    private javax.swing.JMenuItem menuImprimirListado;
    private javax.swing.JMenuItem menuMensajeAdministrador;
    private javax.swing.JMenuItem menuMensajeTodosOperedores;
    private javax.swing.JMenuItem menuPedirDatosNif;
    private javax.swing.JMenuItem menuSalir1;
    private javax.swing.JMenuItem menuitemMensajeMesa;
    private javax.swing.JPanel panelApilado;
    private javax.swing.JPanel panelDerecho;
    private javax.swing.JPanel panelMesas;
    private javax.swing.JPanel panelPrincipal;
    private javax.swing.JPopupMenu popupMenuMesas;
    private javax.swing.JLabel status;
    // End of variables declaration//GEN-END:variables
 public class Puesto {

        public String denominacion = "";
        public int estado = 0;
        public String operador = null;
        public JButton boton;
        public String ticket = null;
        public String hora = null;

        public void ponerEstado(int nuevoEstado) {
            estado = nuevoEstado;
            boton.setIcon(iconos[estado]);
        }

        public void borrarTique() {
            ticket = null;
            hora = null;
        }

        public void borrarTodo() {
            operador = null;
            borrarTique();
        }
    }

    protected class BotonMesa extends JButton {

        public Puesto puesto;
    }

}
