/***************************** LICENSE START ***********************************

 Copyright 2013 ECMWF and INPE. This software is distributed under the terms
 of the Apache License version 2.0. In applying this license, ECMWF does not
 waive the privileges and immunities granted to it by virtue of its status as
 an Intergovernmental Organization or submit itself to any jurisdiction.

 ***************************** LICENSE END *************************************/

#pragma once

#include <QAction>
#include <QList>
#include <QMenu>
#include <QPoint>
#include <QSet>
#include <QString>

#include <set>
#include <string>
#include <vector>

class QMenu;
class QObject;
class QShortcut;

class IconObject;
class MvRequest;

class MvQContextItem;

class MvQContextItemSet
{
public:
    MvQContextItemSet(const std::string& name);
    QList<MvQContextItem*> icon() const { return icon_; }
    QList<MvQContextItem*> multiIcon() const { return multiIcon_; }
    QList<MvQContextItem*> desktop() const { return desktop_; }
    QList<MvQContextItem*> container() const { return container_; }
    QShortcut* makeDefaultIconShortCut(QWidget*);

private:
    void add(const MvRequest&);
    QList<MvQContextItem*> icon_;
    QList<MvQContextItem*> multiIcon_;
    QList<MvQContextItem*> desktop_;
    QList<MvQContextItem*> container_;
};

class MvQContextItemCondition
{
public:
    MvQContextItemCondition(QString);
    bool check(QString);
    bool isValid() const { return valid_; }

protected:
    QString operand() const { return operand_; }
    QString key() const { return key_; }
    QString value() const { return value_; }

    QString operand_;
    QString key_;
    QString value_;
    bool valid_;
};

class MvQContextItem
{
public:
    MvQContextItem();
    MvQContextItem(const MvRequest& r);

    QString id() const { return id_; }
    QString command() const { return command_; }
    QString service() const { return service_; }
    QString shortCut() const { return shortCut_; }
    virtual void addToMenu(QMenu*) = 0;
    virtual QShortcut* makeShortCut(QWidget*) = 0;
    bool checkCondition(QString);
    static bool checkEnv(const MvRequest& r);
    static MvQContextItem* build(const MvRequest& r, QList<MvQContextItem*> items);
    bool hasShortCut(QString);
    virtual bool checkCommand(const std::set<std::string>&) const;

protected:
    QString iconPath(const MvRequest& r);

    MvQContextItemCondition condition_;
    QString id_;
    QString command_;
    QString service_;
    QString shortCut_;
};

class MvQContextSubMenu : public QMenu, public MvQContextItem
{
public:
    MvQContextSubMenu(QString, QString iconPath = QString());
    MvQContextSubMenu(const MvRequest& r);
    void addToMenu(QMenu*) override;
    QShortcut* makeShortCut(QWidget*) override { return nullptr; }
    void addChildCommand(QString cmd);
    bool checkCommand(const std::set<std::string>&) const override;

private:
    QStringList childCommands_;
};

class MvQContextAction : public QAction, public MvQContextItem
{
public:
    MvQContextAction(QMenu*, const MvRequest& r);
    void addToMenu(QMenu*) override;
    QShortcut* makeShortCut(QWidget*) override;

protected:
    void init(QString, QString, QString, QString);
};

class MvQContextSeparator : public QAction, public MvQContextItem
{
public:
    MvQContextSeparator(QMenu* menu = nullptr);
    void addToMenu(QMenu*) override;
    QShortcut* makeShortCut(QWidget*) override { return nullptr; }
};

class MvQContextMenu
{
public:
    MvQContextMenu();
    static MvQContextMenu* instance();

    QString exec(QList<MvQContextItem*>, IconObject*, QPoint, QWidget*);
    QString exec(QList<MvQContextItem*> lst, const std::vector<IconObject*>& objLst, QPoint pos, QWidget* parent);
    QString exec(QList<MvQContextItem*> lst, QPoint pos, QWidget* parent,
                 QString defaultMethod = QString(), QString condition = QString());

protected:
    static MvQContextMenu* instance_;
};
