/* ToolTipManager.java --
   Copyright (C) 2002, 2004, 2006, 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;

import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;

/**
 * This class is responsible for the registration of JToolTips to Components
 * and for displaying them when appropriate.
 */
public class ToolTipManager extends MouseAdapter implements MouseMotionListener
{
  /**
   * This ActionListener is associated with the Timer that listens to whether
   * the JToolTip can be hidden after four seconds.
   */
  protected class stillInsideTimerAction implements ActionListener
  {
    /**
     * This method creates a new stillInsideTimerAction object.
     */
    protected stillInsideTimerAction()
    {
      // Nothing to do here.
    }

    /**
     * This method hides the JToolTip when the Timer has finished.
     *
     * @param event The ActionEvent.
     */
    public void actionPerformed(ActionEvent event)
    {
      hideTip();
    }
  }

  /**
   * This Actionlistener is associated with the Timer that listens to whether
   * the mouse cursor has re-entered the JComponent in time for an immediate
   * redisplay of the JToolTip.
   */
  protected class outsideTimerAction implements ActionListener
  {
    /**
     * This method creates a new outsideTimerAction object.
     */
    protected outsideTimerAction()
    {
      // Nothing to do here.
    }

    /**
     * This method is called when the Timer that listens to whether the mouse
     * cursor has re-entered the JComponent has run out.
     *
     * @param event The ActionEvent.
     */
    public void actionPerformed(ActionEvent event)
    {
      // TODO: What should be done here, if anything?
    }
  }

  /**
   * This ActionListener is associated with the Timer that listens to whether
   * it is time for the JToolTip to be displayed after the mouse has entered
   * the JComponent.
   */
  protected class insideTimerAction implements ActionListener
  {
    /**
     * This method creates a new insideTimerAction object.
     */
    protected insideTimerAction()
    {
      // Nothing to do here.
    }

    /**
     * This method displays the JToolTip when the Mouse has been still for the
     * delay.
     *
     * @param event The ActionEvent.
     */
    public void actionPerformed(ActionEvent event)
    {
      showTip();
    }
  }

  /**
   * The Timer that determines whether the Mouse has been still long enough
   * for the JToolTip to be displayed.
   */
  Timer enterTimer;

  /**
   * The Timer that determines whether the Mouse has re-entered the JComponent
   * quickly enough for the JToolTip to be displayed immediately.
   */
  Timer exitTimer;

  /**
   * The Timer that determines whether the JToolTip has been displayed long
   * enough for it to be hidden.
   */
  Timer insideTimer;

  /** A global enabled setting for the ToolTipManager. */
  private transient boolean enabled = true;

  /** lightWeightPopupEnabled */
  protected boolean lightWeightPopupEnabled = true;

  /** heavyWeightPopupEnabled */
  protected boolean heavyWeightPopupEnabled = false;

  /** The shared instance of the ToolTipManager. */
  private static ToolTipManager shared;

  /** The current component the tooltip is being displayed for. */
  private static Component currentComponent;

  /** The current tooltip. */
  private static JToolTip currentTip;

  /** The last known position of the mouse cursor. */
  private static Point currentPoint;
  
  /**  */
  private static Popup popup;

  /**
   * Creates a new ToolTipManager and sets up the timers.
   */
  ToolTipManager()
  {
    enterTimer = new Timer(750, new insideTimerAction());
    enterTimer.setRepeats(false);

    insideTimer = new Timer(4000, new stillInsideTimerAction());
    insideTimer.setRepeats(false);

    exitTimer = new Timer(500, new outsideTimerAction());
    exitTimer.setRepeats(false);
  }

  /**
   * This method returns the shared instance of ToolTipManager used by all
   * JComponents.
   *
   * @return The shared instance of ToolTipManager.
   */
  public static ToolTipManager sharedInstance()
  {
    if (shared == null)
      shared = new ToolTipManager();

    return shared;
  }

  /**
   * This method sets whether ToolTips are enabled or disabled for all
   * JComponents.
   *
   * @param enabled Whether ToolTips are enabled or disabled for all
   *        JComponents.
   */
  public void setEnabled(boolean enabled)
  {
    if (! enabled)
      {
	enterTimer.stop();
	exitTimer.stop();
	insideTimer.stop();
      }

    this.enabled = enabled;
  }

