package org.pietschy.command;

import javax.swing.*;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import java.awt.*;
import java.awt.event.HierarchyEvent;
import java.awt.event.HierarchyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

/**
 * Created by IntelliJ IDEA.
 * User: andrew
 * Date: Jun 4, 2005
 * Time: 12:29:16 PM
 * To change this template use File | Settings | File Templates.
 */
class HoverManager
extends MouseAdapter
implements HierarchyListener, PopupMenuListener
{

   private Command command;
   private Face lastHoveredFace;


   public HoverManager(Command command)
   {
      this.command = command;
   }

   public void
   mouseEntered(MouseEvent e)
   {
      command.fireHoverStarted(getFace(e), (Component) e.getSource());
   }


   public void
   mouseExited(MouseEvent e)
   {
      command.fireHoverEnded(getFace(e), (Component) e.getSource());
   }

   private Face
   getFace(MouseEvent e)
   {
      lastHoveredFace = RenderContext.get((AbstractButton) e.getComponent()).getFace();
      return lastHoveredFace;
   }


   public void
   hierarchyChanged(HierarchyEvent e)
   {
      if (e.getChangeFlags() == HierarchyEvent.PARENT_CHANGED)
      {
         Container oldParent = e.getChangedParent();
         Container parent = e.getComponent().getParent();

         // we have to track the popup parent of the button so we can fire a hover ended when
         // the popup is closed.  In such cases we don't get a mouse exited event on the
         // button.
         if (oldParent != null && oldParent instanceof JPopupMenu && !oldParent.equals(parent))
         {
            ((JPopupMenu) oldParent).removePopupMenuListener(HoverManager.this);
         }

         if (parent instanceof JPopupMenu)
         {
            ((JPopupMenu) parent).addPopupMenuListener(HoverManager.this);
         }

      }
   }

   public void popupMenuWillBecomeVisible(PopupMenuEvent e)
   {
   }

   public void popupMenuWillBecomeInvisible(PopupMenuEvent e)
   {
      command.fireHoverEnded(lastHoveredFace, (Component) e.getSource());
   }

   public void popupMenuCanceled(PopupMenuEvent e)
   {
      command.fireHoverEnded(lastHoveredFace, (Component) e.getSource());
   }

}
