/*
    This file is part of Rocs.
    Copyright 2010  Tomaz Canabrava <tomaz.canabrava@gmail.com>
    Copyright 2010  Wagner Reck <wagner.reck@gmail.com>

    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, see <http://www.gnu.org/licenses/>.
*/

#include "GMLParser.h"

#include "Document.h"
#include "Pointer.h"
#include "DataStructure.h"
#include "GMLGraphParsingHelper.h"
#include "GMLGrammar.h"

#include <KAboutData>
#include <KGenericFactory>

#include <QFile>

static const KAboutData aboutdata("rocs_gmlplugin", 0, ki18n("Open and Save GML files") , "0.1");


extern Rocs::GMLPlugin::GMLGraphParsingHelper* phelper;

K_PLUGIN_FACTORY(FilePLuginFactory, registerPlugin< GMLParser>();)
K_EXPORT_PLUGIN(FilePLuginFactory(aboutdata))


GMLParser::~GMLParser()
{

}

GMLParser::GMLParser(QObject* parent, const QList< QVariant >&) :
    FilePluginInterface(FilePLuginFactory::componentData(), parent)
{

}

const QStringList GMLParser::extensions() const
{
    return QStringList()
           << i18n("*.gml|Graph Markup Language Files") + '\n';
}


Document* GMLParser::readFile(const QString& fileName)
{
    Document * graphDoc = new Document("Untitled");
//     Graph * graph = graphDoc->addGraph();
    QList < QPair<QString, QString> > edges;
    QFile f(fileName);
    if (!f.open(QIODevice::ReadOnly | QIODevice::Text)) {
        setError(i18n("Cannot open the file: %1. Error %2", fileName, f.errorString()));
        delete graphDoc;
        return 0;
    }
    QString content = f.readAll();
    if (!Rocs::GMLPlugin::parse(content, graphDoc)) {
        setError(i18n("cannot parse the file %1.", fileName));
        delete graphDoc;
        return 0;
    }
    return graphDoc;
}



bool GMLParser::writeFile(Document& graph, const QString& filename)
{
    QFile file(filename);
    QVariantList subgraphs;
    if (file.open(QFile::WriteOnly | QFile::Text)) {
        QTextStream out(&file);
        out << "Version 1\n";
        out << "Vendor \"Rocs\"\n";
        for (int i = 0 ; i < graph.dataStructures().count(); ++i) {
            DataStructurePtr g = graph.dataStructures().at(i);
//         Graph *g = graph.activeGraph();
//FIXME uncommented following directed() check sind this is moved to subclass
//need to add toggle
//             out << QString("graph [\n directed %1 \n").arg(g->directed()?"1":"0");
            out << QString("id \"%1\" \n").arg(g->name());

            foreach(DataPtr n, g->dataList()) {
                out << QString("node [\n id \"%1\" \n").arg(n->name());
//                 foreach (QByteArray p, n->dynamicPropertyNames()){
//                    out << p << " " << n->property(p).toString() << "\n";
//                  }
                out << processNode(n);
                out << "]\n";

            }
            foreach(PointerPtr e, g->pointers()) {
                out << "edge [\n";
//                  foreach (QByteArray p, e->dynamicPropertyNames()){
//                    out << p << " " << e->property(p).toString() << "\n";
//                  }
                out << processEdge(e);

                out << "]\n";
            }
            out << "]\n";
        }
        return true;
    }
    setError(i18n("Cannot open file %1 to write document. Error: %2", filename, file.errorString()));
    return false;
}

QString const GMLParser::processEdge(PointerPtr e) const
{
    QString edge;
    edge.append(QString("source \"%1\"\n target \"%2\"\n").arg(e->from()->name(), e->to()->name()));
    if (!e->name().isEmpty()) {
        edge.append(QString(" id \"%1\"\n").arg(e->name()));
    }
    edge.append(QString(" width \"%1\"\n").arg(e->width()));
//     edge.append (QString(" color \"%1\"\n").arg(e->color())); //Problem with comments (both starts by '#')
    edge.append(QString(" value \"%1\"\n").arg(e->value()));


    foreach(const QByteArray& p, e->dynamicPropertyNames()) {
        edge.append(QString("%1 %2\n").arg(QString(p)).arg(e->property(p).toString()));
    }

    return edge;
}

QString const GMLParser::processNode(DataPtr n) const
{
    QString node;
    node.append(QString("  x %1 \n  y %2 \n").arg(n->x()).arg(n->y()));
    node.append(QString(" width %1\n").arg(n->width()));
//       node.append (QString(" color \"%1\"\n").arg(n->color())); //Problem with comments (both starts by '#')
    node.append(QString(" value \"%1\"\n").arg(n->value().toString()));
    node.append(QString(" iconPackage \"%1\"\n").arg(n->iconPackage()));
    node.append(QString(" icon \"%1\"\n").arg(n->icon()));

    foreach(const QByteArray& p, n->dynamicPropertyNames()) {
        QString s = p ;

        node.append(QString("%1 \"%2\"\n").arg(s.replace('.', '_')).arg(n->property(p).toString()));
    }

    return node;
}

const QString GMLParser::lastError()
{
    return _lastError;
}


void GMLParser::setError(QString arg1)
{
    _lastError = arg1;
}

const QString GMLParser::scriptToRun()
{
    return QString(/*"include ( arrangeNodes.js )\n"
                     "for (g = 0; g < graphs.length; ++g){\n"
                     "  nodes = graphs[g].list_nodes();\n"
                     "  for (var i = 0; i < nodes.length; i++){\n"
                     "    nodes[i].addDynamicProperty(\"NodeName\", nodes[i].name);\n"
                     "    if (nodes[i].label != undefined)\n"
                     "       nodes[i].name = nodes[i].label;\n"
                     "  }\n"
                     "}"*/
           );
}


#include "GMLParser.moc"
