/***************************************************************************
 *   This program 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 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   copyright (C) 2002-2020                                               *
 *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
 ***************************************************************************/

#ifndef OBJECTWIDGET_H
#define OBJECTWIDGET_H

#include "messagewidgetlist.h"
#include "umlwidget.h"

class MessageWidget;
class SeqLineWidget;
class UMLScene;

/**
 * Displays an instance UMLObject of a concept.
 *
 * The local ID is needed as it can represent a class
 * that has many objects representing it.
 *
 * @short Displays an instance of a Concept.
 * @author Paul Hensgen <phensgen@techie.com>
 * @see UMLWidget
 * Bugs and comments to umbrello-devel@kde.org or https://bugs.kde.org
 */
class ObjectWidget : public UMLWidget
{
    Q_OBJECT
public:
    ObjectWidget(UMLScene *scene, UMLObject *o);
    virtual ~ObjectWidget();

    virtual void setX(qreal x);
    virtual void setY(qreal y);

    qreal centerX();

    void setMultipleInstance(bool multiple);
    bool multipleInstance() const;

    void setSelected(bool state);

    virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);

    bool activate(IDChangeLog* ChangeLog = 0);

    void cleanup();

    virtual bool showPropertiesDialog();

    void setDrawAsActor(bool drawAsActor);
    bool drawAsActor() const;

    void setShowDestruction(bool bShow);
    bool showDestruction() const;

    int topMargin();

    void setEndLine(int yPosition);
    int getEndLineY();

    void messageAdded(MessageWidget* message);
    void messageRemoved(MessageWidget* message);

    bool canTabUp();

    bool messageOverlap(qreal y, MessageWidget* messageWidget);

    virtual void setLineColorCmd(const QColor &color);

    SeqLineWidget *sequentialLine() const;

    virtual void resizeWidget(qreal newW, qreal newH);

    virtual void saveToXMI1(QDomDocument& qDoc, QDomElement& qElement);
    virtual bool loadFromXMI1(QDomElement& qElement);

public slots:
    void slotMenuSelection(QAction* action);
    virtual void slotFillColorChanged(Uml::ID::Type viewID);
    void slotMessageMoved();

protected:
    virtual void mousePressEvent(QGraphicsSceneMouseEvent *me);
    virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *me);

    QSizeF minimumSize() const;

    virtual void moveEvent(QGraphicsSceneMouseEvent *event);
    virtual void moveWidgetBy(qreal diffX, qreal diffY);
    virtual void constrainMovementForAllWidgets(qreal &diffX, qreal &diffY);

    virtual QCursor resizeCursor() const;

    void paintActor(QPainter *p);
    void paintObject(QPainter *p);

private:
    void tabUp();
    void tabDown();

    void moveDestructionBy(qreal diffY);

    SeqLineWidget* m_pLine;
    bool m_multipleInstance;   ///< draw an object as a multiple object
    bool m_drawAsActor;        ///< object should be drawn as an Actor or an Object
    bool m_showDestruction;    ///< show object destruction on sequence diagram line
    bool m_isOnDestructionBox;  ///< true when a click occurred on the destruction box
    MessageWidgetList m_messages;   ///< message widgets with an end on this widget

    friend class SeqLineWidget;
};

#endif
