/*
 * DefaultActionManager.java  $Revision: 1.5 $  $Date: 2007/10/03 04:59:32 $
 *
 * Copyright (C) 2007 Meldcraft Corporation
 *
 * This file is part of Scaffold.
 * 
 * Scaffold is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * Scaffold 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 Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with Scaffold.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.meldcraft.application.swing.action;

import java.awt.event.ActionEvent;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;

import javax.swing.AbstractAction;
import javax.swing.Action;

import com.meldcraft.application.swing.SwingApplicationContext;

/**
 * @version $Revision: 1.5 $ $Date: 2007/10/03 04:59:32 $
 * @author Rob Richards
 */
public class DefaultActionManager implements ActionManager
{
// Static variables
// Member variables
    private SwingApplicationContext mApplicationContext;
    private Map                     mActions;
    private Map                     mReverseMap;
    private Action                  mEmptyAction;
    private ActionFactory           mActionFactory;

// Constructors and initialization
    public DefaultActionManager(SwingApplicationContext context)
    {
        mApplicationContext = context;
        mActions = new HashMap();
        mReverseMap = new HashMap();
        mEmptyAction = new EmptyAction();
        mActionFactory = createActionFactory(context);
    }

// Public methods
    public Action getAction(String actionId)
    {
        Action ret = (Action)mActions.get(actionId);

        if (ret == null)
        {
            try
            {
                ret = mActionFactory.createAction(actionId);
            }
            catch (Exception e)
            {
                mApplicationContext.getLogger().log(Level.WARNING, "Error creating action for actionId="+actionId, e);
            }

            if (ret == null)
            {
                ret = mEmptyAction;
            }

            putAction(actionId, ret);
        }

        if (ret == mEmptyAction)
        {
            ret = null;
        }

        return ret;
    }

    public void putAction(String actionId, Action action)
    {
        if (mActions.get(actionId) == null)
        {
            mActions.put(actionId, action);
            mReverseMap.put(action, actionId);

            postPutAction(actionId, action);
        }
    }

    public boolean removeAction(Action action)
    {
        boolean ret = false;
        Object key = mReverseMap.remove(action);
        if (key != null)
        {
            mActions.remove(key);
            ret = true;
        }

        postRemoveAction((String)key, action);

        return ret;
    }

    public boolean removeAction(String actionId)
    {
        boolean ret = false;
        Object key = mActions.remove(actionId);
        if (key != null)
        {
            mReverseMap.remove(key);
            ret = true;
        }

        postRemoveAction(actionId, (Action)key);

        return ret;
    }

// Protected methods
    protected ActionFactory createActionFactory(SwingApplicationContext context)
    {
        return ActionFactory.createActionFactory(context);
    }

    protected void postPutAction(String actionId, Action action)
    {
        if ((actionId != null) && (action != null))
        {
            mApplicationContext.contextChanged(createActionKey(actionId), action);
        }
    }

    protected void postRemoveAction(String actionId, Action action)
    {
        if (actionId != null)
        {
            mApplicationContext.contextChanged(createActionKey(actionId), null);
        }
    }

    protected String createActionKey(String actionId)
    {
        return "actionManager.action(" + actionId + ")";
    }

// Private methods
// Inner classes
    public static class EmptyAction extends AbstractAction
    {
        public void actionPerformed(ActionEvent e)
        {
            // noop
        }
    }
}
