/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package monitor.utiles;

import java.awt.*;
import java.awt.event.*;
import java.awt.font.FontRenderContext;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.TimerTask;
import javax.swing.*;
import monitor.Configuracion;

/**
 *
 * @author fernando
 */
public class BannerGrafico extends JPanel {

    JPanel contenedor;
    private int alto = 1;
    private int ancho = 1;
    private Color colorFondo;
    private Color colorTexto = Color.red;
    private Font fuenteBanner = null;
    int vueltasInicio;
    int posInicial = 0;
    //public javax.swing.Timer timer;
    java.util.Timer timer;
    private final ArrayList<MensajeTexto> mensajes = new ArrayList<>();
    MensajeTexto mensajeActual;
    private int posMensajeActual = 0;
    monitor.Configuracion conf;
    
    class MensajeTexto {

        public String texto;
        public Image bmp;
        public int anchoImagen;
        public boolean paraBorrar = false;
    }

    public BannerGrafico(JPanel contenedor) {
        this.contenedor = contenedor;
        conf = Configuracion.instanciaUnica();
        colorFondo = conf.colorFondoBanner;
        colorTexto = conf.colorTextoBanner;
        
        this.addComponentListener(new ComponentListener() {

            @Override
            public void componentResized(ComponentEvent e) {
                onResized();
            }

            @Override
            public void componentMoved(ComponentEvent e) {
            }

            @Override
            public void componentShown(ComponentEvent e) {
            }

            @Override
            public void componentHidden(ComponentEvent e) {
            }
        });

        timer = new java.util.Timer();
        //timer = new javax.swing.Timer(40, new java.awt.event.ActionListener() {        
    }

    public void setColor(Color fondo, Color tinta) {
        colorFondo = fondo;
        colorTexto = tinta;
    }

    public void addText(String texto) {
        MensajeTexto mt = new MensajeTexto();
        mt.texto = texto;
        generarBmp(mt);
        mensajes.add(mt);
    }

    public void removeText(String texto) {
        for (int i = 0; i < mensajes.size(); i++) {
            MensajeTexto mt = mensajes.get(i);
            if (mt.texto.equals(texto)) {
                if (posMensajeActual == i) {
                    mt.paraBorrar = true;
                } else {
                    mensajes.remove(mt);
                }
            }
        }
    }
    
    public int numeroMensajes() {
        int numero = 0;
        for (MensajeTexto m : mensajes) {
            if(!m.paraBorrar) numero++;
        }
        return  numero;
    }

    public void removeAll() {
        mensajes.clear();
    }
    
    public void regenerarBitmaps() {
        for (MensajeTexto mt : mensajes) {
            generarBmp(mt);
        }
    }

    public void onResized() {
        alto = getHeight();
        if (getWidth() != ancho && getHeight() > 0) {
            regenerarBitmaps();  // no va a darse un resize del componente en ejecucion
            calcularFuente();
            ancho = getWidth();
        }
    }

    public void start() {
        if (!mensajes.isEmpty()) {
            posMensajeActual = 0;
            mensajeActual = mensajes.get(posMensajeActual);
            posInicial = 0;
            vueltasInicio = 0;
            timer = new java.util.Timer();
            TimerTask tt = new TimerTask() {
                @Override
                public void run() {
                    repaint();
                    //vueltasInicio++;
                    //if (vueltasInicio >= 50) {
                        posInicial -= 4;
                        if (posInicial <= -mensajeActual.anchoImagen) {
                            posInicial = getWidth();
                            cambiarMensaje();
                        }
                    //}
                }
            };
            timer.schedule(tt, 2000, 40);
        }
    }

    public void stop() {
        timer.cancel();
    }

    private void cambiarMensaje() {        
        try {
            if (mensajeActual.paraBorrar) {
                mensajes.remove(mensajeActual);
            } else {
                posMensajeActual++;
            }
            if(mensajes.size() > 0) {
                if (posMensajeActual >= mensajes.size()) {
                    posMensajeActual = 0;
                }
                mensajeActual = mensajes.get(posMensajeActual);
            }
        } catch(Exception exc) {}
    }

    private void calcularFuente() {
        Graphics2D gr = (Graphics2D) this.getGraphics();
        FontRenderContext frc = gr.getFontRenderContext();
        float prop = conf.proporcionFuenteBanner;
        float altoDeseado = alto * prop;
        String nombreFuente = conf.fuenteBanner;
        float fontSize = altoDeseado;
        while(true) {
            fuenteBanner = new Font(nombreFuente, conf.estiloFuenteBanner, (int) fontSize);
            FontMetrics fm = gr.getFontMetrics(fuenteBanner);
            if(fm.getHeight() <= altoDeseado) {
                break;
            }
            fontSize--;
        }       
    }

    void generarBmp(MensajeTexto mt) {
        if (alto > 0) {
            try {
                Graphics2D gr = (Graphics2D) this.getGraphics();
                if(fuenteBanner == null) {
                    calcularFuente();
                }
                gr.setFont(fuenteBanner);
                FontMetrics fm = gr.getFontMetrics();
                mt.anchoImagen = fm.stringWidth(mt.texto);
                if (alto <= 0) {
                    return;
                }
                mt.bmp = new BufferedImage(mt.anchoImagen, alto, BufferedImage.TYPE_INT_RGB);
                Graphics2D g2 = (Graphics2D) mt.bmp.getGraphics();
                g2.setBackground(colorFondo);
                g2.clearRect(0, 0, mt.anchoImagen, alto);
                RenderingHints rhints = new RenderingHints(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
                rhints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                rhints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
                g2.addRenderingHints(rhints);
                g2.setFont(fuenteBanner);
                g2.setColor(colorTexto);
                g2.drawString(mt.texto, 0, fm.getHeight() + (alto - fm.getHeight())/2 - 1)  ;
            } catch (Exception exc) {
                String s = exc.getMessage();
                exc.printStackTrace();
            }
        }
    }

    @Override
    public void paint(Graphics gr) {
        if (getHeight() > 0) {
            alto = getHeight();
            ancho = getWidth();
            gr.setColor(colorFondo);
            gr.fillRect(0, 0, ancho, alto);
            if (!mensajes.isEmpty() && mensajeActual != null) {
                if (mensajeActual.bmp == null) {
                    generarBmp(mensajeActual);
                }
                if (mensajeActual.bmp != null) {
                    gr.drawImage(mensajeActual.bmp, this.posInicial, 0, null);
                }
            }
        }
    }
}
