/*
Copyright 2005-2013 Samuel Gesche

This file is part of ArcEnCiel.

ArcEnCiel is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

ArcEnCiel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with ArcEnCiel.  If not, see <http://www.gnu.org/licenses/>.
*/

package ihm;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JComponent;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Graphics;

import java.awt.image.BufferedImage;

/**
 *
 * @author Samuel Gesche
 * @version 3.0
 * @since 3.0.1
 */
public class Legende extends JPanel {
    private final Color[] colors = { // 26 en tout
                                   new Color(0, 0, 255, 192), // 1.bleu
                                   new Color(255, 0, 0, 192), // 2.rouge
                                   new Color(0, 255, 0, 192), // 3.vert
                                   new Color(255, 255, 0, 192), // 4.jaune
                                   new Color(128, 0, 255, 192), // 5.violet
                                   new Color(0, 0, 0, 192), // 6.noir
                                   new Color(0, 255, 255, 192), // 7.cyan
                                   new Color(255, 128, 0, 192), // 8.orange
                                   new Color(255, 0, 255, 192), // 9.magenta
                                   new Color(255, 128, 128, 192), // 10.rose
                                   new Color(255, 255, 255, 192), // 11.blanc
                                   new Color(0, 0, 128, 192), // 12.bleu foncé
                                   new Color(255, 255, 128, 192), // 13.jaune pâle
                                   new Color(128, 255, 255, 192), // 14.bleu pâle
                                   new Color(0, 128, 0, 192), // 15.vert foncé
                                   new Color(128, 0, 0, 192), // 16.rouge foncé
                                   new Color(255, 128, 255, 192), // 17.violet pâle
                                   new Color(128, 128, 128, 192), // 18.gris
                                   new Color(128, 128, 0, 192), // 19.ocre
                                   new Color(128, 0, 128, 192), // 20.violet foncé
                                   new Color(0, 255, 128, 192), // 21.vert-bleu
                                   new Color(128, 255, 0, 192), // 22.vert citron
                                   new Color(0, 128, 128, 192), // 23.turquoise
                                   new Color(255, 0, 128, 192), // 24.fushia
                                   new Color(128, 255, 128, 192), // 25.vert pâle
                                   new Color(0, 128, 255, 192) // 26.bleu mer
    };
    private String[] noms;

    /**
     * Crée une instance de Légende prévue pour différencier un certain nombre
     * de points de vue.
     * @param nbPV int le nombre de points de vue à étiqueter
     * @since 3.0.3
     */
    public Legende(int nbPV){
        noms = new String[nbPV];
        for(int i=0; i<noms.length; i++){
            noms[i] = "";
        }
        for (int i = 0; i < noms.length; i++) {
            final int j = i;
            JLabel couleur = new JLabel() {
                public Dimension getPreferredSize() {
                    return new Dimension((Charte.getFont().getSize()+1)/2*3,
                                         (Charte.getFont().getSize()+1)/2*2);
                }

                public void paint(Graphics g) {
                    g.setColor(colors[j % colors.length]);
                    g.fillRect(0, 0, getWidth(), getHeight());
                }
            };
            Charte.formate(couleur);
            JLabel nom = new JLabel(noms[i], JLabel.LEFT);
            Charte.formate(nom);
            JPanel p = new JPanel(new BorderLayout());
            Charte.formate(p);
            p.add(couleur, BorderLayout.WEST);
            p.add(nom, BorderLayout.CENTER);
            add(p);
        }
    }

    /**
     * Crée une instance de Légende prévue pour différencier un certain nombre
     * de points de vue.
     * @param noms String[] les points de vue à étiqueter
     * @since 3.0.3
     */
    public Legende(String[] noms) {
        setLayout(new GridLayout(noms.length, 1));
        this.noms = noms;
        for (int i = 0; i < noms.length; i++) {
            final int j = i;
            JLabel couleur = new JLabel() {
                public Dimension getPreferredSize() {
                    return new Dimension((Charte.getFont().getSize()+1)/2*3,
                                         (Charte.getFont().getSize()+1)/2*2);
                }

                public void paint(Graphics g) {
                    g.setColor(colors[j % colors.length]);
                    g.fillRect(0, 0, getWidth(), getHeight());
                }
            };
            Charte.formate(couleur);
            JLabel nom = new JLabel(noms[i], JLabel.LEFT);
            Charte.formate(nom);
            JPanel p = new JPanel(new BorderLayout());
            Charte.formate(p);
            p.add(couleur, BorderLayout.WEST);
            p.add(nom, BorderLayout.CENTER);
            add(p);
        }
    }

