/***************************************************************
QGVCore
Copyright (c) 2014, Bergont Nicolas, All rights reserved.

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3.0 of the License, or (at your option) any later version.

This library 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
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library.
***************************************************************/

#ifndef QGVCORE_H
#define QGVCORE_H

#include <QPointF>
#include <QPolygonF>
#include <QPainterPath>
#include <QColor>

//GraphViz headers
#include <gvc.h>
#include <cgraph.h>

const qreal DotDefaultDPI = 72.0;

/**
 * @brief GraphViz to GraphicsScene conversions
 *
 */
class QGVCore
{
public:
    static qreal graphHeight(Agraph_t *graph);
    static QPointF toPoint(pointf p, qreal gheight);
    static QPointF toPoint(point p, qreal gheight);
    static QPointF centerToOrigin(const QPointF &p, qreal width, qreal height);
    static QPolygonF toPolygon(const polygon_t* poly, qreal width, qreal height);

    static QPainterPath toPath(const char *type, const polygon_t *poly, qreal width, qreal height);
    static QPainterPath toPath(const splines* spl, qreal gheight);

    static Qt::BrushStyle toBrushStyle(const QString &style);
    static Qt::PenStyle toPenStyle(const QString &style);
    static QColor toColor(const QString &color);

    typedef struct {
        const char *data;
        int len;
        int cur;
    } rdr_t;

    static int memiofread(void *chan, char *buf, int bufsize)
    {
        const char *ptr;
        char *optr;
        char c;
        int l;
        rdr_t *s;

        if (bufsize == 0) return 0;
        s = (rdr_t *) chan;
        if (s->cur >= s->len)
            return 0;
        l = 0;
        ptr = s->data + s->cur;
        optr = buf;
        do {
            *optr++ = c = *ptr++;
            l++;
        } while (c && (c != '\n') && (l < bufsize));
        s->cur += l;
        return l;
    }

    static Agraph_t *agmemread2(const char *cp)
    {
        Agraph_t* g;
        rdr_t rdr;
        Agdisc_t disc;
        Agiodisc_t memIoDisc;

        memIoDisc.afread = memiofread;
        memIoDisc.putstr = AgIoDisc.putstr;
        memIoDisc.flush = AgIoDisc.flush;
        rdr.data = cp;
        rdr.len = strlen(cp);
        rdr.cur = 0;

        disc.mem = &AgMemDisc;
        disc.id = &AgIdDisc;
        disc.io = &memIoDisc;
        g = agread (&rdr, &disc);
        return g;
    }
};

#endif // QGVCORE_H
