/*============================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center (DKFZ)
All rights reserved.

Use of this source code is governed by a 3-clause BSD license that can be
found in the LICENSE file.

============================================================================*/

#ifndef BERRYCOMMANDCATEGORY_H_
#define BERRYCOMMANDCATEGORY_H_

#include "common/berryNamedHandleObject.h"
#include "berryICommandCategoryListener.h"

#include <org_blueberry_core_commands_Export.h>

namespace berry
{

/**
 * <p>
 * A logical group for a set of commands. A command belongs to exactly one
 * category. The category has no functional effect, but may be used in graphical
 * tools that want to group the set of commands somehow.
 * </p>
 */
class BERRY_COMMANDS CommandCategory: public NamedHandleObject
{

public:

  berryObjectMacro(CommandCategory);

  /**
   * Adds a listener to this category that will be notified when this
   * category's state changes.
   *
   * @param categoryListener
   *            The listener to be added; must not be <code>null</code>.
   */
  void AddCategoryListener(ICommandCategoryListener* categoryListener);

  /**
   * <p>
   * Defines this category by giving it a name, and possibly a description as
   * well. The defined property automatically becomes <code>true</code>.
   * </p>
   * <p>
   * Notification is sent to all listeners that something has changed.
   * </p>
   *
   * @param name
   *            The name of this command; must not be <code>null</code>.
   * @param description
   *            The description for this command; may be <code>null</code>.
   */
  void Define(const QString& name, const QString& description);

  /**
   * Removes a listener from this category.
   *
   * @param categoryListener
   *            The listener to be removed; must not be <code>null</code>.
   *
   */
  void RemoveCategoryListener(ICommandCategoryListener* categoryListener);

  /*
   * (non-Javadoc)
   *
   * @see org.eclipse.core.commands.common.HandleObject#toString()
   */
  QString ToString() const override;

  /*
   * (non-Javadoc)
   *
   * @see org.eclipse.core.commands.common.HandleObject#undefine()
   */
  void Undefine() override;

protected:

  friend class CommandManager;

  /**
   * Constructs a new instance of <code>Category</code> based on the given
   * identifier. When a category is first constructed, it is undefined.
   * Category should only be constructed by the <code>CommandManager</code>
   * to ensure that identifier remain unique.
   *
   * @param id
   *            The identifier for the category. This value must not be
   *            <code>null</code>, and must be unique amongst all
   *            categories.
   */
  CommandCategory(const QString& id);

private:

  /**
   * Notifies the listeners for this category that it has changed in some way.
   *
   * @param categoryEvent
   *            The event to send to all of the listener; must not be
   *            <code>null</code>.
   */
  void FireCategoryChanged(const SmartPointer<CommandCategoryEvent> categoryEvent);

  /**
   * A collection of objects listening to changes to this category. This
   * collection is <code>null</code> if there are no listeners.
   */
  ICommandCategoryListener::Events categoryEvents;
};

}

#endif /* BERRYCOMMANDCATEGORY_H_ */
