/******************************************************************************
  This source file is part of the Avogadro project.
  This source code is released under the 3-Clause BSD License, (see "LICENSE").
******************************************************************************/

#ifndef AVOGADRO_MENUBUILDER_H
#define AVOGADRO_MENUBUILDER_H

#include <QtCore/QMap>
#include <QtCore/QObject>

class QAction;
class QMenu;
class QMenuBar;

/**
 * @brief The MenuBuilder class helps to dynamically build up the application
 * menus.
 *
 * This class allows you to build up a list of menu entries, order them by
 * priority/section and then add them to a QMenu once all elements have been
 * added.
 *
 * Separators are inserted as needed when priorities cross multiples of 100
 * (e.g. The ranges ..., (-100)-(-1), 0-99, 100-199, ... will be grouped
 * together).
 */

namespace Avogadro {

class MenuBuilder : public QObject
{
  Q_OBJECT

public:
  MenuBuilder();

  /**
   * @brief Add a new action to the menu builder object.
   * @param path The menu path, where each element specifies a menu level.
   * @param action The action that will be added at the path.
   * @param priority The priority of the entry, higher will be at the top.
   */
  void addAction(const QStringList& path, QAction* action, int priority = -1);

  /**
   * @brief Populate the supplied menu bar with the items added to builder.
   * Ordering
   * is attempted, ensuring File is first, Help is last and ordering by priority
   * and then alphanumerically.
   * @param menu The menu to be populated.
   */
  void buildMenuBar(QMenuBar* menuBar);

  /**
   * @brief Populate a menu with the appropriate sub-entries.
   */
  void buildMenu(QMenu* menu, const QString& path);

  /**
   * @brief Print the contents of the MenuBuilder, intended for debug.
   */
  void print();

private:
  /** A map of string to action lists. */
  QMap<QString, QList<QAction*>> m_menuActions;
  /** Mapping QString from m_menuActions to QStringLists. */
  QMap<QString, QStringList> m_menuPaths;
  /** Store entry priority orders mapped to the QActions. */
  QMap<QAction*, int> m_priorities;
  /** Top level menus mapped to text. */
  QMap<QString, QMenu*> m_topLevelMenus;

  /** Get the priority of a submenu (takes the highest priority). */
  int priorityGroup(const QString& path);
};

} // End namespace Avogadro.

#endif // AVOGADRO_MENUBUILDER_H
