/* BasicDesktopIconUI.java --
   Copyright (C) 2004, 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.basic;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyVetoException;

import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDesktopPane;
import javax.swing.JInternalFrame;
import javax.swing.JInternalFrame.JDesktopIcon;
import javax.swing.SwingConstants;
import javax.swing.border.Border;
import javax.swing.event.MouseInputAdapter;
import javax.swing.event.MouseInputListener;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.DesktopIconUI;

/**
 * This class acts as the UI delegate for JDesktopIcons for the Basic look and feel.
 */
public class BasicDesktopIconUI extends DesktopIconUI
{
  /**
   * This helper class handles mouse events that occur on the JDesktopIcon.
   */
  public class MouseInputHandler extends MouseInputAdapter
  {
    /** The x offset from the MouseEvent coordinates to the top left corner. */
    private transient int xOffset;

    /** The y offset fromt he MouseEvent coordinates to the top left corner. */
    private transient int yOffset;

    /** A cached value of the JDesktopPane that parents this JDesktopIcon. */
    private transient JDesktopPane pane;

    /**
     * This method is called when the mouse is dragged in the JDesktopIcon.
     *
     * @param e The MouseEvent.
     */
    public void mouseDragged(MouseEvent e)
    {
      Rectangle b = desktopIcon.getBounds();

      moveAndRepaint(desktopIcon, b.x + e.getX() - xOffset,
                     b.y + e.getY() - yOffset, b.width, b.height);
    }

    /**
     * This method is called when the mouse is moved in the JDesktopIcon.
     *
     * @param e The MouseEvent.
     */
    public void mouseMoved(MouseEvent e)
    {
      // Nothing to do.
    }

    /**
     * This method is called when the mouse is pressed in the JDesktopIcon.
     *
     * @param e The MouseEvent.
     */
    public void mousePressed(MouseEvent e)
    {
      xOffset = e.getX();
      yOffset = e.getY();
      pane = frame.getDesktopPane();
      if (pane != null)
	pane.getDesktopManager().beginDraggingFrame(desktopIcon);
    }

    /**
     * This method is called when the mouse is released in the JDesktopIcon.
     *
     * @param e The MouseEvent.
     */
    public void mouseReleased(MouseEvent e)
    {
      if (pane != null)
	pane.getDesktopManager().endDraggingFrame(desktopIcon);
      xOffset = 0;
      yOffset = 0;
    }

    /**
     * This method moves and repaints the JDesktopIcon to the given bounds.
     *
     * @param f The JComponent to move and repaint.
     * @param newX The new x coordinate.
     * @param newY The new y coordinate.
     * @param newWidth The new width.
     * @param newHeight The new height.
     */
    public void moveAndRepaint(JComponent f, int newX, int newY, int newWidth,
                               int newHeight)
    {
      if (pane != null)
	pane.getDesktopManager().dragFrame(f, newX, newY);
      else
	desktopIcon.setBounds(newX, newY, newWidth, newHeight);
    }
  }

  /**
   * This class acts as the border for the JDesktopIcon.
   */
  private class DesktopIconBorder implements Border
  {
    /** The left inset value. */
    int left = 10;

    /** The top inset value. */
    int top = 4;

    /** The right inset value. */
    int right = top;

    /** The bottom inset value. */
    int bottom = top;

    /**
     * This method returns the insets of the border.
     *
     * @param c The Component to find border insets for.
     *
     * @return The border insets.
     */
    public Insets getBorderInsets(Component c)
    {
      return new Insets(top, left, bottom, right);
    }

    /**
     * This method returns whether the border is opaque.
     *
     * @return Whether the border is opaque.
     */
    public boolean isBorderOpaque()
    {
      return true;
    }

    /**
     * This method paints the border.
     *
     * @param c The Component the border is in.
     * @param g The Graphics object to paint with.
     * @param x The x coordinate of the Component.
     * @param y The y coordinate of the Component.
     * @param width The width of the Component.
     * @param height The height of the Component.
     */
    public void paintBorder(Component c, Graphics g, int x, int y, int width,
                            int height)
    {
      g.translate(x, y);
      Color saved = g.getColor();

      g.setColor(Color.LIGHT_GRAY);

      g.fillRect(0, 0, left, height);
      g.fillRect(0, 0, width, top);
      g.fillRect(0, height - bottom, width, bottom);
      g.fillRect(width - right, 0, right, height);

      g.setColor(Color.BLACK);
      g.drawRect(0, 0, width - 1, height - 1);

      int fHeight = height / 4;
      int hLeft = left / 2;

      g.setColor(Color.BLACK);
      g.fillRect(hLeft, fHeight, 2, 2);
      g.fillRect(hLeft, fHeight * 2, 2, 2);
      g.fillRect(hLeft, fHeight * 3, 2, 2);

      g.setColor(saved);
      g.translate(-x, -y);
    }
  }

