/****************************************************************************
** $Id: qsenv.h  beta1   edited Dec 10 14:29 $
**
** 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.
**
*****************************************************************************/

#ifndef QSENV_H
#define QSENV_H

#include "qsobject.h"
#include "qsclasslist.h"
#include <qstring.h>
#include <qvaluelist.h>
#include <qptrlist.h>
#include <qstringlist.h>

class QSClass;
class QSObjectClass;
class QSUndefinedClass;
class QSNullClass;
class QSBooleanClass;
class QSNumberClass;
class QSStringClass;
class QSCharacterClass;
class QSFunctionClass;
class QSTypeClass;
class QSDateClass;
class QSMathClass;
class QSRegExpClass;
class QSArrayClass;
class QSErrorClass;
class QSArgumentsClass;
class QSDynamicClass;
class QSGlobalClass;
class QSFuncRefClass;

typedef QValueList<QSObject> ScopeChain;

class QUICKCORE_EXPORT QSEnv {
public:
    enum ExecutionMode { Normal, Break, Continue, ReturnValue, Throw };
    QSEnv();
    ~QSEnv();
    void init();
    void clear();

    void pushScopeBlock();
    void pushScope( const QSObject &scope );
    void popScope();
    void popScopeBlock();
    ScopeChain scope() const;
    QSObject currentScope() const;
    void printScopeChain() const;
    QSObject thisValue() const;
    void setThisValue( const QSObject &t );
    QSObject globalObject() const;
    QSObject getValueDirect( int index, int level );
    void setValueDirect( int index, int level, const QSObject &value );
    QSObject scopeObjectAt( int level ) const;

    QSClass* classByName( const QString &n );

    void pushLabel( const QString &l );
    void popLabel();
    bool containsLabel( const QString &l ) const;
    QString currentLabel() const { return label; }
    void setCurrentLabel( const QString &l ) { label = l; }
    bool isCurrentLabelValid() const;

    static QSEnv *current() { return curr; } // ### temp

    QSObjectClass *objectClass() const { return objClass; }
    QSNullClass *nullClass() const { return nilClass; }
    QSUndefinedClass *undefinedClass() const { return undefClass; }
    QSNumberClass *numberClass() const { return numClass; }
    QSBooleanClass *booleanClass() const { return boolClass; }
    QSStringClass *stringClass() const { return strClass; }
    QSTypeClass *typeClass() const { return typClass; }
    QSErrorClass *errorClass() const { return errClass; }
    QSArrayClass *arrayClass() const { return arrClass; }
    QSDateClass *dateClass() const { return datClass; }
    QSRegExpClass *regexpClass() const { return regClass; }
    QSMathClass *mathClass() const { return matClass; }
    QSFuncRefClass *funcRefClass() const { return refClass; }

    // internal
    QSGlobalClass *globalClass() const { return globClass; }
    QSArgumentsClass *argumentsClass() const { return argsClass; }
    QSDynamicClass *dynamicClass() const { return dynClass; }

    void registerClass( QSClass *cl );

    QSObject resolveValue( const QString &n ) const;

    QPtrList<QSClass> classes() const { return classList; }

    QSObject throwError( ErrorType e, const QString &m = QString::null,
			 int l = -1 );

    void setException( const QSObject &e );
    void setException( const QString &msg );
    QSObject exception();
    void clearException();

    void setExecutionMode( ExecutionMode mode );
    ExecutionMode executionMode() const { return execMode; }
    bool isNormalMode() const { return execMode==Normal; }
    bool isExceptionMode() const { return execMode==Throw; }
    bool isBreakMode() const { return execMode==Break; }
    bool isContinueMode() const { return execMode==Continue; }
    bool isReturnValueMode() const { return execMode==ReturnValue; }

private:
    QSObjectClass *objClass;
    QSUndefinedClass *undefClass;
    QSNullClass *nilClass;
    QSBooleanClass *boolClass;
    QSNumberClass *numClass;
    QSStringClass *strClass;
    QSCharacterClass *charClass;
    QSTypeClass *typClass;
    QSDateClass *datClass;
    QSMathClass *matClass;
    QSRegExpClass *regClass;
    QSArrayClass *arrClass;
    QSErrorClass *errClass;
    QSGlobalClass *globClass;
    QSArgumentsClass *argsClass;
    QSDynamicClass *dynClass;
    QSFuncRefClass * refClass;

    static QSEnv *curr; // ### temp

    ScopeChain * scopeChain;
    QSObject thVal;
    QSClassList classList;
    QStringList labels;
    QString label;

    // exception
    QString exMsg;
    QSObject exVal;
    QSObject retVal;

    ExecutionMode execMode;
};

#endif
