/*
 *  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", !initialized);
    pyinterpreter_initialize();
    pyinterpreter_aquire();
    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()); }

NEXTPNR_NAMESPACE_END
