/* MetalComboBoxUI.java
   Copyright (C) 2005 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath 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, or (at your option)
any later version.

GNU Classpath 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 GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package javax.swing.plaf.metal;

import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.LayoutManager;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import javax.swing.CellRendererPane;
import javax.swing.ComboBoxEditor;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicComboBoxUI;
import javax.swing.plaf.basic.BasicComboPopup;
import javax.swing.plaf.basic.ComboPopup;


/**
 * A UI delegate for the {@link JComboBox} component.
 */
public class MetalComboBoxUI extends BasicComboBoxUI
{
  /**
   * A layout manager that arranges the editor component (if active) and the
   * button that make up the combo box.
   */
  public class MetalComboBoxLayoutManager
    extends BasicComboBoxUI.ComboBoxLayoutManager
  {
    /**
     * Creates a new instance of the layout manager.
     */
    public MetalComboBoxLayoutManager()
    {
      // Nothing to do here.
    }
    
    /**
     * Arranges the editor (if visible) and button that comprise the combo
     * box.
     * 
     * @param parent  the parent.
     */
    public void layoutContainer(Container parent)
    {
      layoutComboBox(parent, this);
    }
    
    /**
     * Calls the <code>layoutContainer(Container)</code> method in the super 
     * class.
     * 
     * @param parent  the container.
     */
    public void superLayout(Container parent)
    {
      super.layoutContainer(parent);
    }
  }
  
  /**
   * A listener used to handle property changes in the {@link JComboBox} 
   * component, to ensure that the UI delegate accurately reflects the current
   * state in the rendering onscreen.
   */
  public class MetalPropertyChangeListener
    extends BasicComboBoxUI.PropertyChangeHandler
  {
    /**
     * Creates a new listener.
     */
    public MetalPropertyChangeListener()
    {
      // Nothing to do here.
    }
    
    /**
     * Handles a property change event, updating the UI components as
     * appropriate.
     * 
     * @param e  the event.
     */
    public void propertyChange(PropertyChangeEvent e)
    {
      super.propertyChange(e);
      String name = e.getPropertyName();
      if (name.equals("editable"))
        editablePropertyChanged(e);
      else if (name.equals("enabled"))
        {
          if (arrowButton instanceof MetalComboBoxButton)
            {
              arrowButton.setFocusable(!comboBox.isEditable()
                                       && comboBox.isEnabled());
              comboBox.repaint();
            }
        }
      else if (name.equals("background"))
        {
          Color c = (Color) e.getNewValue();
          arrowButton.setBackground(c);
          listBox.setBackground(c);
        }
      else if (name.equals("foreground"))
        {
          Color c = (Color) e.getNewValue();
          arrowButton.setForeground(c);
          listBox.setForeground(c);
        }
    }
  }

  /**
   * A popup menu for the combo-box.
   * 
   * @see #createPopup()
   *
   * @deprecated 1.4
   */
  public class MetalComboPopup extends BasicComboPopup
  {
    /**
     * Creates a new popup.
     * 
     * @param cBox  the combo box.
     */
    public MetalComboPopup(JComboBox cBox)
    {
      super(cBox); 
    }
    
    public void delegateFocus(MouseEvent e)
    {
      super.delegateFocus(e);
    }
  }
  
  /**
   * Constructs a new instance of MetalComboBoxUI.
   */
  public MetalComboBoxUI()
  {
    super();
  }

  /**
   * Returns an instance of MetalComboBoxUI.
   *
   * @param component the component for which we return an UI instance
   *
   * @return an instance of MetalComboBoxUI
   */
  public static ComponentUI createUI(JComponent component)
  {
    return new MetalComboBoxUI();
  }
  
  /**
   * Creates an editor for the combo box.
   * 
   * @return An editor.
   */
  protected ComboBoxEditor createEditor()
  {
    return new MetalComboBoxEditor.UIResource();   
  }
  
  /**
   * Creates a popup for the combo box.
   * 
   * @return A popup.
   */
  protected ComboPopup createPopup()
  {
    return new MetalComboPopup(comboBox);
  }
  