  /**
   * This method returns whether ToolTips are enabled.
   *
   * @return Whether ToolTips are enabled.
   */
  public boolean isEnabled()
  {
    return enabled;
  }

  /**
   * This method returns whether LightweightToolTips are enabled.
   *
   * @return Whether LighweightToolTips are enabled.
   */
  public boolean isLightWeightPopupEnabled()
  {
    return lightWeightPopupEnabled;
  }

  /**
   * This method sets whether LightweightToolTips are enabled. If you mix
   * Lightweight and Heavyweight components, you must set this to false to
   * ensure that the ToolTips popup above all other components.
   *
   * @param enabled Whether LightweightToolTips will be enabled.
   */
  public void setLightWeightPopupEnabled(boolean enabled)
  {
    lightWeightPopupEnabled = enabled;
    heavyWeightPopupEnabled = ! enabled;
  }

  /**
   * This method returns the initial delay before the ToolTip is shown when
   * the mouse enters a Component.
   *
   * @return The initial delay before the ToolTip is shown.
   */
  public int getInitialDelay()
  {
    return enterTimer.getDelay();
  }

  /**
   * Sets the initial delay before the ToolTip is shown when the
   * mouse enters a Component.
   *
   * @param delay The initial delay before the ToolTip is shown.
   * 
   * @throws IllegalArgumentException if <code>delay</code> is less than zero.
   */
  public void setInitialDelay(int delay)
  {
    enterTimer.setDelay(delay);
  }

  /**
   * This method returns the time the ToolTip will be shown before being
   * hidden.
   *
   * @return The time the ToolTip will be shown before being hidden.
   */
  public int getDismissDelay()
  {
    return insideTimer.getDelay();
  }

  /**
   * Sets the time the ToolTip will be shown before being hidden.
   *
   * @param delay  the delay (in milliseconds) before tool tips are hidden.
   * 
   * @throws IllegalArgumentException if <code>delay</code> is less than zero.
   */
  public void setDismissDelay(int delay)
  {
    insideTimer.setDelay(delay);
  }

  /**
   * This method returns the amount of delay where if the mouse re-enters a
   * Component, the tooltip will be shown immediately.
   *
   * @return The reshow delay.
   */
  public int getReshowDelay()
  {
    return exitTimer.getDelay();
  }

  /**
   * Sets the amount of delay where if the mouse re-enters a
   * Component, the tooltip will be shown immediately.
   *
   * @param delay The reshow delay (in milliseconds).
   * 
   * @throws IllegalArgumentException if <code>delay</code> is less than zero.
   */
  public void setReshowDelay(int delay)
  {
    exitTimer.setDelay(delay);
  }

  /**
   * This method registers a JComponent with the ToolTipManager.
   *
   * @param component The JComponent to register with the ToolTipManager.
   */
  public void registerComponent(JComponent component)
  {
    component.addMouseListener(this);
    component.addMouseMotionListener(this);
  }

  /**
   * This method unregisters a JComponent with the ToolTipManager.
   *
   * @param component The JComponent to unregister with the ToolTipManager.
   */
  public void unregisterComponent(JComponent component)
  {
    component.removeMouseMotionListener(this);
    component.removeMouseListener(this);
  }

  /**
   * This method is called whenever the mouse enters a JComponent registered
   * with the ToolTipManager. When the mouse enters within the period of time
   * specified by the reshow delay, the tooltip will be displayed
   * immediately. Otherwise, it must wait for the initial delay before
   * displaying the tooltip.
   *
   * @param event The MouseEvent.
   */
  public void mouseEntered(MouseEvent event)
  {
    if (currentComponent != null
        && getContentPaneDeepestComponent(event) == currentComponent)
      return;
    currentPoint = event.getPoint();

    currentComponent = (Component) event.getSource();

    if (exitTimer.isRunning())
      {
        exitTimer.stop();
        showTip();
        return;
      }
    // This should always be stopped unless we have just fake-exited.
    if (!enterTimer.isRunning())
      enterTimer.start();
  }

  /**
   * This method is called when the mouse exits a JComponent registered with the
   * ToolTipManager. When the mouse exits, the tooltip should be hidden
   * immediately.
   * 
   * @param event
   *          The MouseEvent.
   */
  public void mouseExited(MouseEvent event)
  {
    if (getContentPaneDeepestComponent(event) == currentComponent)
      return;

    currentPoint = event.getPoint();
    currentComponent = null;
    hideTip();

    if (! enterTimer.isRunning())
      exitTimer.start();
    if (enterTimer.isRunning())
      enterTimer.stop();
    if (insideTimer.isRunning())
      insideTimer.stop();
  }

