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

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

/**
 *
 * @author admf11600q4
 */
public final class ImpresionListadoCita {

    PrinterJob pj;
    PrintService prt;
    TablaCandidatos candidatos;
    Font fntNormal;
    Font fntNegrita;
    String cabecera;
    static final float puntosMm = 72.0f / 25.4f;
    boolean filtrado = false;

    /**
     * Creates a new instance of ImpresionListadoCita
     */
    public ImpresionListadoCita(boolean filtrado) {
        candidatos = TablaCandidatos.getTablaCandidatos().clonar(filtrado);
        this.filtrado = filtrado;
        if (candidatos.recordsCount() == 0) {
            return;
        }
        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.formatoHoraDMA(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);
    }

    void ordenaListado(int orden, boolean asc) {
        Comparator<RegistroCandidatos> comparador = candidatos.obtenerComparador(orden, asc);
        candidatos.ordena(comparador);
    }

    public void imprimir() {
        imprimir(TablaCandidatos.ORDEN_HORACITA, true);
    }

    public void imprimir(int orden, boolean asc) {
        try {
            if (candidatos.recordsCount() == 0) {
                Global.principal.msgBox("No hay datos que listar");
                return;
            }
            ordenaListado(orden, asc);
            pj.print();
        } catch (Exception exc) {
            exc.printStackTrace();
        }
    }

    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 registroActual = 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) {
                registroActual = primerRegistroPagina;
            } else {
                if (terminado) {
                    return Printable.NO_SUCH_PAGE;
                }
                primerRegistroPagina = registroActual;
            }
            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) {
                RegistroCandidatos reg = candidatos.getRegistroNum(registroActual);
                if (reg == null) {
                    terminado = true;
                    segundoPaso = !segundoPaso;
                    return Printable.PAGE_EXISTS;
                }
                imprimeColumna(reg.nif, 0);
                imprimeColumna(reg.nombre, 1);
                imprimeColumna(Fecha.formatoHoraHM(reg.horaCita), 2);
                imprimeColumna(Fecha.formatoHoraHM(reg.horaCalculada), 3);
                imprimeColumna(reg.numeroTicket, 4);
                imprimeColumna(reg.cola, 5);
                imprimeColumna(reg.mesa, 6);
                imprimeColumna(reg.estado, 7);
                registroActual++;
                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 * 15) + d2;
            columnas[2] = columnas[1] + (m * 35) + 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;
        }
    }

}
