#include "scriptsession.h"
#include "QConsoleWidget.h"
#include "qscriptcompleter.h"
 
#include <QApplication>
#include <QEventLoop>
#include <QJSEngine>
 
#include <QJSValue>
 

#include <QTimer>
#include <QElapsedTimer>
#include <QIODevice>


ScriptSession::ScriptSession(QConsoleWidget *aw) : QObject(), w(aw)
{
    // Create script engine and add extra functions
    e = new QJSEngine(this);
    e->installExtensions(QJSEngine::AllExtensions); // 安裝所有的扩展

    // write preample
    w->writeStdOut(
                "LAMP Command Console :"
                " interactive qscript interpreter\n\n"
                "Ctrl-Q aborts a qscript evaluation\n\n"
                );

    // Set the completer
    QScriptCompleter* c = new QScriptCompleter;
    c->seScripttEngine(e);
    w->setCompleter(c);
    // A "." triggers the completer
    QStringList tr;
    tr << ".";
    w->setCompletionTriggers(tr);

    // init the internal timer for tic()/toc()
    tmr_ = new QElapsedTimer();

}

void ScriptSession::tic()
{
    tmr_->start();
}
qreal ScriptSession::toc()
{
    return  1.e-6*tmr_->nsecsElapsed();
}

void ScriptSession::quit()
{
    w->device()->close();
}

 

void ScriptSession::settingApplication(QObject* object)
{

    QJSValue* app = new QJSValue(e->newQObject(object));
    QJSValue global = e->globalObject();
    global.setProperty("app", *app);
}

void ScriptSession::addJsObeject(const QString& objname, QObject* obj)
{

    QJSValue* jsobj = new QJSValue(e->newQObject(obj));
    QJSValue global = e->globalObject();
    global.setProperty(objname, *jsobj);

}

void ScriptSession::abortEvaluation()
{
    
}

void ScriptSession::REPL()
{
    QIODevice* d = w->device();
    QTextStream ws(d);
    QString multilineCode;

    while(ws.device()->isOpen()) {

        ws << (multilineCode.isEmpty() ? "js> " : "....> ") << flush;

        ws >> inputMode >> waitForInput; 

        multilineCode += ws.readAll();
        
		if (!multilineCode.isEmpty())
		{
			QJSValue res = e->evaluate(multilineCode);
            multilineCode = "";
            
            // 测试输出
            qDebug() << "res.isError()" << res.isError();
            qDebug() << "res.isUndefined()" << res.isUndefined();
            qDebug() << "res.isNull()" << res.isNull();
            qDebug() << "res: " << res.toString();

			if (res.isError())
			{
				ws << errChannel;
				if (!res.isUndefined()) ws << res.toString();
				ws << endl;
				ws << res.property("stack").toString() << endl;
				ws << outChannel;
			}
            else if (!res.isNull())
            {
                ws << res.toString() << endl;
            }
            else if(res.isUndefined()) {
                ws << u8"undefined" << endl;
            }
            else if (res.isNull()) {
				ws << u8"null" << endl;
			}
		}
	}

}




