/****************************************************************************
** $Id: quickinterpreterinterfaceimpl.cpp  beta1   edited Dec 10 13:07 $
**
** Copyright (C) 2001-2002 Trolltech AS.  All rights reserved.
**
** This file is part of the Qt Script for Applications framework (QSA).
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.
**
** Licensees holding a valid QSA Beta Evaluation Version license may use
** this file in accordance with the QSA Beta Evaluation Version License
** Agreement provided with the Software.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
**   information about QSA Commercial License Agreements.
** See http://www.trolltech.com/gpl/ for GPL licensing information.
**
** Contact info@trolltech.com if any conditions of this licensing are
** not clear to you.
**
*****************************************************************************/

#include "quickinterpreterinterfaceimpl.h"
#include "quickinterpreter.h"
#include "quickdebugger.h"
#include "quickclassparser.h"
#include <qobjectlist.h>
#include <qvariant.h>
#include <qregexp.h>
#include <qfile.h>
#include <qfileinfo.h>
#include <qdir.h>
#include <qtextstream.h>
#include <qapplication.h>

QObject *QuickInterpreterInterfaceImpl::debugReceiver = 0;
const char *QuickInterpreterInterfaceImpl::debugSlot = 0;
QObject *QuickInterpreterInterfaceImpl::errorReceiver = 0;
const char *QuickInterpreterInterfaceImpl::errorSlot = 0;
QObject *QuickInterpreterInterfaceImpl::finishReceiver = 0;
const char *QuickInterpreterInterfaceImpl::finishSlot = 0;
QObject *QuickInterpreterInterfaceImpl::stackFrameReceiver = 0;
const char *QuickInterpreterInterfaceImpl::stackFrameSlot = 0;

QuickInterpreterInterfaceImpl::QuickInterpreterInterfaceImpl()
    : ref( 0 )
{
}

QuickInterpreterInterfaceImpl::~QuickInterpreterInterfaceImpl()
{
}

QRESULT QuickInterpreterInterfaceImpl::queryInterface( const QUuid &uuid, QUnknownInterface **iface )
{
    *iface = 0;
    if ( uuid == IID_QUnknown )
	*iface = (QUnknownInterface*)this;
    else if ( uuid == IID_Interpreter )
	*iface = (InterpreterInterface*)this;
    else
	return QE_NOINTERFACE;

    (*iface)->addRef();
    return QS_OK;
}

unsigned long QuickInterpreterInterfaceImpl::addRef()
{
    return ref++;
}

unsigned long QuickInterpreterInterfaceImpl::release()
{
    if ( !--ref ) {
	delete this;
	return 0;
    }
    return ref;
}

bool QuickInterpreterInterfaceImpl::exec( QObject *obj, const QString &code )
{
    QuickInterpreter *ip = QuickInterpreter::self();

    if ( !obj ) {
	ip->call( 0, code, QSList() );
	return TRUE;
    }

    int sourceId;
    ip->execute( obj, code, sourceId );
    return TRUE;
}

void QuickInterpreterInterfaceImpl::setBreakPoints( QObject *obj, const QValueList<uint> &lst )
{
    int sourceId = QuickInterpreter::self()->sourceIdOfObject( obj );
    if ( sourceId == -1 )
	return;
    QuickInterpreter::self()->debuggerEngine()->clearAllBreakpoints( sourceId );
    for ( QValueList<uint>::ConstIterator bit = lst.begin(); bit != lst.end(); ++bit )
	QuickInterpreter::self()->debuggerEngine()->setBreakpoint( sourceId, *bit );
}

void QuickInterpreterInterfaceImpl::showDebugStep( QWidget *w, int line )
{
    if ( debugReceiver )
	onShowDebugStep( debugReceiver, debugSlot );
    emit sDebugStep( w, line );
}

void QuickInterpreterInterfaceImpl::showStackFrame( QWidget *w, int line )
{
    if ( stackFrameReceiver )
	onShowStackFrame( stackFrameReceiver, stackFrameSlot );
    emit sStackFrame( w, line );
}

void QuickInterpreterInterfaceImpl::showError( QWidget *w, int line, const QString &message )
{
    if ( errorReceiver )
	onShowError( errorReceiver, errorSlot );
    emit sError( w, line, message );
}

void QuickInterpreterInterfaceImpl::doFinish()
{
    if ( finishReceiver )
	onFinish( finishReceiver, finishSlot );
    emit finish();
}

void QuickInterpreterInterfaceImpl::onShowDebugStep( QObject *obj, const char *slot )
{
    if ( debugReceiver ) {
	disconnect( this, SIGNAL( sDebugStep( QObject *, int ) ), debugReceiver, debugSlot );
    }
    debugReceiver = obj;
    debugSlot = qstrdup( slot );
    connect( this, SIGNAL( sDebugStep( QObject *, int ) ), obj, slot );
}

void QuickInterpreterInterfaceImpl::onShowStackFrame( QObject *obj, const char *slot )
{
    if ( stackFrameReceiver ) {
	disconnect( this, SIGNAL( sStackFrame( QObject *, int ) ), stackFrameReceiver, stackFrameSlot );
    }
    stackFrameReceiver = obj;
    stackFrameSlot = qstrdup( slot );
    connect( this, SIGNAL( sStackFrame( QObject *, int ) ), obj, slot );
}

void QuickInterpreterInterfaceImpl::onShowError( QObject *obj, const char *slot )
{
    if ( errorReceiver ) {
	disconnect( this, SIGNAL( sError( QObject *, int, const QString & ) ), errorReceiver, errorSlot );
    }
    errorReceiver = obj;
    errorSlot = qstrdup( slot );
    connect( this, SIGNAL( sError( QObject *, int, const QString & ) ), obj, slot );
}

void QuickInterpreterInterfaceImpl::onFinish( QObject *obj, const char *slot )
{
    if ( finishReceiver ) {
	disconnect( this, SIGNAL( finish() ), finishReceiver, finishSlot );
    }
    finishReceiver = obj;
    finishSlot = qstrdup( slot );
    connect( this, SIGNAL( finish() ), finishReceiver, finishSlot );
}

QString QuickInterpreterInterfaceImpl::createVariableDeclaration( const QString &var )
{
    if ( !var.startsWith( "var" ) && !var.startsWith( "const" ) && !var.startsWith( "static" ) )
	return "var " + var;
    return var;
}

QString QuickInterpreterInterfaceImpl::createFunctionDeclaration( const QString &name, const QString &body )
{
    return "function " + name + "\n" + body + "\n\n";
}

void QuickInterpreterInterfaceImpl::clear()
{
}
