/*
 * Copyright
 *   2007 axYus - www.axyus.com
 *   2005 C.Marchand - christophe.marchand@axyus.com
 *
 * This file is part of XEMELIOS.
 *
 * XEMELIOS is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * XEMELIOS 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 Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with XEMELIOS; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package fr.gouv.finances.cp.utils.ui;

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Iterator;
import java.util.TreeSet;
import java.util.Vector;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRootPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.Timer;

import com.jgoodies.forms.builder.PanelBuilder;
import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;

import fr.gouv.finances.cp.utils.Pair;

/**
 * @author chm
 */
public class DlgGetPair extends JDialog {
    /**
     * Comment for <code>serialVersionUID</code>
     */
    private static final long serialVersionUID = 5506053470241303864L;
//    private static Logger logger = Logger.getLogger(DlgGetPair.class);
    private static final String TITLE = "Informations";
    static {
        System.out.println(System.getProperty("os.name"));
        if(System.getProperty("os.name").toLowerCase().indexOf("win")>=0)
            setDefaultLookAndFeelDecorated(true);
    }
    private JButton pbOk, pbCancel;
    private boolean ret;
    private Action escapeAction;
    private String question;
    private JTextField dfCode, dfLibelle;
    private JComboBox cbxData;
    private TreeSet<Pair> defaultValues;
    private Timer timer = null;
    
