/***************************************************************************
 *   Copyright 2007-2008 Wouter Haffmans <cheetah@simply-life.net>         *
 *                                                                         *
 *   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) version 3 or any later version        *
 *   accepted by the membership of KDE e.V. (or its successor approved     *
 *   by the membership of KDE e.V.), which shall act as a proxy            *
 *   defined in Section 14 of version 3 of the license.                    *
 *                                                                         *
 *   This program 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 this program.  If not, see <http://www.gnu.org/licenses/>. *
 ***************************************************************************/

#include "graphicslinesitem.h"

#include <QPainterPath>
#include <QPointF>
#include <QVector>
#include <QPen>
#include <QPainter>
#include <QtDebug>

GraphicsLinesItem::GraphicsLinesItem(QGraphicsItem *parent)
 : QAbstractGraphicsShapeItem(parent)
{
    m_tag = 0;
}

GraphicsLinesItem::GraphicsLinesItem(const QVector<QPointF> points,
        QGraphicsItem *parent)
 : QAbstractGraphicsShapeItem(parent)
{
    m_tag = 0;
    setPoints(points);
}

GraphicsLinesItem::GraphicsLinesItem(const QPointF point,
        QGraphicsItem *parent)
 : QAbstractGraphicsShapeItem(parent)
{
    QVector<QPointF> points;
    points.append(point);
    setPoints(points);
}

GraphicsLinesItem::~GraphicsLinesItem()
{
}

QVector<QPointF> GraphicsLinesItem::points() const
{
    return m_points;
}

void GraphicsLinesItem::setPoints(QVector<QPointF> points)
{
    // Reset points/path
    m_points = QVector<QPointF>();
    m_path = QPainterPath();
    m_boundingRect = QRectF();

    // Add points
    Q_FOREACH(const QPointF &point, points) {
        addPoint(point);
    }
}

void GraphicsLinesItem::addPoint(QPointF point) {
    // Base line
    QPointF previous;

    if (m_points.count() > 0) {
        previous = m_points.at(m_points.count() - 1);
    }
    else {
        previous = point;
    }

    QLineF line(previous, point);
    if (pen().style() != Qt::NoPen && pen().capStyle() != Qt::FlatCap) {
        // Extend line to real end points (add cap)
        qreal length = line.length() + pen().widthF();
        line.setLength(-(pen().widthF() / 2));
        line = QLineF(line.p2(), line.p1());
        line.setLength(length);
    }

    // Create two (long) sides of the rectangle
    QLineF side1 = line;
    QLineF side2 = line;

    // Translate to either side by line width
    QLineF base = line.normalVector();
    base.setLength(pen().widthF() / 2);
    side1.translate(base.dx(), base.dy());
    side2.translate(-base.dx(), -base.dy());

    // Actually create polygon and add to path
    QPolygonF linePoly;
    m_path.moveTo(side1.p1());
    linePoly.append(side1.p1());
    linePoly.append(side1.p2());
    linePoly.append(side2.p2());
    linePoly.append(side2.p1());
    m_path.addPolygon(linePoly);


    // Expand bounding box if necessary
    if (!m_boundingRect.contains(point)) {
        m_boundingRect = m_path.boundingRect();
    }
    m_points.append(point);

    // Update ourselves, scene, etc
    update(linePoly.boundingRect());
}

void GraphicsLinesItem::paint(QPainter *painter,
        const QStyleOptionGraphicsItem *, QWidget *)
{
    if (points().count() > 0) {
        painter->setPen(pen());
        QPointF previous = points().at(0);
        QVector<QPointF>::const_iterator i;
        for (i = points().constBegin(); i != points().constEnd(); ++i) {
            painter->drawLine(previous, *i);
            previous = *i;
        }
    }
}

QPainterPath GraphicsLinesItem::shape() const
{
    return m_path;
}

QRectF GraphicsLinesItem::boundingRect() const
{
    return m_boundingRect;
}

qint16 GraphicsLinesItem::tag() const
{
    return m_tag;
}

void GraphicsLinesItem::setTag(qint16 tag)
{
    m_tag = tag;
}