    /**
     * Renvoie un Label contenant des marques de couleur pour les points de vue
     * correspondant aux valeurs vraies du tableau spécifié.
     * @param valeurs boolean[] un tableau donnant les points de vue valides
     * @return JLabel le résultat
     * @since 3.0.1
     */
    public JLabel getClasseur(boolean[] valeurs){
        if(valeurs.length != noms.length){
            throw new IllegalArgumentException();
        }
        return new Classeur(valeurs);
    }

    /**
     * Renvoie un Component contenant la légende sous une forme textuelle.
     * @return JComponent le résultat
     * @since 4.0.3
     */
    public JComponent getLegendeTextuelle(){
        JPanel resultat = new JPanel();
        Charte.formate(resultat);
        int dX = Math.min(noms.length, colors.length/2);     // nombre de pastilles par ligne
        int dY = (int)(Math.ceil(1.0*noms.length/dX));       // nombre de lignes de pastilles
        resultat.setLayout(new GridLayout(dY, dX, 5, 5));
        for(int i=0; i<noms.length; i++){
            JLabel img = getIndicateur(i);
            Charte.formate(img);
            JLabel txt = new JLabel(noms[i]);
            Charte.formate(txt);
            JPanel p = new JPanel(new BorderLayout());
            Charte.formate(p);
            p.add(img, BorderLayout.WEST);
            p.add(txt, BorderLayout.CENTER);
            resultat.add(p);
        }
        for(int i=noms.length; i<dX*dY; i++){
            resultat.add(Charte.format(new JLabel("")));
        }
        resultat.setBorder(Charte.getBorder());
        return resultat;
    }

    /**
     * Renvoie un Label contenant une icône de la couleur du point de vue à
     * l'index spécifié.
     * @param index int l'index à colorier
     * @return JLabel le Label résultante
     * @since 3.0.1
     */
    public JLabel getIndicateur(int index){
        if(index > noms.length){
            throw new IllegalArgumentException();
        }
        return new JLabel(getIconeIndicateur(index));
    }

    /**
     * Renvoie une icône de la couleur du point de vue à l'index spécifié.
     * @param index int l'index à colorier
     * @return Icon l'icône résultante
     * @since 3.0.1
     */
    public Icon getIconeIndicateur(int index){
        BufferedImage im = new BufferedImage((Charte.getFont().getSize()+1)/2,
                                             (Charte.getFont().getSize()+1)/2*2,
                                             BufferedImage.TYPE_INT_ARGB);
        Graphics g = im.getGraphics();
        g.setColor(colors[index%colors.length]);
        g.fillRect(0,0,(Charte.getFont().getSize()+1)/2,
                   (Charte.getFont().getSize()+1)/2*2);
        return new ImageIcon(im);
    }

    private class Classeur extends JLabel {

        private boolean[] valeurs;

        public Classeur(boolean[] valeurs) {
            this.valeurs = valeurs;
        }

        public Dimension getPreferredSize() {
            int d0 = Math.max((Charte.getFont().getSize()+1)/2,8); // côté d'une pastille
            int dX = Math.min(valeurs.length, colors.length/2);     // nombre de pastilles par ligne
            int dY = (int)(Math.ceil(1.0*valeurs.length/dX));       // nombre de lignes de pastilles
            int dimX = d0 * dX + 4;
            int dimY = d0 * dY + 4;
            return new Dimension(dimX, dimY);
        }

        public void paint(Graphics g) {
            int w = getWidth();  // largeur
            int h = getHeight(); // hauteur

            int d0 = Math.max((Charte.getFont().getSize()+1)/2,8); // côté d'une pastille
            int dX = Math.min(valeurs.length, colors.length/2);     // nombre de pastilles par ligne
            int dY = (int)(Math.ceil(1.0*valeurs.length/dX));       // nombre de lignes de pastilles
            int dimX = d0 * dX;      // largeur voulue
            int dimY = d0 * dY;      // hauteur voulue
            int dx = (w-dimX)/2;     // offset largeur
            int dy = (h-dimY)/2;     // offset hauteur


            for (int i = 0; i < valeurs.length; i++) {
                if (valeurs[i]) {
                    int x = d0 * (i % dX);
                    int y = d0 * (i / dX);
                    g.setColor(colors[i % colors.length]);
                    g.fillRect(dx + x, dy + y, d0, d0);
                }
            }

            Charte.getBorder().paintBorder(this, g, dx-2, dy-2, dimX+4, dimY+4);
        }

    }
}
