/*
 * @(#)ActionWrapper.java    1.0  21 February 2002
 *
 * Copyright 2004
 * College of Computer and Information Science
 * Northeastern University
 * Boston, MA  02115
 *
 * The Java Power Tools software may be used for educational
 * purposes as long as this copyright notice is retained intact
 * at the top of all source files.
 *
 * To discuss possible commercial use of this software, 
 * contact Richard Rasala at Northeastern University, 
 * College of Computer and Information Science,
 * 617-373-2462 or rasala@ccs.neu.edu.
 *
 * The Java Power Tools software has been designed and built
 * in collaboration with Viera Proulx and Jeff Raab.
 *
 * Should this software be modified, the words "Modified from 
 * Original" must be included as a comment below this notice.
 *
 * All publication rights are retained.  This software or its 
 * documentation may not be published in any media either
 * in whole or in part without explicit permission.
 *
 * This software was created with support from Northeastern 
 * University and from NSF grant DUE-9950829.
 */

package edu.neu.ccs.gui;

import java.awt.event.*;
import javax.swing.*;
import java.beans.*;
 
/**
 * <P>Base class for encapsulating <CODE>Action</CODE> objects 
 * to provide extra functionality.</P>
 *
 * @author Richard Rasala
 * @version 2.2
 * @since   2.0
 */
public abstract class ActionWrapper implements Action {
 
    /** The action to encapsulate as a thread. */
    protected Action action = null;
    
    //////////////////
    // Constructors //
    //////////////////
    
    /** 
     * Constructs an empty wrapper. 
     *
     * @see #ActionWrapper(Action)
     */
    public ActionWrapper() {}
    
    /**
     * Constructs a wrapper that encapsulates the given action.
     *
     * @param action the action to encapsulate
     * @see #ActionWrapper()
     */
    public ActionWrapper(Action action) {
        setAction(action);
    }
    
    ////////////
    // Action //
    ////////////
    
    public Object getValue(String key) {
        if (action == null)
            return null;
        
        return action.getValue(key);
    }
    
    public void putValue(String key, Object value) {
        if (action == null)
            return;
        
        action.putValue(key, value);
    }
    
    public boolean isEnabled() {
        if (action == null)
            return false;
        
        return action.isEnabled();
    }
    
    public void setEnabled(boolean b) {
        if (action == null)
            return;
        
        action.setEnabled(b);
    }
    
    public void addPropertyChangeListener
        (PropertyChangeListener listener)
    {
        if (action == null)
            return;
        
        action.addPropertyChangeListener(listener);
    }
    
    public void removePropertyChangeListener
        (PropertyChangeListener listener)
    {
        if (action == null)
            return;
        
        action.removePropertyChangeListener(listener);
    }
    
    ////////////////////
    // ActionListener //
    ////////////////////
    
    /**
     * Implement the <CODE>actionPerformed</CODE> method to
     * decide how the encapsulated action will be used.
     *
     * @param event the event that invoked this action
     */
    public abstract void actionPerformed(ActionEvent event);
    
    ////////////////
    // Public API //
    ////////////////
    
    /** 
     * Returns the encapsulated action. 
     *
     * @see #setAction(Action)
     */
    public Action getAction() { 
        return action; 
    }
    
    /**
     * Sets the encapsulated action to the given action.
     *
     * @param action the action to encapsulate
     * @see #getAction()
     */
    public void setAction(Action action) {
        this.action = action;
    }
    
    /**
     * Returns the name associated with the action,
     * or an empty <CODE>String</CODE> if no name is defined.
     */
    public String getName() {
        String name = "";
        
        if (action != null) {
            Object actionName = getValue(Action.NAME);
            
            if (actionName instanceof String)
                name = (String) actionName;
        }
        
        return name;
    }
    
    ////////////////////
    // Static Methods //
    ////////////////////
    
    /**
     * Returns the base action that remains after 
     * recursively stripping all action wrappers 
     * from the given action.
     *
     * If the given action is not wrapped,
     * the given action is itself returned.
     */
    public static Action getBaseAction(Action action) {
        if (action instanceof ActionWrapper) {
            ActionWrapper wrapper = (ActionWrapper)action;
            return getBaseAction(wrapper.getAction());
        }

        return action;
    }
}
