//  Copyright (2010-2013) Cédric Coussinet (cedric.coussinet@nomoseed.net)
//
//  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 3 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 <QtWebKit/QWebFrame>
#include <QtGui/QMessageBox>
#include <QtGui/QFileDialog>
#include <QLocale>
#include <QSettings>
#include <QDirIterator>

#include <QTextCodec>

#include "reception.h"
#include "xsltprocessor.h"

QString item(const QString value, const QString label){
    return "<item value=\"" + value + "\" label=\"" + label + "\" />";
}

Reception::Reception (QMainWindow * mainWindow, QWebView * webView)
{
    this->mainWindow = mainWindow;
    this->webView = webView;

    QWebFrame *webFrame = webView->page()->mainFrame();
    webFrame->setScrollBarPolicy(Qt::Horizontal, Qt::ScrollBarAlwaysOff);
    webFrame->setScrollBarPolicy(Qt::Vertical, Qt::ScrollBarAlwaysOff);

    this->projectFormalism = "none";
    this->projectType = uni;

    const QByteArray open(QString("\""+tr("Open")+"\"").toUtf8());
    const QByteArray create(QString("\""+tr("Create")+"\"").toUtf8());
    const QByteArray unit(QString("\""+tr("Unit")+"\"").toUtf8());
    const QByteArray map(QString("\""+tr("Map")+"\"").toUtf8());
    const QByteArray inference_engine(QString("\""+tr("Inference engine")+"\"").toUtf8());
    const QByteArray model(QString("\""+tr("Model")+"\"").toUtf8());
    const QByteArray knowledge_base(QString("\""+tr("Knowledge base")+"\"").toUtf8());
    const QByteArray program(QString("\""+tr("Program")+"\"").toUtf8());
    const QByteArray warning(QString("\""+tr("The project name must begin with a letter possibly followed by any alphanumeric characters or underscores.")+"\"").toUtf8());
    const QByteArray name(QString("\""+tr("Name of project")+"\"").toUtf8());
    const QByteArray location(QString("\""+tr("Choose location")+"\"").toUtf8());
    const QByteArray legalNotice(QString("\""+tr("Copyright Cedric Coussinet (2013) - All right reserved - GPL Edition")+"\"").toUtf8());
    const QByteArray project(QString("\""+tr("A project")+"\"").toUtf8());
    const QByteArray database(QString("\""+tr("A database")+"\"").toUtf8());

    const char * params[29];
    params[0]="open";
    params[1]= open.constData();
    params[2]="create";
    params[3]= create.constData();
    params[4]="unit";
    params[5]= unit.constData();
    params[6]="map";
    params[7]= map.constData();
    params[8]="inference_engine";
    params[9]= inference_engine.constData();
    params[10]="model";
    params[11]= model.constData();
    params[12]="knowledge_base";
    params[13]= knowledge_base.constData();
    params[14]="program";
    params[15]= program.constData();
    params[16]="warning";
    params[17]= warning.constData();
    params[18]="name";
    params[19]= name.constData();
    params[20]="location";
    params[21]= location.constData();
    params[22]="legalNotice";
    params[23]= legalNotice.constData();
    params[24]="project";
    params[25]= project.constData();
    params[26]="database";
    params[27]= database.constData();
    params[28]=NULL;

    QString reception= "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\"?><reception xmlns=\"http://www.nomoseed.org/nomosdk\">";
    reception.append("<formalism>");
    QDirIterator formalismsDir("formalisms", QDir::Dirs | QDir::NoSymLinks | QDir::NoDotAndDotDot);
    QString formalism;
    QString formalismName;
    QFile csv;
    QString line;
    const QLocale locale = dynamic_cast<MainWindow*>(this->mainWindow)->getLocale();
    const QString localeName = QLocale::languageToString(QLocale(locale).language());
    const QString localeID = locale.name().split('_')[0];
    while(formalismsDir.hasNext())
    {
        formalism = formalismsDir.next();
        formalismName = formalism;
        csv.setFileName(formalism+"/name.csv");
        formalism = formalism.split('/').last();
        formalismName = formalism;
        if (csv.open(QFile::ReadOnly)){
            line = csv.readLine();
            line = csv.readLine();
            while (line.split(",")[0] != localeID && !line.isEmpty()){
                line = csv.readLine();
            }
            if (line.split(",")[0] == localeID)
                formalismName = line.split(",")[1];
        }
        csv.close();
        reception.append(item(formalism, formalismName));
    }
    reception.append("</formalism>");

    reception.append("<language>");
    reception.append(item(localeID, localeName));
    QStringList qmFilter;
    qmFilter << "*.qm";
    QDirIterator translationsDir("translations", qmFilter,QDir::Files | QDir::NoSymLinks);
    QString language;
    while(translationsDir.hasNext())
    {
        language = translationsDir.next().section("_",1).split(".")[0];
        if (language != localeID)
            reception.append(item(language, QLocale::languageToString(QLocale(language).language())));
    }
    reception.append("</language></reception>");

    const QByteArray out = XSLTProcessor::transform(QByteArray("web/reception/reception.xsl"), reception, params);

    QByteArray url(QDir::currentPath().toUtf8());
    url.append("/web/reception/reception.xhtml");

    QObject::connect(webView->page()->mainFrame(), SIGNAL(javaScriptWindowObjectCleared()),this, SLOT(populateJavaScriptWindowObject()));

    webView->setContent( out, "application/xhtml+xml", QUrl::fromLocalFile(url));
}

