/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package adt.evente.gui.outils;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.Method;
import javax.swing.*;

/**
 * Panel de présentation d'une comboBox des objets de type T à sélectionner 
 * génère le PropertyChangeEvent 'Selected' à chaque fois que la sélection est modifiée.
 * @author ADT
 */
public class MaComboBox<T> extends JPanel {

    private T objectSelected;
    private T[] model;
    private boolean representeNonSelection = false;
    private JComboBox maCombo;
    private String methodName;

    public MaComboBox() {
        setLayout(new BorderLayout());
        maCombo = new JComboBox();
        maCombo.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                gereSelection();
            }
        });
        this.add(maCombo);
    }

    /**
     * constructeur
     * @param model modèle à présenter, tableau d'objets de type T
     * @param representeNonSelection vrai si la combo doit présenter une ligne correspondant à 'aucune sélection'
     * @param methodName méthode de T fournissant la valeur à présenter pour chacun des objets 
     */
    public MaComboBox(T[] model, boolean representeNonSelection, String methodName) {
        this();
        this.representeNonSelection = representeNonSelection;
        this.methodName = methodName;
        setModel(model);
    }

    private void gereSelection() {
        T oldValue = objectSelected;
        int selIndex = maCombo.getSelectedIndex();
        if (selIndex == -1) {
            objectSelected = null;
        } else {
            if (representeNonSelection) {
                selIndex = selIndex - 1;
            }
            if (selIndex == -1) {
                objectSelected = null;
            } else {
                objectSelected = model[selIndex];
            }
        }
        firePropertyChange("SelChanged", oldValue, objectSelected);
    }

    public void setModel(T[] mesT) {
        if (methodName==null) methodName="toString";
        maCombo.removeAllItems();
        this.model = mesT;
        if (representeNonSelection) {
            maCombo.addItem("---------------");
        }
        Method m = null;
        for (T t : model) {
            try {
                if (m == null) {
                    m = t.getClass().getMethod(methodName);
                }
                maCombo.addItem(m.invoke(t));
            } catch (Exception ex) {
                //sans objet
                ex.printStackTrace();
            }
        }
    }

    protected void setSelectionByObject(T sel) {
        int i = 0;
        while (i < model.length && !model[i].equals(sel)) {
            i++;
        }
        setSelectionView(i);
    }

    protected void setSelectionById(Object objId) {
        int i = 0;
        boolean trouve = false;
        Method m = null;
        while (i < model.length && !trouve) {
            try {
                if (m == null) {
                    m = model[0].getClass().getMethod("getId");
                }
                if (m.invoke(model[i]).equals(objId)) {
                    trouve = true;
                } else {
                    i++;
                }
            } catch (Exception ex) {
            //sans objet
                ex.printStackTrace();
            }
        }
        setSelectionView(i);
    }

    private void setSelectionView(int i) {
        if (i < 0 || i >= model.length) {
            if (representeNonSelection) {
                maCombo.setSelectedIndex(0);
            } else {
                maCombo.setSelectedItem(null);
            }
        } else {
            if (representeNonSelection) {
                maCombo.setSelectedIndex(i + 1);
            } else {
                maCombo.setSelectedIndex(i);
            }
        }
    }

    protected T getObjectSelected() {
        return objectSelected;
    }

    @Override
    public void setEnabled(boolean b) {
        super.setEnabled(b);
        maCombo.setEnabled(b);
    }
}
