/* 
* 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 servidor.utiles;

import java.util.*;
import java.awt.*;
import java.awt.font.*;
import java.awt.geom.*;
import java.awt.print.*;
import javax.print.*;
import servidor.datos.*;
import servidor.datos.base.*;

public class ImpresionListadoCita {

    PrinterJob pj;
    PrintService prt;
    ArrayList<RegistroCandidatos> candidatos = new ArrayList<RegistroCandidatos>();
    int numCandidatos;
    Font fntNormal;
    Font fntNegrita;
    String cabecera;
    static final float puntosMm = 72.0f / 25.4f;

    public ImpresionListadoCita() {
        fntNormal = new Font("Courier new", Font.PLAIN, 10);
        fntNegrita = new Font("Courier new", Font.BOLD, 10);
        Date ahora = new Date();
        cabecera = "LISTADO DE CITA PREVIA DEL DIA " + Fecha.formatoFechaCorta(ahora)
                + "    obtenido a las " + Fecha.formatoHoraHM(ahora) + "          pag.";
        pj = PrinterJob.getPrinterJob();
        pj.printDialog();
        PageFormat format = pj.defaultPage();
        Paper papel = format.getPaper();
        papel.setImageableArea(pmm(10), pmm(10), papel.getWidth() - pmm(20), papel.getHeight() - pmm(25));
        format.setPaper(papel);
        pj.setPrintable(new pagina(), format);
        cargarTabla();
    }

    @SuppressWarnings("unchecked")
    void cargarTabla() {
        TablaCandidatos cand = servidor.comunicaciones.GestorColas.getGestor().tablaCandidatos;
        candidatos = (ArrayList<RegistroCandidatos>) (cand.registros().clone());
        Comparador comparador = new Comparador();
        Collections.sort(candidatos, comparador);
        numCandidatos = candidatos.size();
    }

    public void imprimir() {
        try {
            pj.print();
        } catch (Exception exc) {
            System.err.println(" ** ERROR al imprimir listado de candidatos **");
        }
    }

    float pmm(double mm) {
        return (float) (mm * puntosMm);
    }

    float pmm(float mm) {
        return mm * puntosMm;
    }

    float pmm(int mm) {
        return (float) mm * puntosMm;
    }

    class pagina implements Printable {

        float posY = 0f;
        Graphics2D g2;
        Rectangle2D r2d;
        FontRenderContext frc;
        int numRegistro = 0;
        boolean terminado = false;
        int primerRegistroPagina = 0;
        int cursor = 0;
        boolean segundoPaso = false;
        boolean columnasCalculadas = false;
        float[] columnas = new float[9];
        float d = 3;
        float d2 = d * 2;
        Line2D linea = new Line2D.Float();
        BasicStroke lapiz = new BasicStroke(0.2f);

        @Override
        public int print(Graphics g, PageFormat pf, int indicePag) {
            if (segundoPaso) {
                cursor = primerRegistroPagina;
            } else {
                if (terminado) {
                    return Printable.NO_SUCH_PAGE;
                }
                primerRegistroPagina = cursor;
            }
            g2 = (Graphics2D) g;
            g2.translate((int) pf.getImageableX(), (int) pf.getImageableY());
            g2.setStroke(lapiz);
            if (!columnasCalculadas) {
                calculaColumnas();
            }
            posY = 0f;
            imprimeCabecera(indicePag + 1);
            ponFuente(fntNormal);
            g2.setColor(Color.black);
            while (true) {
                if (cursor == numCandidatos) {
                    terminado = true;
                    segundoPaso = !segundoPaso;
                    return Printable.PAGE_EXISTS;
                }
                RegistroCandidatos reg = candidatos.get(cursor);
                cursor++;
                imprimeColumna(reg.getNif(), 0);
                imprimeColumna(reg.getNombre(), 1);
                imprimeColumna(Fecha.formatoHoraHM(reg.getHoraCita()), 2);
                imprimeColumna(Fecha.formatoHoraHM(reg.getHoraCalculada()), 3);
                imprimeColumna(reg.getNumeroTicket(), 4);
                imprimeColumna(reg.getCola(), 5);
                imprimeColumna(reg.getMesa(), 6);
                imprimeColumna(reg.getEstado(), 7);
                if (posY + (float) r2d.getHeight() > pf.getImageableHeight()) {
                    break;
                }
            }
            segundoPaso = !segundoPaso;
            return Printable.PAGE_EXISTS;
        }

        void dibujaLinea(float x1, float y1, float x2, float y2) {
            linea.setLine(x1, y1, x2, y2);
            g2.draw(linea);
        }

        void imprimeCabecera(int indicePag) {
            ponFuente(fntNegrita);
            imprimeLinea(cabecera + (indicePag));
            posY += 2f;
            dibujaLinea(columnas[0], posY + 2, columnas[8], posY + 2);
            imprimeColumna("NIF", 0);
            imprimeColumna("NOMBRE", 1);
            imprimeColumna("H.CITA", 2);
            imprimeColumna("H.CALC", 3);
            imprimeColumna("TIQUE", 4);
            imprimeColumna("COLA", 5);
            imprimeColumna("MESA", 6);
            imprimeColumna("EST.", 7);
        }

        void ponFuente(Font fuente) {
            g2.setFont(fuente);
            frc = g2.getFontRenderContext();
        }

        void imprimeLinea(String txt) {
            posY += (int) r2d.getHeight();
            g2.drawString(txt, 0f, posY);
        }

        float posY1, posY2;

        void imprimeColumna(String txt, int col) {
            if (col == 0) {
                posY1 = posY + 2;
                posY += (float) r2d.getHeight();
                posY2 = posY + 2;
                dibujaLinea(columnas[0], posY2, columnas[8], posY2); // linea horizontal inferior
                dibujaLinea(columnas[0], posY1, columnas[0], posY2); // linea vertical izquierda
            }
            g2.drawString(txt, columnas[col] + d, posY);
            dibujaLinea(columnas[col + 1], posY1, columnas[col + 1], posY2);
        }

        void calculaColumnas() {
            ponFuente(fntNormal);
            r2d = g2.getFont().getStringBounds("M", frc);
            int m = (int) r2d.getWidth();
            columnas[0] = 1;
            columnas[1] = columnas[0] + (m * 9) + d2;
            columnas[2] = columnas[1] + (m * 40) + d2;
            columnas[3] = columnas[2] + (m * 6) + d2;
            columnas[4] = columnas[3] + (m * 6) + d2;
            columnas[5] = columnas[4] + (m * 6) + d2;
            columnas[6] = columnas[5] + (m * 4) + d2;
            columnas[7] = columnas[6] + (m * 4) + d2;
            columnas[8] = columnas[7] + (m * 4) + d2;
            columnasCalculadas = true;
        }
    }

    class Comparador implements Comparator<RegistroCandidatos> {

        @Override
        public int compare(RegistroCandidatos r1, RegistroCandidatos r2) {
            java.sql.Timestamp t1 = r1.getHoraCita();
            java.sql.Timestamp t2 = r2.getHoraCita();
            if (t1 == null) {
                t1 = Fecha.TimestampNulo;
            }
            if (t2 == null) {
                t2 = Fecha.TimestampNulo;
            }
            int v = t1.compareTo(t2);
            if (v == 0) {
                t1 = r1.getHoraPresente();
                t2 = r2.getHoraPresente();
                if (t1 == null) {
                    t1 = Fecha.TimestampNulo;
                }
                if (t2 == null) {
                    t2 = Fecha.TimestampNulo;
                }
                return t1.compareTo(t2);
            }
            return v;
        }
    }

}
