/* ParameterPanel.java
 * =========================================================================
 * This file is part of the GrInvIn project - http://www.grinvin.org
 * 
 * Copyright (C) 2005-2008 Universiteit Gent
 * 
 * This program 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 2 of the License, or (at
 * your option) any later version.
 * 
 * This program 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.
 * 
 * A copy of the GNU General Public License can be found in the file
 * LICENSE.txt provided with the source distribution of this program (see
 * the META-INF directory in the source jar). This license can also be
 * found on the GNU website at http://www.gnu.org/licenses/gpl.html.
 * 
 * If you did not receive a copy of the GNU General Public License along
 * with this program, contact the lead developer, or write to the Free
 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 */

package org.grinvin.params;

import be.ugent.caagt.swirl.dialogs.DialogPanel;

import java.awt.Component;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JToolTip;
import javax.swing.UIManager;

import org.grinvin.gui.MultilineToolTip;

/**
 * Panel that can be used to edit parameter values.
 * Uses a {@link ParameterList} to specify what parameters should be present.
 */
public class ParameterPanel extends DialogPanel {
    
    //
    private ParameterEditor[] editors;
    
    //
    private ParameterComponent[] components;
    
    //
    private JTextArea explanation;
    
    //
    private static final Insets LEFT_INSETS = new Insets(3, 0, 3, 11);
    
    //
    private static final Insets RIGHT_INSETS = new Insets(3, 0, 3, 0);
    
    /**
     * Construct a new panel of this type.
     * @param parameters list of parameters
     * whose values can be edited in this panel.
     */
    public ParameterPanel(ParameterList parameters) {
        super(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.anchor = GridBagConstraints.WEST;
        
        int len = parameters.getCount();
        editors = new ParameterEditor[len];
        components = new ParameterComponent[len];
        for (int i=0; i < len; i++) {
            gbc.gridy = i;
            ParameterInfo info = parameters.getParameter(i);
            JLabel label = new JLabel(info.getCaption()) {
                public JToolTip createToolTip() {
                    return new MultilineToolTip(150);
                    //TODO: don't hardcode width
                }
            };
            label.setToolTipText(info.getDescription());
            gbc.gridx = 0;
            gbc.weightx = 0.0;
            gbc.insets = LEFT_INSETS;
            add(label, gbc);
            editors[i] = info.getEditor();
            components[i] = editors[i].getEditorComponent();
            components[i].addFocusListener(new ParameterComponentFocusListener(info.getDescription()));
            gbc.gridx = 1;
            gbc.weightx = 1.0;
            gbc.insets = RIGHT_INSETS;
            add((Component)components[i], gbc);
        }
        gbc.gridy = len;
        gbc.gridx = 0;
        gbc.gridwidth = 2;
        gbc.weightx = 1.0;
        gbc.fill = GridBagConstraints.BOTH;
        explanation = new JTextArea(3,20);
        explanation.setLineWrap(true);
        explanation.setWrapStyleWord(true);
        explanation.setEditable(false);
        explanation.setOpaque(true);
        explanation.setBackground(UIManager.getColor("ToolTip.background"));
        explanation.setFocusable (false); // avoid tabbing into this
        add(new JScrollPane(explanation), gbc);
    }
    
    /**
     * Initialize the fields of the panel from the given array of values.
     */
    public void setValues(Object[] values) {
        for (int i=0; i < components.length; i++)
            components[i].setParameterValue(values[i]);
    }
    
    /**
     * Initialize the given array from the values stored in the various fields of
     * the panel.
     */
    public void getValues(Object[] values) {
        for (int i=0; i < components.length; i++)
            values[i] = components[i].getParameterValue();
    }
    
    private class ParameterComponentFocusListener implements FocusListener {
        
        private String infoText;
        
        public ParameterComponentFocusListener(String infoText) {
            super();
            this.infoText = infoText;
        }
 
        public void focusGained(FocusEvent e) {
            explanation.setText(infoText);
            explanation.setCaretPosition(0);
        }

        public void focusLost(FocusEvent e) {
            explanation.setText(null);
        }
    }
}
