/* SwingCheckboxPeer.java -- A Swing based peer for AWT checkboxes
   Copyright (C)  2007  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 gnu.java.awt.peer.swing;

import java.awt.Checkbox;
import java.awt.CheckboxGroup;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.event.FocusEvent;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.peer.CheckboxPeer;

import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JToggleButton;

/**
 * A CheckboxPeer implementation that is backed by the Swing JCheckBox.
 */
public class SwingCheckboxPeer extends SwingComponentPeer implements
        CheckboxPeer {

  /**
   * A spezialized Swing checkbox used to paint the checkbox for the
   * AWT checkbox.
   */
  private class SwingCheckbox
    extends JCheckBox
    implements SwingComponent
  {
    Checkbox checkbox;

    SwingCheckbox(Checkbox checkbox)
    {
      this.checkbox = checkbox;
    }

    /**
     * Returns this checkbox.
     *
     * @return <code>this</code>
     */
    public JComponent getJComponent()
    {
      return this;
    }

    /**
     * Handles mouse events by forwarding it to
     * <code>processMouseEvent()</code>.
     *
     * @param ev the mouse event
     */
    public void handleMouseEvent(MouseEvent ev)
    {
      ev.setSource(this);
      processMouseEvent(ev);
    }

    /**
     * Handles mouse motion events by forwarding it to
     * <code>processMouseMotionEvent()</code>.
     *
     * @param ev the mouse motion event
     */
    public void handleMouseMotionEvent(MouseEvent ev)
    {
      ev.setSource(this);
      processMouseMotionEvent(ev);
    }

    /**
     * Handles key events by forwarding it to <code>processKeyEvent()</code>.
     *
     * @param ev the mouse event
     */
    public void handleKeyEvent(KeyEvent ev)
    {
      ev.setSource(this);
      processKeyEvent(ev);
    }

    /**
     * Handles focus events by forwarding it to
     * <code>processFocusEvent()</code>.
     *
     * @param ev the Focus event
     */
    public void handleFocusEvent(FocusEvent ev)
    {
      processFocusEvent(ev);
    }

    /**
     * Overridden so that this method returns the correct value even without a
     * peer.
     *
     * @return the screen location of the button
     */
    public Point getLocationOnScreen()
    {
      return SwingCheckboxPeer.this.getLocationOnScreen();
    }

    /**
     * Overridden so that the isShowing method returns the correct value
     * for the swing button, even if it has no peer on its own.
     *
     * @return <code>true</code> if the button is currently showing,
     *         <code>false</code> otherwise
     */
    public boolean isShowing()
    {
      boolean retVal = false;
      if (checkbox != null)
        retVal = checkbox.isShowing();
      return retVal;
    }

    /**
     * Overridden, so that the Swing button can create an Image without its
     * own peer.
     *
     * @param w the width of the image
     * @param h the height of the image
     *
     * @return an image
     */
    public Image createImage(int w, int h)
    {
      return SwingCheckboxPeer.this.createImage(w, h);
    }

    public Graphics getGraphics()
    {
      return SwingCheckboxPeer.this.getGraphics();
    }

    public Container getParent()
    {
      Container par = null;
      if (checkbox != null)
        par = checkbox.getParent();
      return par;
    }

    public void requestFocus() {
      SwingCheckboxPeer.this.requestFocus(awtComponent, false, true, 0);
    }

    public boolean requestFocus(boolean temporary) {
      return SwingCheckboxPeer.this.requestFocus(awtComponent, temporary,
                                                 true, 0);
    }
  }

  /**
   * Listens for ActionEvents on the Swing button and triggers corresponding
   * ActionEvents on the AWT button.
   */
  class SwingCheckboxListener implements ItemListener
  {
    Checkbox awtCheckbox;

    SwingCheckboxListener(Checkbox checkbox)
    {
      awtCheckbox = checkbox;
    }

    /**
     * Receives notification when an action was performend on the button.
     *
     * @param event the action event
     */
    public void itemStateChanged(ItemEvent event)
    {
      awtCheckbox.setState(event.getStateChange()==ItemEvent.SELECTED);
      ItemListener[] l = awtCheckbox.getItemListeners();
      if (l.length == 0)
        return;
      ItemEvent ev = new ItemEvent(awtCheckbox, ItemEvent.ITEM_STATE_CHANGED,
                                   awtCheckbox, event.getStateChange());
      for (int i = 0; i < l.length; ++i)
        l[i].itemStateChanged(ev);
    }
  }

  /**
   * Creates a new SwingCheckboxPeer instance.
   */
  public SwingCheckboxPeer(Checkbox checkbox)
  {
    SwingCheckbox swingCheckbox = new SwingCheckbox(checkbox);
    swingCheckbox.addItemListener(new SwingCheckboxListener(checkbox));

    init(checkbox, swingCheckbox);
    setLabel(checkbox.getLabel());
    setState(checkbox.getState());
  }

  public void setCheckboxGroup(CheckboxGroup group)
  {
    // TODO: Implement this.
  }

  public void setLabel(String label)
  {
    ((JToggleButton) swingComponent).setText(label);
  }

  public void setState(boolean state)
  {
    ((JToggleButton) swingComponent).setSelected(state);
  }

}
