/*
 *  nextpnr -- Next Generation Place and Route
 *
 *  Copyright (C) 2018  Miodrag Milanovic <miodrag@symbioticeda.com>
 *
 *  Permission to use, copy, modify, and/or distribute this software for any
 *  purpose with or without fee is hereby granted, provided that the above
 *  copyright notice and this permission notice appear in all copies.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

#include "pythontab.h"
#include <QGridLayout>
#include "pybindings.h"
#include "pyinterpreter.h"

NEXTPNR_NAMESPACE_BEGIN

const QString PythonTab::PROMPT = ">>> ";
const QString PythonTab::MULTILINE_PROMPT = "... ";

PythonTab::PythonTab(QWidget *parent) : QWidget(parent), initialized(false)
{
    QFont f("unexistent");
    f.setStyleHint(QFont::Monospace);

    // Add text area for Python output and input line
    console = new PythonConsole();
    console->setMinimumHeight(100);
    console->setReadOnly(true);
    console->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard);
    console->setFont(f);

    console->setContextMenuPolicy(Qt::CustomContextMenu);
    QAction *clearAction = new QAction("Clear &buffer", this);
    clearAction->setStatusTip("Clears display buffer");
    connect(clearAction, &QAction::triggered, this, &PythonTab::clearBuffer);
    contextMenu = console->createStandardContextMenu();
    contextMenu->addSeparator();
    contextMenu->addAction(clearAction);
    connect(console, &PythonConsole::customContextMenuRequested, this, &PythonTab::showContextMenu);

    lineEdit = new LineEditor(&parseHelper);
    lineEdit->setMinimumHeight(30);
    lineEdit->setMaximumHeight(30);
    lineEdit->setFont(f);
    lineEdit->setPlaceholderText(PythonTab::PROMPT);
    connect(lineEdit, &LineEditor::textLineInserted, this, &PythonTab::editLineReturnPressed);

    QGridLayout *mainLayout = new QGridLayout();
    mainLayout->addWidget(console, 0, 0);
    mainLayout->addWidget(lineEdit, 1, 0);
    setLayout(mainLayout);

    parseHelper.subscribe(console);

    prompt = PythonTab::PROMPT;
}

PythonTab::~PythonTab()
{
    if (initialized) {
        pyinterpreter_finalize();
        deinit_python();
    }
}

void PythonTab::editLineReturnPressed(QString text)
{
    console->displayString(prompt + text + "\n");

    parseHelper.process(text.toStdString());

    if (parseHelper.buffered())
        prompt = PythonTab::MULTILINE_PROMPT;
    else
        prompt = PythonTab::PROMPT;

    lineEdit->setPlaceholderText(prompt);
}

void PythonTab::newContext(Context *ctx)
{
    if (initialized) {
        pyinterpreter_finalize();
        deinit_python();
    }
    console->clear();

    pyinterpreter_preinit();
    init_python("nextpnr", true);
    pyinterpreter_initialize();
    pyinterpreter_aquire();
    init_python("nextpnr", false);
    python_export_global("ctx", ctx);
    pyinterpreter_release();

    initialized = true;

    QString version = QString("Python %1 on %2\n").arg(Py_GetVersion(), Py_GetPlatform());
    console->displayString(version);
}

void PythonTab::showContextMenu(const QPoint &pt) { contextMenu->exec(mapToGlobal(pt)); }

void PythonTab::clearBuffer() { console->clear(); }

void PythonTab::info(std::string str) { console->displayString(str.c_str()); }

void PythonTab::execute_python(std::string filename) { console->execute_python(filename); }

NEXTPNR_NAMESPACE_END