  /**
   * Creates a new button for use in rendering the JComboBox.
   * 
   * @return A button.
   */
  protected JButton createArrowButton()
  {
    JButton button = new MetalComboBoxButton(comboBox, new MetalComboBoxIcon(), 
            new CellRendererPane(), listBox);  
    button.setMargin(new Insets(0, 1, 1, 3));
    return button;
  }
  
  /**
   * Creates a new property change listener.
   * 
   * @return A new property change listener.
   */
  public PropertyChangeListener createPropertyChangeListener()
  {
    return new MetalPropertyChangeListener();
  }
  
  public void paint(Graphics g, JComponent c)
  {
    // do nothing, the button and text field are painted elsewhere
  }
  
  /**
   * Updates the button and text field to reflect a change in the 'editable'
   * property.
   * 
   * @param e  the event.
   * 
   * @deprecated 1.4
   */
  protected void editablePropertyChanged(PropertyChangeEvent e)
  {
    if (arrowButton instanceof MetalComboBoxButton)
      {
        MetalComboBoxButton b = (MetalComboBoxButton) arrowButton;
        b.setIconOnly(comboBox.isEditable());
        b.setFocusable(!comboBox.isEditable() && comboBox.isEnabled());
        comboBox.repaint();
      }
  }
  
  /**
   * Creates a new layout manager for the UI delegate.
   * 
   * @return A new layout manager.
   */
  protected LayoutManager createLayoutManager()
  {
    return new MetalComboBoxLayoutManager();
  }
  
  /**
   * Not used in Classpath.
   * 
   * @deprecated 1.4
   */
  protected void removeListeners()
  {
    // no longer used in JDK 1.4 
  }
  
  /**
   * Returns the minimum size for the combo.
   * 
   * @param c  the component
   * 
   * @return The minimum size for the combo box.
   */
  public Dimension getMinimumSize(JComponent c)
  {
    if (!isMinimumSizeDirty)
      return new Dimension(cachedMinimumSize);

    Dimension d;
    if (!comboBox.isEditable() && arrowButton != null
        && arrowButton instanceof MetalComboBoxButton)
      {
        MetalComboBoxButton b = (MetalComboBoxButton) arrowButton;
        d = getDisplaySize();
        Insets insets = b.getInsets();
        Insets arrowInsets = b.getInsets();
        Insets comboInsets = comboBox.getInsets();
        Icon icon = b.getComboIcon();
        d.width += comboInsets.left + comboInsets.right;
        d.width += arrowInsets.left + arrowInsets.right;
        d.width += arrowInsets.right + icon.getIconWidth();
        d.height += comboInsets.top + comboInsets.bottom;
        d.height += arrowInsets.top + arrowInsets.bottom;
      }
    else if (comboBox.isEditable() && arrowButton != null && editor != null)
      {
        d = super.getMinimumSize(c);
        Insets arrowMargin = arrowButton.getMargin();
        d.height += arrowMargin.top + arrowMargin.bottom;
        d.width += arrowMargin.left + arrowMargin.right;
      }
    else
      {
        d = super.getMinimumSize(c);
      }
    cachedMinimumSize.setSize(d.width, d.height);
    isMinimumSizeDirty = false;
    return new Dimension(cachedMinimumSize);
  }
  
  /**
   * Configures the editor for this combo box.
   */
  public void configureEditor()
  {
    super.configureEditor();
    if (popupKeyListener != null)
      editor.removeKeyListener(popupKeyListener);
    if (focusListener != null)
      editor.addFocusListener(focusListener);
  }

  /**
   * Unconfigures the editor for this combo box.
   */
  public void unconfigureEditor()
  {
    super.unconfigureEditor();
    if (focusListener != null)
      editor.removeFocusListener(focusListener);
  }
  
  /** 
   * Lays out the ComboBox
   */
  public void layoutComboBox(Container parent,
                             MetalComboBoxUI.MetalComboBoxLayoutManager manager)
  {
    if (comboBox.isEditable())
      manager.superLayout(parent);
    else if (arrowButton != null)
      {
        Insets comboInsets = comboBox.getInsets();
        int width = comboBox.getWidth();
        int height = comboBox.getHeight();
        arrowButton.setBounds(comboInsets.left, comboInsets.top,
                              width - (comboInsets.left + comboInsets.right),
                              height - (comboInsets.top + comboInsets.bottom));
      }
  }
}
