#ifndef BasicActionDefinitionH
#define BasicActionDefinitionH
#define BOOST_THREAD_USE_LIB
#include "context/AbstractEntityDefinition.h"
#include "action/ActionDefinition.h"
#include "action/ActionCommandList.h"
#include "action/KeyStroke.h"
#include "security/Permission.h"
#include <boost/shared_ptr.hpp>
#include <boost/thread/mutex.hpp>
#include "action/Action.h"
#include "action/ActionCommand.h"
#include "action/GroupIdentifier.h"
#include "action/KeyStroke.h"
#include "action/RequestIdentifier.h"
#include "action/ResourceMask.h"
#include <string>

class BasicActionDefinition
	: public AbstractEntityDefinition
	, public ActionDefinition
    , public ActionCommandList
{
private:
    static AgString GROUP_ID_SEPARATOR_() { return "/"; }
    static AgString PROPERTY_NAME_() { return "name"; }
    static AgString PROPERTY_DESCRIPTION_() { return "description"; }
    static AgString PROPERTY_DROP_SOURCES_() { return "dropSources"; }
    static AgString PROPERTY_HELP_() { return "help"; }
    static AgString PROPERTY_ACCELERATOR_() { return "accelerator"; }
    static AgString PROPERTY_HIDDEN_() { return "hidden"; }
    static AgString PROPERTY_ENABLED_() { return "enabled"; }
    static AgString PROPERTY_GROUP_ID_() { return "groupId"; }
    static AgString PROPERTY_ICON_ID_() { return "iconId"; }
    static AgString PROPERTY_DEFAULT_() { return "default"; }

    std::string actionClass;
    bool enabled;
    bool isDefault_;
    bool hidden;
    boost::shared_ptr<GroupIdentifier> executionGroup;
    boost::shared_ptr<KeyStroke> accelerator;
	std::list<ResourceMaskPtr>  dropSources;
    std::list<ActionCommandPtr>  commandList;
	boost::mutex executionLock;

	void init();

public:
    bool concurrent;

    GroupIdentifierPtr getExecutionGroup();
    bool isEnabled();
    bool isHidden();
	boost::shared_ptr<KeyStroke> getAccelerator();
	std::list< ResourceMaskPtr >  getDropSources();
    void setIconId(const AgString & iconId);
    void setHelp(const AgString & help);
    void setDescription(const AgString & description);
    void setExecutionGroup(const AgString & base);
    void setExecutionGroup(boost::shared_ptr<GroupIdentifier> groupId);
    void setEnabled(bool enabled);
    void setHidden(bool hidden);
    void setAccelerator(boost::shared_ptr<KeyStroke> accelerator);
	void setDropSources(std::list< ResourceMaskPtr >  dropSources);
    void setName(const AgString & name);
    bool isDefault();
    void setDefault(bool isDefault);
    bool isConcurrent();
    void setConcurrent(bool allowConcurrentExecution);
    void addDropSource(ResourceMaskPtr resourceMask);
    ActionPtr instantiate();
    std::list<ActionCommandPtr>  getCommands();

    void registerCommands();
    void registerCommand(ActionCommandPtr cmd);
    void unregisterCommand(const AgString & id);

    boost::mutex& getExecutionLock();
    bool isHeadless();
	PermissionsPtr getPermissions();

    virtual int compareTo(Comparable *obj);

    BasicActionDefinition(const AgString & name);
    BasicActionDefinition(const AgString & name, const std::string& actionClass);

	AgString &getDescription();
    AgString &getGroup();
    AgString &getHelp();
    AgString &getIconId();
    int  getIndex() const;
    AgString &getName();
    AgObjectPtr getOwner();
    AgString toDetailedString();
};

#endif
