/*
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 data.Confrontation;
import data.ListeSynonymes;
import data.LienEntreListes;
import ihm.townto.EventHandler;
import ihm.townto.EventListener;
import ihm.townto.MultiPVGraph;
import ihm.townto.MultiPVGraphPanel;
import ihm.townto.LinkFailureException;

import javax.swing.JPanel;
import javax.swing.JSplitPane;
import java.awt.BorderLayout;
import javax.swing.JScrollPane;
import javax.swing.JList;
import javax.swing.ListSelectionModel;
import javax.swing.ListCellRenderer;
import javax.swing.JLabel;
import java.awt.Component;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Dimension;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.util.Vector;
import javax.swing.JOptionPane;

/**
 * @author Samuel GESCHE
 * @version 3.0
 */
public class PanelConfrontation extends JPanel implements EventListener {
    private Legende legende;
    private Confrontation confrontation;
    private MultiPVGraphPanel graphe;


    public PanelConfrontation(FenetrePrincipale container,
                              Confrontation confrontation) {
        setLayout(new BorderLayout());
        Charte.formate(this);
        legende = new Legende(confrontation.getAllNomsGraphes());
        this.confrontation = confrontation;

        EventHandler.register(this);

        JSplitPane pVisuGraphe = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
        Charte.formate(pVisuGraphe);
        pVisuGraphe.setContinuousLayout(true);

        spLiens = new JScrollPane();
        Charte.formate(spLiens);
        Charte.formate(spLiens.getViewport());
        Charte.formate(spLiens.getHorizontalScrollBar());
        Charte.formate(spLiens.getVerticalScrollBar());
        pVisuGraphe.setLeftComponent(spLiens);

        MultiPVGraph g = new MultiPVGraph();
        if (confrontation.getListeCompleteNoeudsLies().length > 0) {
            g = remplissageGraphe(confrontation.getListeCompleteNoeudsLies()[0]);
        }
        if (!(g.isExhaustive()) && this.hasFocus()) {
            JOptionPane.showMessageDialog(
                    this,
                    Charte.getMessage("PanelConf_GrapheTropGros"),
                    Charte.getMessage("PanelConf_GrapheTropGrosT"),
                    JOptionPane.INFORMATION_MESSAGE,
                    Charte.getSmiley(Charte.MITIGE));
        }
        graphe = new MultiPVGraphPanel(confrontation.getNombreDeGraphes(), g, 0);

        JScrollPane spGraphe = new JScrollPane(graphe){
            public Dimension getPreferredSize() {
                // Oui parce que sinon ça prend toute la place...
                return new Dimension((int) (this.getSize().width * 0.8),
                                     this.getSize().height);
            }
        };
        Charte.formate(spGraphe);
        Charte.formate(spGraphe.getViewport());
        Charte.formate(spGraphe.getHorizontalScrollBar());
        Charte.formate(spGraphe.getVerticalScrollBar());
        pVisuGraphe.setRightComponent(spGraphe);

        pVisuGraphe.setDividerSize(5);
        pVisuGraphe.setDividerLocation(0.20);

        add(legende.getLegendeTextuelle(), BorderLayout.NORTH);
        add(pVisuGraphe, BorderLayout.CENTER);
        refaisListe();
    }

    private JList lLiens = new JList();
    private JScrollPane spLiens;

