/**
 * GUI Commands
 * Copyright 2005 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: SwingActionDelegate.java,v 1.2 2006/04/14 20:08:20 pietschy Exp $
 */
package org.pietschy.command.delegate;

import org.pietschy.command.ActionCommand;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Map;

/**
 * SwingActionDelete is an instance of {@link CommandDelegate} that invokes an existing swing action.  This is
 * useful for mapping Commands to components that have built in actions.
 * <p>
 * Example.<br>
 * <code>CommandDelegate delgate = new SwingActionDelegate("copy-command", getActionMap(), "copy-to-clipboard")</code>
 * <p>
 * The above example will invoke the "copy-to-clipboard" action when the "copy-command" is invoked.
 *
 * @author andrewp
 * @version $Revision: 1.2 $
 */
public class
SwingActionDelegate
extends CommandDelegate
{
   private Action action;

   /**
    * Creates a new delegate with the specified id that invokes the specfied {@link javax.swing.Action}.
    *
    * @param id     the id of the delegate.
    * @param action the {@link javax.swing.Action} to invoke.
    */
   public SwingActionDelegate(String id, Action action)
   {
      super(id);

      if (action == null)
         throw new NullPointerException("action is null");

      this.action = action;

      action.addPropertyChangeListener(new PropertyChangeListener()
      {
         public void propertyChange(PropertyChangeEvent evt)
         {
            if ("enabled".equals(evt.getPropertyName()))
            {
               setEnabled(SwingActionDelegate.this.action.isEnabled());
            }
         }
      });

   }

   /**
    * Creates a new delegate with the specified id that invokes the {@link javax.swing.Action} in the
    * specified {@link javax.swing.ActionMap} with the specified action key.
    * <p>
    * Example.<br>
    * <code>CommandDelegate delgate = new SwingActionDelegate("copy-command", getActionMap(), "copy-to-clipboard")</code>
    * <p>
    * The above example will invoke the "copy-to-clipboard" action when the "copy-command" is invoked.
    *
    * @param id        the id of the delegate.
    * @param actionMap the {@link javax.swing.ActionMap} containing the Action.
    * @param actionKey the actions key within the map.
    */
   public SwingActionDelegate(String id, ActionMap actionMap, Object actionKey)
   {
      this(id, actionMap.get(actionKey));
   }


   public void
   execute(Map hints)
   {
      ActionEvent actionEvent = (ActionEvent) hints.get(ActionCommand.HINT_ACTION_EVENT);

      if (actionEvent == null)
      {
         // should I pass the commands invoker here, or just the command???
         actionEvent = new ActionEvent(this, 0, "");
      }

      action.actionPerformed(actionEvent);
   }

}