  /** The static width and height of the iconSize. */
  private static final int iconSize = 16;

  /**
   * This class represents the default frame icon when none
   * is supplied by the JInternalFrame.
   */
  static class InternalFrameDefaultMenuIcon implements Icon
  {
    /**
     * This returns the icon height.
     *
     * @return The icon height.
     */
    public int getIconHeight()
    {
      return iconSize;
    }

    /**
     * This returns the icon width.
     *
     * @return The icon width.
     */
    public int getIconWidth()
    {
      return iconSize;
    }

    /**
     * This method paints the icon.
     *
     * @param c The Component this icon belongs to.
     * @param g The Graphics object to paint with.
     * @param x The x coordinate to paint at.
     * @param y The y coordinate to paint at.
     */
    public void paintIcon(Component c, Graphics g, int x, int y)
    {
      g.translate(x, y);
      Color saved = g.getColor();

      g.setColor(Color.BLUE);
      g.fillRect(0, 0, iconSize, (int) ((double) iconSize / 3) + 1);

      g.setColor(Color.WHITE);
      g.fillRect(0, (int) ((double) iconSize / 3), iconSize, iconSize * 5 / 6);

      g.setColor(Color.GRAY);
      g.drawRect(0, 0, iconSize, iconSize);

      g.setColor(saved);
      g.translate(-x, -y);
    }
  }

  /** The default JDesktopIcon width. */
  private static final int iconWidth = 160;

  /** The default JDesktopIcon height */
  private static final int iconHeight = 35;

  /** The JDesktopIcon this UI delegate represents. */
  protected JDesktopIcon desktopIcon;

  /** The JInternalFrame associated with the JDesktopIcon. */
  protected JInternalFrame frame;

  /** The MouseListener responsible for reacting to MouseEvents on the JDesktopIcon. */
  private transient MouseInputListener mouseHandler;

  /** The Button in the JDesktopIcon responsible for deiconifying it.
   * This is package-private to avoid an accessor method. */
  transient BoundButton button;

  /** The PropertyChangeListener listening to the JDesktopIcon. */
  private transient PropertyChangeListener propertyHandler;
  
  /** The default icon used when no frame icon is given by the JInternalFrame. */
  static Icon defaultIcon = new InternalFrameDefaultMenuIcon();

  /**
   * This is a helper class that is used in JDesktopIcon and gives the Button a predetermined size.
   */
  private class BoundButton extends JButton
  {
    /**
     * Creates a new BoundButton object.
     *
     * @param title The title of the button.
     */
    public BoundButton(String title)
    {
      super(title);
    }

    /**
     * This method returns a standard size (based on the defaults of the JDesktopIcon) and the insets.
     *
     * @return The preferred size of the JDesktopIcon.
     */
    public Dimension getPreferredSize()
    {
      Insets insets = desktopIcon.getInsets();
      return new Dimension(iconWidth - insets.left - insets.right,
                           iconHeight - insets.top - insets.bottom);
    }

    /**
     * This method returns the minimum size of the button.
     *
     * @return The minimum size of the button.
     */
    public Dimension getMinimumSize()
    {
      return getPreferredSize();
    }

    /**
     * This method returns the maximum size of the button.
     *
     * @return The maximum size of the button.
     */
    public Dimension getMaximumSize()
    {
      return getPreferredSize();
    }
  }

  /**
   * Creates a new BasicDesktopIconUI object.
   */
  public BasicDesktopIconUI()
  {
    // Nothing to do here.
  }

  /**
   * This method creates a new BasicDesktopIconUI for the given JComponent.
   *
   * @param c The JComponent to create a UI for.
   *
   * @return A new BasicDesktopIconUI.
   */
  public static ComponentUI createUI(JComponent c)
  {
    return new BasicDesktopIconUI();
  }

  /**
   * This method installs the UI for the given JComponent.
   *
   * @param c The JComponent to install this UI for.
   */
  public void installUI(JComponent c)
  {
    if (c instanceof JDesktopIcon)
      {
	desktopIcon = (JDesktopIcon) c;
	desktopIcon.setLayout(new BorderLayout());
	frame = desktopIcon.getInternalFrame();

	installDefaults();
	installComponents();
	installListeners();

	desktopIcon.setOpaque(true);
      }
  }

