/***************************************************************************
    Copyright 2010 Daniel Laidig <laidig@kde.org>
    Copyright 2009 Alexander Rieder <alexanderrieder@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.                                   *
 *                                                                         *
 ***************************************************************************/

#include "latexrenderer.h"

#include <klocale.h>
#include <kdebug.h>
#include <ktemporaryfile.h>
#include <kstandarddirs.h>
#include <kprocess.h>

#include <QLabel>
#include <QProcess>
#include <QFileInfo>
#include <QColor>
#include <complex>

using namespace Practice;

const char* texTemplate = "\\documentclass[12pt,fleqn]{article}          \n "\
                          "\\usepackage{latexsym,amsfonts,amssymb,ulem}  \n "\
                          "\\usepackage[dvips]{graphicx}                 \n "\
                          "\\setlength\\textwidth{5in}                   \n "\
                          "\\setlength{\\parindent}{0pt}                 \n "\
                          "\\usepackage{amsmath}                         \n "\
                          "\\usepackage{color}                           \n "\
                          "\\pagestyle{empty}                            \n "\
                          "\\begin{document}                             \n "\
                          "{\\definecolor{mycolor}{rgb}{%1}              \n "\
                          "{\\color{mycolor}                             \n "\
                          "%2 }                                          \n "\
                          "\\end{document}\n";

LatexRenderer::LatexRenderer(QObject* parent)
    : QObject(parent), m_label(0)
{

}

void LatexRenderer::renderLatex(QString tex)
{
    if (m_label) {
        m_label->setText(i18n("Rendering..."));
        m_label->setToolTip(tex);
    }

    if (tex.startsWith(QLatin1String("$$"))) {
        tex.replace(0, 2, "\\begin{eqnarray*}").remove(-2, 2).append("\\end{eqnarray*}");
    } else {
        tex.remove(0, 2).remove(-2, 2);
    }
    kDebug() << "rendering as latex";

    QString dir = KGlobal::dirs()->saveLocation("tmp", "parley/");

    //Check if the parley subdir exists, if not, create it
    KTemporaryFile *texFile = new KTemporaryFile();
    texFile->setPrefix("parley/");
    texFile->setSuffix(".tex");
    texFile->open();

    QColor color = m_label->palette().color(QPalette::WindowText);
    QString colorString = QString::number(color.redF()) + ','
                          + QString::number(color.greenF()) + ','
                          + QString::number(color.blueF());
    QString expressionTex = QString(texTemplate).arg(colorString, tex.trimmed());

    texFile->write(expressionTex.toUtf8());
    texFile->flush();

    QString fileName = texFile->fileName();
    kDebug() << "fileName: " << fileName;
    m_latexFilename = fileName;
    m_latexFilename.replace(".tex", ".eps");
    KProcess *p = new KProcess(this);
    p->setWorkingDirectory(dir);

    (*p) << "latex" << "-interaction=batchmode" << "-halt-on-error" << fileName;

    connect(p, SIGNAL(finished(int,  QProcess::ExitStatus)), this, SLOT(convertToPs()));
    connect(p, SIGNAL(error(QProcess::ProcessError)), this, SLOT(latexRendered()));
    p->start();
}

bool LatexRenderer::isLatex(const QString& tex)
{
    return tex.length() > 4 && tex.mid(2, tex.length() - 4).simplified().length() > 0 &&
           ((tex.startsWith(QLatin1String("$$")) && tex.endsWith(QLatin1String("$$"))) ||
            (tex.startsWith(QString::fromUtf8("§§")) && tex.endsWith(QString::fromUtf8("§§"))));
}

void LatexRenderer::convertToPs()
{
    kDebug() << "converting to ps";
    QString dviFile = m_latexFilename;
    dviFile.replace(".eps", ".dvi");
    KProcess *p = new KProcess(this);
    kDebug() << "running: " << "dvips" << "-E" << "-o" << m_latexFilename << dviFile;
    (*p) << "dvips" << "-E" << "-o" << m_latexFilename << dviFile;

    connect(p, SIGNAL(finished(int,  QProcess::ExitStatus)), this, SLOT(convertToImage()));
    connect(p, SIGNAL(error(QProcess::ProcessError)), this, SLOT(latexRendered()));
    p->start();
}

void LatexRenderer::convertToImage()
{
    kDebug() << "converting to ps";
    QString pngFile = m_latexFilename;
    pngFile.replace(".eps", ".png");
    KProcess *p = new KProcess(this);
    kDebug() << "running:" << "convert" << m_latexFilename << pngFile;
    (*p) << "convert" << "-density" << "85" << m_latexFilename << pngFile;

    connect(p, SIGNAL(finished(int,  QProcess::ExitStatus)), this, SLOT(latexRendered()));
    connect(p, SIGNAL(error(QProcess::ProcessError)), this, SLOT(latexRendered()));
    p->start();
}

void LatexRenderer::latexRendered()
{
    kDebug() << "rendered file " << m_latexFilename;

    QString pngFile = m_latexFilename;
    pngFile.replace(".eps", ".png");
    if (QFileInfo(pngFile).exists()) {
        QPixmap pixmap(pngFile);
        m_label->setPixmap(pixmap);
        m_label->setMinimumSize(pixmap.size().boundedTo(QSize(600, 300)));
    } else {
        m_label->setText(i18n("LaTeX error.")); //TODO: better error handling and error messages
    }

    //cleanup the temp directory a bit...
    QString dir = KGlobal::dirs()->saveLocation("tmp", "parley/");
    QStringList extensions;
    extensions << ".log" << ".aux" << ".tex" << ".dvi" << ".eps" << ".png";
    foreach(const QString & ext, extensions) {
        QString s = m_latexFilename;
        s.replace(".eps", ext);
        QFile f(s);
        f.remove();
    }
}

#include "latexrenderer.moc"