    public DlgGetPair(JFrame owner, String question) {
        this(owner,question,TITLE);
    }
    public DlgGetPair(JFrame owner, String question,String title) {
        super(owner,title,true);
        this.question = question;
        initialize();
    }
    public DlgGetPair(JFrame owner, String question,TreeSet<Pair> values) {
        this(owner,question,values,TITLE);
    }
    public DlgGetPair(JFrame owner, String question,TreeSet<Pair> values,String title) {
        super(owner,title,true);
        this.question = question;
        this.defaultValues=values;
        initialize();
    }
    public DlgGetPair(JFrame owner, String question,TreeSet<Pair> values,String title,Pair initialValue) {
        this(owner,question,values,title);
        if(initialValue!=null) {
            if(initialValue.key!=null && initialValue.key.trim().length()>0) {
                dfCode.setText(initialValue.key);
                if(cbxData!=null) cbxData.setEnabled(false);
                dfCode.setEnabled(false);
                dfLibelle.grabFocus();
                dfLibelle.setText(initialValue.libelle);
                // try to find an existing lib to this code
                if(values!=null) {
                    Pair p = null;
                    for(Iterator<Pair> it=values.iterator();it.hasNext();) {
                        Pair p1 = it.next();
                        if(p1.equals(initialValue)) p = p1;
                    }
                    if(p!=null) dfLibelle.setText(p.libelle);
                }
            } else {
                dfLibelle.setText(initialValue.libelle);
            }
        }
    }
    public void initialize() {
        int sepInfo = 2;
        int lineInfo = sepInfo + 2;
        int sepData = lineInfo + 2;
        int existingData = sepData + (defaultValues!=null ? 2 : 0);
        int codeLine = existingData + 2;
        
        int libelleLine = codeLine + 2;
        int buttonLine = libelleLine + 2;
        
        JTextArea area = null;
        cbxData = null;
        
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        
        FormLayout fl = new FormLayout(
                //        1     2     3    4    5    6
                /*						"1dlu,20dlu,pref,1dlu,pref,1dlu", */
                "3dlu,20dlu,pref,3dlu,pref,3dlu",
                "7dlu,"+                                   // 1
                "pref,"+                                   // 2		separateur INFO
                "3dlu,"+                                   // 3
                "pref,"+                                   // 4		message (question)
                "7dlu,"+                                   // 5
                "pref,"+                                   // 6		separateur DATA
                (defaultValues!=null?"3dlu,pref,":"")+	   //		les deux lignes pour les valeurs existantes
                "3dlu,"+                                   // 7
                "pref,"+                                   // 8		codeLine
                "1dlu,"+                                   // 9
                "pref,"+                                   // 10	libelleLine
                "10dlu,"+                                  // 11
                "pref,"+                                   // 12	buttonLine
                "3dlu");                                   // 13
        CellConstraints cc = new CellConstraints();
        PanelBuilder pb = new PanelBuilder(fl);
        IhmFactory iF=IhmFactory.newInstance();
        
        pb.addSeparator("Informations",					cc.xyw(2,sepInfo,4));
        pb.add(area = new JTextArea(), 					cc.xyw(3,lineInfo,3));
        
        pb.addSeparator("Données",						cc.xyw(2,sepData,4));
        if(defaultValues!=null) {
            pb.add(iF.newLabel("Valeurs possibles","normal"),	cc.xy(3,existingData));
            Vector<Pair> data = new Vector<Pair>();
            data.add(new Pair("",""));
            data.addAll(defaultValues);
            pb.add(cbxData = new JComboBox(data),		cc.xy(5,existingData));
            cbxData.addItemListener(new ItemListener() {
                public void itemStateChanged(ItemEvent e) {
                    if(e.getStateChange()==ItemEvent.SELECTED) {
                        JComboBox cbxData = (JComboBox)e.getSource();
                        Pair p = (Pair)cbxData.getSelectedItem();
                        dfCode.setText(p.key);
                        dfLibelle.setText(p.libelle);
                    }
                    resetTimer();
                }
            });
        }
        pb.add(iF.newLabel("Code","normal"),			cc.xy(3,codeLine));
        pb.add(dfCode = new JTextField(),				cc.xy(5,codeLine));
        pb.add(iF.newLabel("Libellé","normal"),			cc.xy(3,libelleLine));
        pb.add(dfLibelle = new JTextField(),				cc.xy(5,libelleLine));
        
        JPanel bPane = new JPanel(new FlowLayout(FlowLayout.CENTER));
        pbCancel = new JButton(escapeAction);
        pbOk = new JButton("Ok");
        bPane.add(pbOk); bPane.add(pbCancel);
        
        pb.add(bPane,									cc.xyw(2,buttonLine,4));
        
        dfCode.setColumns(15);
        add(pb.getPanel());
        
        area.setEditable(false);
        area.setLineWrap(true);
        area.setRows(3);
        area.setBackground(getBackground());
        area.setText(question);
        
        if(defaultValues!=null && defaultValues.size()>0) {
            cbxData.setSelectedIndex(1);
        }
        
        // timer stop !
        dfCode.addKeyListener(new KeyListener() {
            public void keyTyped(KeyEvent e) { resetTimer(); }
            public void keyPressed(KeyEvent e) { resetTimer(); }
            public void keyReleased(KeyEvent e) { resetTimer(); }
        });
        dfLibelle.addKeyListener(new KeyListener() {
            public void keyTyped(KeyEvent e) { resetTimer(); }
            public void keyPressed(KeyEvent e) { resetTimer(); }
            public void keyReleased(KeyEvent e) { resetTimer();     resetTimer();
            }
        });
        dfCode.addFocusListener(new FocusListener() {
            public void focusGained(FocusEvent e) { /*resetTimer();*/ }
            public void focusLost(FocusEvent e) { resetTimer(); }
        });
        dfLibelle.addFocusListener(new FocusListener() {
            public void focusGained(FocusEvent e) { resetTimer(); }
            public void focusLost(FocusEvent e) { resetTimer(); }
        });
        pbOk.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                checkReponse();
            }
        });
        getRootPane().setDefaultButton(pbOk);
        pack();
        setLocationRelativeTo(getParent());
    }
    @Override
    protected JRootPane createRootPane() {
        KeyStroke ks = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE,0);
        JRootPane rp = new JRootPane();
        escapeAction = new AbstractAction("Annuler") {
            /**
             * Comment for <code>serialVersionUID</code>
             */
            private static final long serialVersionUID = 1L;
            
            public void actionPerformed(ActionEvent evt) {
                ret = false;
                setVisible(false);
            }
        };
        rp.registerKeyboardAction(escapeAction,"TOTOTOTO",ks,JComponent.WHEN_IN_FOCUSED_WINDOW);
        return rp;
    }
    protected void checkReponse() {
        if(dfCode.getText()!=null && dfCode.getText().length()>0 && dfLibelle.getText()!=null && dfLibelle.getText().length()>0) {
            setVisible(false);
            ret = true;
        } else {
            JOptionPane.showMessageDialog(this,"Le code ainsi que le libelle sont obligatoires","Erreur de saisie",JOptionPane.WARNING_MESSAGE);
            ret = false;
        }
    }
    public String getCode() {
        return dfCode.getText();
    }
    public String getLibelle() {
        return dfLibelle.getText();
    }
    public boolean run() {
        if(dfCode.getText()!=null && dfCode.getText().length()>0) {
            // mise en place d'un compteur pour auto-cliquer
            int delay=1000;
            ActionListener taskPerformer = new ActionListener() {
                private int sec = 30;
                public void actionPerformed(ActionEvent evt) {
                    if(sec==0) {
                        if(evt.getSource() instanceof Timer) {
                            //Timer timer = (Timer)evt.getSource();
                            timer.stop();
                            timer=null;
                        }
                        pbOk.doClick();
                    } else {
                        String msg = "Ok ("+(sec--)+" sec.)";
                        pbOk.setText(msg);
                    }
                }
            };
            timer = new Timer(delay,taskPerformer);
            timer.start();
        }
        setVisible(true);
        toFront();
        return ret;
    }
    
    @Override
    public void setVisible(boolean b) {
        dfCode.grabFocus();
        super.setVisible(b);
    }
    private void resetTimer() {
        if(timer!=null) {
            timer.stop();
            timer=null;
        }
        pbOk.setText("Ok");
    }
//    public JTextField getDfCode() {
//        return dfCode;
//    }
//    public void setDfCode(String dfCode) {
//        this.dfCode.setText(dfCode);
//    }
//    public JTextField getDfLibelle() {
//        return dfLibelle;
//    }
//    public void setDfLibelle(
//            String dfLibelle) {
//        this.dfLibelle.setText(dfLibelle);
//    }
//    public void setComboEnable(boolean b){
//        this.cbxData.setEnabled(b);
//    }
}