  /**
   * This method uninstalls the UI for the given JComponent.
   *
   * @param c The JComponent to uninstall this UI for.
   */
  public void uninstallUI(JComponent c)
  {
    desktopIcon.setOpaque(false);
    
    uninstallListeners();
    uninstallComponents();
    uninstallDefaults();
    
    frame = null;
    desktopIcon.setLayout(null);
    desktopIcon = null;
  }

  /**
   * This method installs the necessary sub components for the JDesktopIcon.
   */
  protected void installComponents()
  {
    // Try to create a button based on what the frame's
    // state is currently
    button = new BoundButton(frame.getTitle());
    button.setHorizontalAlignment(SwingConstants.LEFT);
    button.setHorizontalTextPosition(SwingConstants.TRAILING);

    Icon use = frame.getFrameIcon();
    if (use == null)
      use = defaultIcon;
    button.setIcon(use);

    desktopIcon.add(button, SwingConstants.CENTER);
  }

  /**
   * This method uninstalls the sub components for the JDesktopIcon.
   */
  protected void uninstallComponents()
  {
    desktopIcon.remove(button);
    
    button = null;
  }

  /**
   * This method installs the listeners needed by this UI.
   */
  protected void installListeners()
  {
    mouseHandler = createMouseInputListener();

    desktopIcon.addMouseMotionListener(mouseHandler);
    desktopIcon.addMouseListener(mouseHandler);

    propertyHandler = new PropertyChangeListener()
        {
	  public void propertyChange(PropertyChangeEvent e)
	  {
	    if (e.getPropertyName().equals(JInternalFrame.TITLE_PROPERTY))
	      button.setText(desktopIcon.getInternalFrame().getTitle());
	    else if (e.getPropertyName().equals(JInternalFrame.FRAME_ICON_PROPERTY))
	      {
		Icon use = desktopIcon.getInternalFrame().getFrameIcon();
		if (use == null)
		  use = defaultIcon;
		button.setIcon(use);
	      }
	    desktopIcon.revalidate();
	    desktopIcon.repaint();
	  }
        };
    frame.addPropertyChangeListener(propertyHandler);

    button.addActionListener(new ActionListener()
        {
	  public void actionPerformed(ActionEvent e)
	  {
            deiconize();
	  }
        });
  }

  /**
   * This method uninstalls the listeners needed by the UI.
   */
  protected void uninstallListeners()
  {
    // button is nulled so no need to remove it.
    
    frame.removePropertyChangeListener(propertyHandler);
    propertyHandler = null;
    
    desktopIcon.removeMouseMotionListener(mouseHandler);
    desktopIcon.removeMouseListener(mouseHandler);
  }

  /**
   * This method installs the defaults for the JDesktopIcon.
   */
  protected void installDefaults()
  {
    // FIXME: Move border to defaults.
    desktopIcon.setBorder(new DesktopIconBorder());  
  }

  /**
   * This method uninstalls the defaults for the JDesktopIcon.
   */
  protected void uninstallDefaults()
  {
    desktopIcon.setBorder(null);
  }

  /**
   * This method creates a new MouseInputListener for the JDesktopIcon.
   *
   * @return A new MouseInputListener.
   */
  protected MouseInputListener createMouseInputListener()
  {
    return new MouseInputHandler();
  }

  /**
   * This method returns the preferred size for the given JComponent.
   *
   * @param c The JComponent to find a preferred size for.
   *
   * @return The preferred size.
   */
  public Dimension getPreferredSize(JComponent c)
  {
    return new Dimension(iconWidth, iconHeight);
  }

  /**
   * This method returns the minimum size for the given JComponent.
   *
   * @param c The JComponent to find a minimum size for.
   *
   * @return The minimum size.
   */
  public Dimension getMinimumSize(JComponent c)
  {
    return getPreferredSize(c);
  }

  /**
   * This method returns the maximum size for the given JComponent.
   *
   * @param c The JComponent to find a maximum size for.
   *
   * @return The maximum size.
   */
  public Dimension getMaximumSize(JComponent c)
  {
    return getPreferredSize(c);
  }

  /**
   * This method returns the insets of the given JComponent.
   *
   * @param c The JComponent to find insets for.
   *
   * @return The insets of the given JComponent.
   */
  public Insets getInsets(JComponent c)
  {
    return c.getInsets();
  }

  /**
   * This method deiconizes the JInternalFrame associated with the JDesktopIcon.
   */
  public void deiconize() 
  {
    try
    {
      frame.setIcon(false);
    }
    catch (PropertyVetoException pve)
    {
      // We do nothing if the attempt has been vetoed.
    }
  }
}