  /**
   * This method is called when the mouse is pressed on a JComponent
   * registered with the ToolTipManager. When the mouse is pressed, the
   * tooltip (if it is shown) must be hidden immediately.
   *
   * @param event The MouseEvent.
   */
  public void mousePressed(MouseEvent event)
  {
    currentPoint = event.getPoint();
    if (enterTimer.isRunning())
      enterTimer.restart();
    else if (insideTimer.isRunning())
      {
	insideTimer.stop();
	hideTip();
      }
  }

  /**
   * This method is called when the mouse is dragged in a JComponent
   * registered with the ToolTipManager.
   *
   * @param event The MouseEvent.
   */
  public void mouseDragged(MouseEvent event)
  {
    currentPoint = event.getPoint();
    if (enterTimer.isRunning())
      enterTimer.restart();
  }

  /**
   * This method is called when the mouse is moved in a JComponent registered
   * with the ToolTipManager.
   *
   * @param event The MouseEvent.
   */
  public void mouseMoved(MouseEvent event)
  {
    currentPoint = event.getPoint();
    if (enterTimer.isRunning())
      enterTimer.restart(); 
  }

  /**
   * This method displays the ToolTip. It can figure out the method needed to
   * show it as well (whether to display it in heavyweight/lightweight panel
   * or a window.)  This is package-private to avoid an accessor method.
   */
  void showTip()
  {
    if (!enabled || currentComponent == null || !currentComponent.isEnabled()
        || !currentComponent.isShowing())
      {
        popup = null;
        return;
      }

    if (currentTip == null || currentTip.getComponent() != currentComponent
        && currentComponent instanceof JComponent)
      currentTip = ((JComponent) currentComponent).createToolTip();

    Point p = currentPoint;
    Point cP = currentComponent.getLocationOnScreen();
    Dimension dims = currentTip.getPreferredSize();
    
    JLayeredPane pane = null;
    JRootPane r = ((JRootPane) SwingUtilities.getAncestorOfClass(JRootPane.class,
                                                                 currentComponent));
    if (r != null)
      pane = r.getLayeredPane();
    if (pane == null)
      return;
    
    p.translate(cP.x, cP.y);
    adjustLocation(p, pane, dims);
    
    currentTip.setBounds(0, 0, dims.width, dims.height);
    
    PopupFactory factory = PopupFactory.getSharedInstance();
    popup = factory.getPopup(currentComponent, currentTip, p.x, p.y);
    popup.show();
  }

  /**
   * Adjusts the point to a new location on the component,
   * using the currentTip's dimensions.
   * 
   * @param p - the point to convert.
   * @param c - the component the point is on.
   * @param d - the dimensions of the currentTip.
   */
  private Point adjustLocation(Point p, Component c, Dimension d)
  {
    if (p.x + d.width > c.getWidth())
      p.x -= d.width;
    if (p.x < 0)
      p.x = 0;
    if (p.y + d.height < c.getHeight())
      p.y += d.height;
    if (p.y + d.height > c.getHeight())
      p.y -= d.height;
    
    return p;
  }
  
  /**
   * This method hides the ToolTip.
   * This is package-private to avoid an accessor method.
   */
  void hideTip()
  {
    if (popup != null)
      popup.hide();
  }

  /**
   * This method returns the deepest component in the content pane for the
   * first RootPaneContainer up from the currentComponent. This method is
   * used in conjunction with one of the mouseXXX methods.
   *
   * @param e The MouseEvent.
   *
   * @return The deepest component in the content pane.
   */
  private Component getContentPaneDeepestComponent(MouseEvent e)
  {
    Component source = (Component) e.getSource();
    Container parent = (Container) SwingUtilities.getAncestorOfClass(JRootPane.class,
                                                                     currentComponent);
    if (parent == null)
      return null;
    parent = ((JRootPane) parent).getContentPane();
    Point p = e.getPoint();
    p = SwingUtilities.convertPoint(source, p, parent);
    Component target = SwingUtilities.getDeepestComponentAt(parent, p.x, p.y);
    return target;
  }
}
