/*****************************************************************************
 *
 * Testmanager - Graphical Automation and Visualisation Tool
 *
 * opyright (C) 2018 - 2019  Florian Pose <fp@igh.de>
 *
 * This file is part of Testmanager.
 *
 * Testmanager is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation, either version 3 of the License, or (at your option)
 * any later version.
 *
 * Testmanager 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 General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with Testmanager. If not, see <http://www.gnu.org/licenses/>.
 *
 ****************************************************************************/

#ifndef WIDGETCONTAINER_H
#define WIDGETCONTAINER_H

/****************************************************************************/

#include "SlotModel.h"
#include "ScriptVariableModel.h"
#include "Legend.h"

#include <QWidget>
#include <QMap>
#include <QByteArray>
#include <QVariant>
#include <QLabel>

class TabPage;
class Plugin;
class HandleWidget;
typedef struct _object PyObject;

/****************************************************************************/

class WidgetContainer:
    public QWidget
{
    Q_OBJECT

    public:
        WidgetContainer(TabPage *, Plugin *);
        ~WidgetContainer();

        TabPage *getTabPage() const { return tabPage; }
        const Plugin *getPlugin() const { return plugin; }
        QWidget *getWidget() const { return widget; }
        const SlotModel *getSlotModel() const { return &slotModel; }

        void adjustLeft(int);
        void adjustTop(int);
        void adjustWidth(int);
        void adjustHeight(int);
        void moveSelected(const QPoint &);
        void editModeChanged();

        void read(const QJsonObject &);
        void write(QJsonObject &) const;

        void connectDataSlots();
        void replaceUrl(const QUrl &, const QUrl &);
        bool uses(const QUrl &) const;

        void select();
        void deselect();
        bool isSelected() const { return selected; }

        bool setProperty(const QByteArray &, const QVariant &value);
        void resetProperty(const QByteArray &);
        bool hasProperty(const QByteArray &key) const {
            return properties.contains(key);
        }

        const WidgetContainer *duplicateSelected() const;

        void openEditor();

        void updateScript();
        void executeScript();
        void scriptVariablesChanged();

        void setLegend(bool);
        void legendMoved();

        static void registerPythonType();

    protected:
        void contextMenuEvent(QContextMenuEvent *);
        void dragEnterEvent(QDragEnterEvent *);
        void dragMoveEvent(QDragMoveEvent *);
        void dragLeaveEvent(QDragLeaveEvent *);
        void dropEvent(QDropEvent *);
        void moveEvent(QMoveEvent *);
        void resizeEvent(QResizeEvent *);

    private:
        TabPage * const tabPage;
        Plugin * const plugin;
        QWidget * const widget;
        HandleWidget * const handleWidget;
        void * const privateData;
        SlotModel slotModel;
        PyObject *pyObject;
        bool dragging;
        bool selected;
        QMap<QByteArray, QVariant> properties;
        ScriptVariableModel scriptVariables;
        QString script;
        PyObject *scriptModule;
        PyObject *scriptUpdate;
        QLabel scriptLabel;
        bool scriptWarning;
        Legend legend;
        bool showLegend;
        QPoint legendOffset;

        void updateHandleWidget();
        void updateScriptLabel();
        bool dropAcceptable(const QDropEvent *) const;
        void updateLegend();

        WidgetContainer();

    private slots:
        void actionDelete();
        void actionDisconnect();
        void actionAlignLeft();
        void actionAlignCenter();
        void actionAlignRight();
        void actionSendToBack();
        void actionBringToFront();
        void actionSlots();
        void actionStylesheet();
        void actionJump();
        void actionScript();
        void actionLegend();
        void scriptChanged();
};

/****************************************************************************/

#endif