Reception::~Reception (){}

void Reception::openProject ()
{
    dynamic_cast<MainWindow*>(mainWindow)->selectProject();
}

void Reception::openDatabase ()
{
    QFileDialog dialog(mainWindow, tr("Choose a directory..."), ".", ".");
    dialog.setWindowState(Qt::WindowNoState);
    dialog.setWindowFlags(Qt::Window | Qt::WindowTitleHint | Qt::WindowCloseButtonHint);
    dialog.setFileMode(QFileDialog::Directory);
    dialog.setViewMode(QFileDialog::Detail);
    dialog.setOptions(QFileDialog::DontUseNativeDialog);
    if (dialog.exec())
        dynamic_cast<MainWindow*>(mainWindow)->openLogging(dialog.directory().absolutePath());

}

void Reception::changeLanguage (QString languageName)
{
    QSettings settings;
    settings.setValue("Locale", QLocale(languageName).name());
    QMessageBox::information(mainWindow, tr("Restart required"), tr("The language change will take effect after a restart of nomoSDK."));
}

void Reception::setProjectType (const QString projectType)
{
    this->projectType = toProjectType(projectType);
    if (this->projectType == error){
        this->projectType = prg;
        this->projectFormalism = projectType;
    }
    else
        this->projectFormalism = "none";
}

void Reception::setProjectName (const QString projectName)
{
    this->projectName = projectName;
}

void Reception::chooseProjectLocation ()
{
    QFileDialog dialog(mainWindow, tr("Choose a directory..."), ".", ".");
    dialog.setWindowState(Qt::WindowNoState);
    dialog.setWindowFlags(Qt::Window | Qt::WindowTitleHint | Qt::WindowCloseButtonHint);
    dialog.setFileMode(QFileDialog::Directory);
    dialog.setViewMode(QFileDialog::Detail);
    dialog.setOptions(QFileDialog::DontUseNativeDialog);
    QString projectPath;
    if (dialog.exec())
    {
        projectPath = dialog.directory().absoluteFilePath(projectName + toQString(projectType));
        int isValid = QMessageBox::Yes;
        if (QFile::exists(projectPath))
        {
            isValid = QMessageBox::warning(mainWindow, tr("Warning"),
                                          tr("Does the file already exist want to replace it to you?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
            if (isValid == QMessageBox::Yes)
            {
                if(!QFile::remove(projectPath))
                    isValid = QMessageBox::No;
            }
        }
        if (isValid == QMessageBox::Yes)
        {
           dynamic_cast<MainWindow*>(mainWindow)->createProject(projectType, projectPath, projectName, projectFormalism);
        }
    }
}

void Reception::populateJavaScriptWindowObject()
{
    webView->page()->mainFrame()->addToJavaScriptWindowObject("nomoSDK", this);
}
