/***************************************************************************
 *   Copyright (C) 2006-2009 by Rajko Albrecht                             *
 *   ral@alwins-world.de                                                   *
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 *   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, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
 ***************************************************************************/
#include "graphtreelabel.h"
#include "graphtree_defines.h"

#include <QStyleOptionGraphicsItem>
#include <QPainter>
#include <QPixmap>

GraphTreeLabel::GraphTreeLabel(const QString &text, const QString &_nodename, const QRectF &r, QGraphicsItem *p)
    : QGraphicsRectItem(r, p), StoredDrawParams(), m_Nodename(_nodename), m_SourceNode()
{
    m_Nodename = _nodename;
    setText(0, text);
    setPosition(0, DrawParams::TopCenter);
    drawFrame(true);
}

GraphTreeLabel::~GraphTreeLabel()
{
}

const QString &GraphTreeLabel::nodename()const
{
    return m_Nodename;
}

int GraphTreeLabel::type()const
{
    return GRAPHTREE_LABEL;
}

void GraphTreeLabel::setBgColor(const QColor &c)
{
    _backColor = c;
}

void GraphTreeLabel::paint(QPainter *p, const QStyleOptionGraphicsItem *option, QWidget *)
{
    Q_UNUSED(option);
    QRect r = rect().toRect();

    RectDrawing d(r);
    d.drawBack(p, this);
    d.drawField(p, 0, this);
    d.drawField(p, 1, this);
}

void GraphTreeLabel::setSelected(bool s)
{
    QGraphicsItem::setSelected(s);
    StoredDrawParams::setSelected(s);
    update();
}

const QString &GraphTreeLabel::source()const
{
    return m_SourceNode;
}

void GraphTreeLabel::setSource(const QString &_s)
{
    m_SourceNode = _s;
}

GraphEdge::GraphEdge(QGraphicsItem *c)
    : QGraphicsPathItem(c)
{
}

GraphEdge::~GraphEdge()
{
}

void GraphEdge::paint(QPainter *p, const QStyleOptionGraphicsItem *options, QWidget *)
{
    Q_UNUSED(options);
    p->save();
    p->setRenderHint(QPainter::Antialiasing);

    QPen pen = QPen(Qt::black);
    pen.setWidthF(1.0);
    p->setPen(pen);
    p->drawPath(path());
    p->restore();
}

const QPolygonF &GraphEdge::controlPoints()const
{
    return _points;
}

void GraphEdge::setControlPoints(const QPolygonF &pa)
{
    _points = pa;

    QPainterPath path;
    path.moveTo(pa[0]);
    for (int i = 1; i < pa.size(); i += 3) {
        path.cubicTo(pa[i], pa[(i + 1) % pa.size()], pa[(i + 2) % pa.size()]);
    }

    setPath(path);
}

int GraphEdge::type()const
{
    return GRAPHTREE_LINE;
}

GraphEdgeArrow::GraphEdgeArrow(GraphEdge *_parent, QGraphicsItem *p)
    : QGraphicsPolygonItem(p), _edge(_parent)
{
}

void GraphEdgeArrow::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *)
{
    p->save();
    p->setRenderHint(QPainter::Antialiasing);
    p->setBrush(Qt::black);
    p->drawPolygon(polygon(), Qt::OddEvenFill);
    p->restore();
}

int GraphEdgeArrow::type()const
{
    return GRAPHTREE_ARROW;
}

GraphEdge *GraphEdgeArrow::edge()
{
    return _edge;
}

/* taken from KCacheGrind project */
QPixmap *GraphMark::_p = 0;

GraphMark::GraphMark(GraphTreeLabel *n, QGraphicsItem *p)
    : QGraphicsRectItem(p)
{
    if (!_p) {

        int d = 5;
        float v1 = 130.0f, v2 = 10.0f, v = v1, f = 1.03f;

        // calculate pix size
        QRect r(0, 0, 30, 30);
        while (v > v2) {
            r.setRect(r.x() - d, r.y() - d, r.width() + 2 * d, r.height() + 2 * d);
            v /= f;
        }

        _p = new QPixmap(r.size());
        _p->fill(Qt::white);
        QPainter p(_p);
        p.setPen(Qt::NoPen);

        r.translate(-r.x(), -r.y());

        while (v < v1) {
            v *= f;
            p.setBrush(QColor(265 - (int)v, 265 - (int)v, 265 - (int)v));

            p.drawRect(QRect(r.x(), r.y(), r.width(), d));
            p.drawRect(QRect(r.x(), r.bottom() - d, r.width(), d));
            p.drawRect(QRect(r.x(), r.y() + d, d, r.height() - 2 * d));
            p.drawRect(QRect(r.right() - d, r.y() + d, d, r.height() - 2 * d));

            r.setRect(r.x() + d, r.y() + d, r.width() - 2 * d, r.height() - 2 * d);
        }
    }

    setRect(QRectF(n->rect().center().x() - _p->width() / 2,
                   n->rect().center().y() - _p->height() / 2, _p->width(), _p->height()));
}

GraphMark::~ GraphMark()
{
}

bool GraphMark::hit(const QPoint &)const
{
    return false;
}

int GraphMark::type()const
{
    return GRAPHTREE_MARK;
}

void GraphMark::paint(QPainter *p, const QStyleOptionGraphicsItem *option, QWidget *)
{
    if (option->levelOfDetail < .5) {
        QRadialGradient g(rect().center(), rect().width() / 3);
        g.setColorAt(0.0, Qt::gray);
        g.setColorAt(1.0, Qt::white);

        p->setBrush(QBrush(g));
        p->setPen(Qt::NoPen);
        p->drawRect(rect());
        return;
    }

    p->drawPixmap(int(rect().x()), int(rect().y()), *_p);
}
