#include <GraphvizIntegrator.hpp>

#include <graphviz/gvc.h>

QString selectFormat(GraphvizIntegrator::PictureFormat format) {
    switch (format) {
        case GraphvizIntegrator::PictureFormat::PNG:
            return "png";
        case GraphvizIntegrator::PictureFormat::SVG:
            return "svg";
    }

    throw std::logic_error ( "Invalid picture format." );
}

namespace GraphvizIntegrator {

    QImage createImage(const QString &dotData, PictureFormat format) {
        char *result;
        unsigned int len;

        QImage img;
        Agraph_t *G;
        GVC_t *gvc;
        gvc = gvContext();
        G = agmemread(dotData.toLatin1().data());
        if (!G)
            return img;
        gvLayout(gvc, G, "dot");
        gvRenderData(gvc, G, selectFormat(format).toLatin1(), &result, &len);
        gvFreeLayout(gvc, G);
        agclose(G);

        img.loadFromData((uchar *) result, (int) len);
        return img;
    }

    bool createImageFile(const QString &dotData, QString filename, PictureFormat format) {
        Agraph_t *G;
        GVC_t *gvc;
        gvc = gvContext();
        G = agmemread(dotData.toLatin1().data());
        if (!G)
            return false;
        gvLayout(gvc, G, "dot");
        gvRenderFilename(gvc, G, selectFormat(format).toLatin1(), filename.toLatin1());
        gvFreeLayout(gvc, G);
        agclose(G);
        return true;
    }


    PictureFormat formatFromFilename(const QString& format) {
        if (format.endsWith("svg"))
            return SVG;
        if (format.endsWith("png"))
            return PNG;
        throw std::runtime_error { "Failed to determine output format from filename." };
    }
}
