#include "qgpythonconsoledockwidget.h"
#include "ui_qgpythonconsoledockwidget.h"

#include "qgpython.h"
#include "qgscopeworkbench.h"
#include "qgpyeditdialog.h"
#include "qglogger.h"

#include <QPlainTextEdit>
#include <QLineEdit>
#include <QDebug>

#include <QDropEvent>
#include <QDragEnterEvent>
#include <QMimeData>
#include <QClipboard>
#include <QMessageBox>

class QgPythonConsoleDockWidget::Implementation
{
public:
    QgPyEditDialog* miniEditor;
    QgLogger logger;

    Implementation(QWidget* parent):
        miniEditor(0),
        logger("PY")
    {
        miniEditor=new QgPyEditDialog(parent);
    }

    void showMiniEditor()
    {
        if (!miniEditor)
        {
            miniEditor=new QgPyEditDialog;
            miniEditor->setWindowTitle("Python Editor");
        }

        miniEditor->show();
    }
};

QgPythonConsoleDockWidget::QgPythonConsoleDockWidget(QWidget *parent) :
    QDockWidget(parent),
    ui(new Ui::QgPythonConsoleDockWidget),
    m_qtdbg(false),
    p_(*new Implementation(this))
{
    ui->setupUi(this);

    PythonQt& pyqt=QgPython::instance().self();

    connect(&pyqt, &PythonQt::pythonStdOut, this,
            [this](const QString& str)
            {
                ui->pyStdOut->moveCursor(QTextCursor::End);
                ui->pyStdOut->insertPlainText (str);
                //ui->pyStdOut->setTextCursor (&prev_cursor);

                //ui->pyStdOut->appendPlainText(str);
                forwardToQDbg(str);
            }
        );
    connect(&pyqt, &PythonQt::pythonStdErr, this,
            [this](const QString& str)
            {
                ui->pyStdOut->moveCursor (QTextCursor::End);
                ui->pyStdOut->insertPlainText (str);

                forwardToQDbg(str, true);
            }
        );

    connect(ui->lineEdit, &QLineEdit::returnPressed, this,
            [this]()
            {
                QString tmp=ui->lineEdit->text();
                //qDebug()<<"evalScript:"<<tmp;
                ui->pyStdOut->append("<p><font color=\"green\">"+tmp+"<font color=\"black\"></p>");
                ui->pyStdOut->append("");
                QgPython::instance().mainContext().evalScript(tmp);
            }
        );

    connect(ui->tbMiniEditor, &QToolButton::clicked, this,
            [this]()
            {
                p_.showMiniEditor();
            }
        );

    connect(p_.miniEditor, &QgPyEditDialog::accepted, this,
            [this]()
            {
                QString tmp=p_.miniEditor->text();
                if (!tmp.isEmpty())
                    QgPython::instance().mainContext().evalScript(tmp);
                else
                {
                    tmp=p_.miniEditor->execFile();
                    if (!tmp.isEmpty())
                    {
                        QgPython::instance().mainContext().evalFile(tmp);
                    }
                }
            }
        );
    QgPython::instance().mainContext().addObject("pypanel", this);
    QgPython::instance().mainContext().evalScript("import sys\npypanel.pyhtonVersion=sys.version");

    setWindowTitle(QString("PythonQT - %1").arg(m_pyver));

    QgScopeWorkbench::instance().log(QString("Python ready"));

    setAcceptDrops(true);
}

void QgPythonConsoleDockWidget::miniEditor()
{
    p_.showMiniEditor();
}

QgPythonConsoleDockWidget::~QgPythonConsoleDockWidget()
{
    delete ui;    
}

void QgPythonConsoleDockWidget::QgPythonConsoleDockWidget::forwardToQDbg(const QString& str, bool err)
{
    static QString accumulator;

    if (!m_qtdbg)
        return;
    if (!err && m_qtdbg)
        qDebug()<<"PY:"<<str;
    else
    {
        accumulator+=str;
        if (str.contains('\n') || (str.size()>1024))
        {
            //qWarning()<<"PYERR:"<<accumulator;
            accumulator.clear();
        }

    }
}

void QgPythonConsoleDockWidget::dropEvent(QDropEvent* evn)
{
    if (!evn)
    {
        const QClipboard *clipboard = QApplication::clipboard();
        if (clipboard)
        {
            const QMimeData *mimeData = clipboard->mimeData();
            if (mimeData)
            {
                if (mimeData->hasText())
                {
                    p_.miniEditor->setMimeInfo(mimeData);
                    p_.miniEditor->show();
                    return;
                }
            }
        }

        QMessageBox::warning(this, "Paste from clipboad", "Invalid or empty clipboard conetnts");

        return;
    }

    if (true) //(evn->keyboardModifiers() & Qt::ShiftModifier) || (evn->dropAction()==Qt::MoveAction))
    {
       evn->setDropAction(Qt::CopyAction);
       //QgVtDropDialog dlg(this);
       p_.miniEditor->setMimeInfo(evn->mimeData());
       evn->accept();
       p_.miniEditor->show();
    }
}

void QgPythonConsoleDockWidget::dragEnterEvent(QDragEnterEvent *event)
{
    qDebug()<<"DRAG";
    //if (event->mimeData()->hasFormat("text/plain"))
    if (event->mimeData()->hasText() || event->mimeData()->hasUrls())
        event->acceptProposedAction();
    else
        qDebug()<<"Unsupported Drop format:"<<event->mimeData()->formats();
}