    private void refaisListe() {
        //int sel = lLiens.getSelectedIndex();
        Object value = lLiens.getSelectedValue();
        if(confrontation.getListeCompleteNoeudsLies().length>0){
            lLiens = new JList(confrontation.getListeCompleteNoeudsLies());
        } else {
            ListeSynonymes[] x = {new ListeSynonymes("", "")};
            lLiens = new JList(x);
        }
        Charte.formate(lLiens);
        lLiens.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        lLiens.setCellRenderer(new ListCellRenderer() {
            public Component getListCellRendererComponent(JList list,
                    Object value, int index, boolean isSelected,
                    boolean cellHasFocus) {
                JPanel res = new JPanel(new FlowLayout(FlowLayout.LEFT));
                ListeSynonymes l = (ListeSynonymes) value;
                for (int i = 0; i < l.getListe().length; i++) {
                    JLabel lab = legende.getClasseur(
                            l.getListe()[i].getConcernes());
                    Charte.formate(lab);
                    JLabel lab2 = new JLabel(l.getListe()[i].getTexte());
                    Charte.formate(lab2);
                    res.add(lab);
                    res.add(lab2);
                    if (i < l.getListe().length - 1) {
                        JLabel lab3 = new JLabel(";");
                        Charte.formate(lab3);
                        res.add(lab3);
                    }
                }
                JLabel res4 = new JLabel("{" + l.getLien() + "}");
                Charte.formate(res4);
                res.add(res4);
                Charte.formate(res);
                if (isSelected) {
                    res.setOpaque(true);
                    res.setBackground(new Color(0, 0, 0, 64));
                }
                return res;
            }
        });
        lLiens.addListSelectionListener(new ListSelectionListener() {
            public void valueChanged(ListSelectionEvent lse) {
                changeGraphe();
            }
        });
        spLiens.setViewportView(lLiens);
        lLiens.setSelectedValue(value, true);
        Object value2 = lLiens.getSelectedValue();
        if(value2==null){
            lLiens.setSelectedIndex(0);
        }
        //lLiens.ensureIndexIsVisible(sel);
    }

    private void changeGraphe() {
        MultiPVGraph g = new MultiPVGraph();
        g = remplissageGraphe((ListeSynonymes)
                              (lLiens.getSelectedValue()));
        if (!(g.isExhaustive()) && this.hasFocus()) {
            JOptionPane.showMessageDialog(
                    this,
                    Charte.getMessage("PanelConf_GrapheTropGros"),
                    Charte.getMessage("PanelConf_GrapheTropGrosT"),
                    JOptionPane.INFORMATION_MESSAGE,
                    Charte.getSmiley(Charte.MITIGE));
        }
        graphe.setGraph(g);
    }

    private MultiPVGraph remplissageGraphe(ListeSynonymes liste){
        MultiPVGraph resultat = new MultiPVGraph();
        resultat.setActive(liste, liste.getLien());
        boolean[] b = new boolean[confrontation.getNombreDeGraphes()];
        for(int i=0; i<liste.getListe().length; i++){
            for(int j=0; j<b.length; j++){
                b[j] = b[j] || liste.getListe()[i].getConcernes()[j];
            }
        }
        LienEntreListes[] liens = confrontation.getListesLiees(liste);
        Vector l = new Vector();
        for(int i=0; i<liens.length; i++){
                if(!(l.contains(liens[i]))){
                    l.addElement(liens[i]);
                    try {
                        resultat.addLink(liens[i].getOrigine(), "",
                                         liens[i].getDestination(), "");
                    } catch (LinkFailureException lfe) {
                        lfe.printStackTrace();
                    }
                    LienEntreListes[] liens2;
                    if (liste.equals(liens[i].getOrigine())) {
                        liens2 = confrontation.getListesLiees(liens[i].
                                getDestination());
                    } else {
                        liens2 = confrontation.getListesLiees(liens[i].
                                getOrigine());
                    }
                    Vector l2 = new Vector();
                    for (int j = 0; j < liens2.length; j++) {
                        if (!(l2.contains(liens2[j]))) {
                            l2.addElement(liens2[j]);
                            if (liens2[j].getOrigine().intersects(b) &&
                                liens2[j].getDestination().intersects(b)) {
                                try {
                                    resultat.addLink(liens2[j].getOrigine(), "",
                                            liens2[j].getDestination(), "");
                                } catch (LinkFailureException lfe) {
                                    lfe.printStackTrace();
                                }
                            }
                        }
                    }
                }
        }
        return resultat;
    }

    public void notifyEvent(int eventCode, String eventContent) {
        if (eventCode == EventHandler.NEW_SYNONYM_OR_HOMONYM) {
            refaisListe();
        }
    }
}
