/**
 * GUI Commands
 * Copyright 2004 Andrew Pietsch
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * $Id: PopupAdapter.java,v 1.5 2005/01/09 03:24:03 pietschy Exp $
 */

package org.pietschy.command;

import javax.swing.*;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

/**
 * Links the display of the button and menu so that pressing the button shows the menu, and
 * closing the menu deselects the button.
 */
class PopupAdapter
implements PopupMenuListener, ItemListener
{
   private AbstractButton button;
   private JPopupMenu menu;

   private boolean buttonWasPressed = false;

   private Timer cancelDelay;

   /**
    * Binds the specified toggle button and menu together.
    * @param button
    * @param menu
    */
   public static void bind(AbstractButton button, JPopupMenu menu)
   {
      new PopupAdapter(button, menu);
   }

   private PopupAdapter(AbstractButton button, JPopupMenu menu)
   {
      this.button = button;
      this.menu = menu;

      button.addItemListener(this);
      menu.addPopupMenuListener(this);

      // We need to keep track of whether the button was pressed or not
      // so the menu can determine if it should deselect the button.
      button.addMouseListener(new MouseAdapter()
      {
         public void mousePressed(MouseEvent e)
         {
            buttonWasPressed = true;
         }

         public void mouseReleased(MouseEvent e)
         {
            buttonWasPressed = false;
         }
      });
   }


   public void itemStateChanged(ItemEvent e)
   {
      if (button.isSelected())
         menu.show(button, 0, button.getHeight());
   }

   public void popupMenuWillBecomeInvisible(PopupMenuEvent e)
   {
      // this method can be called before the mousePressed method so we delay processing.  This
      // is all we need to do to support 1.5
      SwingUtilities.invokeLater(new Runnable()
      {
         public void run()
         {
            menuClosed();
         }
      });
   }

   public void popupMenuWillBecomeVisible(PopupMenuEvent e)
   {
   }

   public void popupMenuCanceled(PopupMenuEvent e)
   {

   }

   public void menuClosed()
   {
      // only set the state of the button to non selected if
      // the close was triggered by something other that
      // clicking the button...
      if (button.isSelected() && !buttonWasPressed)
         button.setSelected(false);
   }

   public static void
   main(String[] args)
   {
      JFrame f = new JFrame("Test");
      f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      JToggleButton b = new JToggleButton("Press me");
      JPopupMenu menu = new JPopupMenu();
      menu.add(new JMenuItem("and me!"));

      PopupAdapter.bind(b, menu);

      f.getContentPane().add(b);
      f.pack();

      f.setLocationRelativeTo(null);
      f.setVisible(true);

   }
}
