/*
 * The contents of this file are subject to the terms of the Common Development
 * and Distribution License (the License). You may not use this file except in
 * compliance with the License.
 * 
 * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
 * or http://www.netbeans.org/cddl.txt.
 * 
 * When distributing Covered Code, include this CDDL Header Notice in each file
 * and include the License file at http://www.netbeans.org/cddl.txt.
 * If applicable, add the following below the CDDL Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyrighted [year] [name of copyright owner]"
 * 
 * The Original Software is NetBeans. The Initial Developer of the Original
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
 * Microsystems, Inc. All Rights Reserved.
 */
/*
 * InputPanel.java
 *
 * Created on May 14, 2004, 8:03 PM
 */

package org.netbeans.core.output2.ui;

import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import org.netbeans.core.output2.Controller;
import org.openide.util.NbBundle;

import javax.swing.*;
import javax.swing.border.Border;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import org.openide.util.Utilities;

/**
 * Panel to enable user entered input.
 *
 * @author  Tim Boudreau
 */
final class InputPanel extends JPanel implements ActionListener, FocusListener {
    public static final String ACTION_EOF = "eof"; //NOI18N
    public static final String ACTION_NEWTEXT = "text"; //NOI18N

    private JTextField field = new JTextField();
    private JButton eof =
        new JButton(NbBundle.getMessage(InputPanel.class, "LBL_EOF")); //NOI18N
    
    private ActionListener listener = null;
    private JLabel lbl = 
        new JLabel(NbBundle.getMessage(InputPanel.class, "LBL_INPUT")); //NOI18N;
    
    /** Creates a new instance of InputPanel */
    public InputPanel() {
        init();
        setFocusable(false);
    }
    
    public void requestFocus() {
        field.requestFocus();
    }
    
    public boolean requestFocusInWindow() {
        return field.requestFocusInWindow();
    }
    
    private void init() {
        setLayout (new BorderLayout());

        add (lbl, BorderLayout.WEST);
        add (field, BorderLayout.CENTER);
        field.setEditable(true);
        add (eof, BorderLayout.EAST);

        field.addActionListener(this);
        eof.addActionListener(this);

        eof.setToolTipText(NbBundle.getMessage(InputPanel.class, "TIP_EOF")); //NOI18N
        field.setToolTipText(NbBundle.getMessage(InputPanel.class, "TIP_INPUT")); //NOI18N

        field.getAccessibleContext().setAccessibleName(lbl.getText());
        eof.getAccessibleContext().setAccessibleName(eof.getText());
        field.getAccessibleContext().setAccessibleDescription(field.getToolTipText());
        eof.getAccessibleContext().setAccessibleDescription(eof.getToolTipText());
        
        // XXX use o.o.awt.Mnemonics instead, simpler...
        lbl.setDisplayedMnemonic(
            Utilities.stringToKey(
            NbBundle.getMessage(InputPanel.class, "INPUT.mnemonic")).getKeyCode()); //NOI18N
        lbl.setDisplayedMnemonicIndex(
            Integer.parseInt(
            NbBundle.getMessage(InputPanel.class, "INPUT.index"))); //NOI18N
        
        eof.setMnemonic(NbBundle.getMessage(
            InputPanel.
            class, "EOF.mnemonic").charAt(0)); //NOI18N

        Border b = field.getBorder();
        field.setBorder (BorderFactory.createCompoundBorder (
            BorderFactory.createMatteBorder(3, 3, 3, 3, getBackground()), b));
        lbl.setBorder (BorderFactory.createEmptyBorder(0,0,0,5));

        lbl.setLabelFor(field);
        
        setBorder (BorderFactory.createCompoundBorder (
                    BorderFactory.createMatteBorder(
                        1,0,0,0,UIManager.getColor("controlShadow")),                
                BorderFactory.createEmptyBorder (4,4,4,4)));
        
        field.addFocusListener(this);
    }

    public void doLayout() {
        Dimension lblp = lbl.getPreferredSize();
        Dimension eofp = eof.getPreferredSize();
        Dimension fp = field.getPreferredSize();

        Insets ins = getInsets();

        lbl.setBounds (ins.left, ins.top, lblp.width, getHeight() - (ins.top + ins.bottom));

        int ftop = (getHeight() / 2) - (fp.height / 2);

        int fright = getWidth() - (ins.right + eofp.width);
        int fleft = ins.left + lblp.width;

        field.setBounds (fleft, ftop, fright - fleft, fp.height);

        int btop = (getHeight() / 2) - (eofp.height / 2);
        eof.setBounds (fright, btop, getWidth() - (fright + ins.right), eofp.height);
    }

    public Dimension getPreferredSize() {
        Dimension lblp = lbl.getPreferredSize();
        Dimension eofp = eof.getPreferredSize();
        Dimension fp = field.getPreferredSize();

        Insets ins = getInsets();

        int h = ins.top + ins.bottom + Math.max (Math.max (lblp.height, eofp.height), fp.height);
        int w = ins.left + lblp.width + eofp.width + fp.width + ins.right;

        return new Dimension (w, h);
    }

    public Dimension getMinimumSize() {
        Dimension lblp = lbl.getMinimumSize();
        Dimension eofp = eof.getMinimumSize();
        Dimension fp = field.getMinimumSize();

        Insets ins = getInsets();

        int h = ins.top + ins.bottom + Math.max (Math.max (lblp.height, eofp.height), fp.height);
        int w = ins.left + lblp.width + eofp.width + fp.width + ins.right;

        return new Dimension (w, h);
    }


    public String getText() {
        return field.getText();
    }
    
    public void addActionListener (ActionListener listener) {
        if (this.listener != null) {
            throw new IllegalStateException (this.listener + " is already " + //NOI18N
                "listening"); //NOI18N
        }
        this.listener = listener;
    }
    
    public void removeActionListener (ActionListener listener) {
        if (listener != this.listener) {
            throw new IllegalArgumentException (listener + " is not " +  //NOI18N
                this.listener);
        }
        this.listener = null;
    }
    
    public void actionPerformed(ActionEvent ae) {
        ActionEvent e = new ActionEvent (this, ActionEvent.ACTION_PERFORMED, 
            ae.getSource() == eof ? ACTION_EOF : ACTION_NEWTEXT);
        if (Controller.log) Controller.log ("Got action event from " + ae.getSource()); //NOI18N
        if (Controller.log) Controller.log ("  Posting event to listener(tab) " + e); //NOI18N

        if (ae.getSource() == field && field.getText().length() > 0) {
            field.setSelectionStart(0);
            field.setSelectionEnd(field.getText().length());
        }

        listener.actionPerformed(e);
    }    
    
    private AbstractOutputTab findOutputTab() {
        if (getParent() != null) {
            return (AbstractOutputTab) SwingUtilities.getAncestorOfClass(AbstractOutputTab.class, this);
        } else {
            return null;
        }
    }
    
    public void focusGained (FocusEvent fe) {
        AbstractOutputTab tab = findOutputTab();
        if (tab != null) {
            tab.notifyInputFocusGained();
        }
    }
    
    public void focusLost (FocusEvent fe) {
        
    }
    
}
