/****************************************************************************
 ** Copyright (C) 2001-2006 Klarälvdalens Datakonsult AB.  All rights reserved.
 **
 ** This file is part of the KD Gantt library.
 **
 ** This file may be distributed and/or modified under the terms of the
 ** GNU General Public License version 2 as published by the Free Software
 ** Foundation and appearing in the file LICENSE.GPL included in the
 ** packaging of this file.
 **
 ** Licensees holding valid commercial KD Gantt licenses may use this file in
 ** accordance with the KD Gantt Commercial License Agreement provided with
 ** the Software.
 **
 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 **
 ** See http://www.kdab.net/kdgantt for
 **   information about KD Gantt Commercial License Agreements.
 **
 ** Contact info@kdab.net if any conditions of this
 ** licensing are not clear to you.
 **
 **********************************************************************/
#ifndef KDGANTTGRAPHICSITEM_H
#define KDGANTTGRAPHICSITEM_H

#include "kdganttglobal.h"
#include "kdganttstyleoptionganttitem.h"

#include <QGraphicsItem>
#include <QDateTime>
#include <QPersistentModelIndex>

class QGraphicsLineItem;

namespace KDGantt
{
class GraphicsScene;
class ConstraintGraphicsItem;

/* Can we fit every kind of item into one gfxitem class? */
class GraphicsItem : public QGraphicsItem
{
public:
    enum { Type = UserType + 42 };

    explicit GraphicsItem(QGraphicsItem *parent = Q_NULLPTR, GraphicsScene *scene = Q_NULLPTR);
    explicit GraphicsItem(const QModelIndex &idx, QGraphicsItem *parent = Q_NULLPTR, GraphicsScene *scene = Q_NULLPTR);
    virtual ~GraphicsItem();

    int type() const Q_DECL_OVERRIDE;
    /*reimp (non-virtual)*/ GraphicsScene *scene() const;

    void updateItem(const Span &rowgeometry, const QPersistentModelIndex &idx);

    //virtual ItemType itemType() const = 0;

    //qreal dateTimeToSceneX( const QDateTime& dt ) const;
    //QDateTime sceneXtoDateTime( qreal x ) const;

    QRectF rect() const
    {
        return m_rect;
    }
    void setRect(const QRectF &r);
    void setBoundingRect(const QRectF &r);

    virtual QString ganttToolTip() const;

    const QPersistentModelIndex &index() const
    {
        return m_index;
    }
    void setIndex(const QPersistentModelIndex &idx);

    bool isEditable() const;
    bool isUpdating() const
    {
        return m_isupdating;
    }

    void addStartConstraint(ConstraintGraphicsItem *);
    void addEndConstraint(ConstraintGraphicsItem *);
    void removeStartConstraint(ConstraintGraphicsItem *);
    void removeEndConstraint(ConstraintGraphicsItem *);
    QList<ConstraintGraphicsItem *> startConstraints() const
    {
        return m_startConstraints;
    }
    QList<ConstraintGraphicsItem *> endConstraints() const
    {
        return m_endConstraints;
    }

    QRectF boundingRect() const Q_DECL_OVERRIDE;
    /*reimp*/ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
                         QWidget *widget = Q_NULLPTR) Q_DECL_OVERRIDE;

    QVariant itemChange(GraphicsItemChange, const QVariant &value) Q_DECL_OVERRIDE;
protected:
    void focusInEvent(QFocusEvent *event) Q_DECL_OVERRIDE;
    void hoverMoveEvent(QGraphicsSceneHoverEvent *) Q_DECL_OVERRIDE;
    void hoverLeaveEvent(QGraphicsSceneHoverEvent *) Q_DECL_OVERRIDE;
    void mousePressEvent(QGraphicsSceneMouseEvent *) Q_DECL_OVERRIDE;
    void mouseReleaseEvent(QGraphicsSceneMouseEvent *) Q_DECL_OVERRIDE;
    void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *) Q_DECL_OVERRIDE;
    void mouseMoveEvent(QGraphicsSceneMouseEvent *) Q_DECL_OVERRIDE;

private:
    void init();

    QPointF startConnector() const;
    QPointF endConnector() const;
    void updateConstraintItems();
    StyleOptionGanttItem getStyleOption() const;
    void updateModel();
    void updateItemFromMouse(const QPointF &scenepos);
    void constraintsChanged();

    QRectF m_rect;
    QRectF m_boundingrect;
    QPersistentModelIndex m_index;
    bool m_isupdating;
    int m_istate;
    QPointF m_presspos;
    QPointF m_pressscenepos;
    QGraphicsLineItem *m_dragline;
    QList<ConstraintGraphicsItem *> m_startConstraints;
    QList<ConstraintGraphicsItem *> m_endConstraints;
};
}

#endif /* KDGANTTGRAPHICSITEM_H */

