/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_basic.hxx"

#include "runtime.hxx"
#ifndef GCC
#endif
#include "iosys.hxx"
#include "image.hxx"
#include "sbintern.hxx"
#include "sbunoobj.hxx"
#include "opcodes.hxx"

#include <com/sun/star/container/XIndexAccess.hpp>
#include <com/sun/star/script/XDefaultMethod.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/uno/Any.hxx>
#include <comphelper/processfactory.hxx>

using namespace com::sun::star::uno;
using namespace com::sun::star::container;
using namespace com::sun::star::lang;
using namespace com::sun::star::beans;
using namespace com::sun::star::script;

using com::sun::star::uno::Reference;

SbxVariable* getVBAConstant( const String& rName );

// Suchen eines Elements
// Die Bits im String-ID:
// 0x8000 - Argv ist belegt

SbxVariable* SbiRuntime::FindElement
	( SbxObject* pObj, sal_uInt32 nOp1, sal_uInt32 nOp2, SbError nNotFound, sal_Bool bLocal, sal_Bool bStatic )
{
	bool bIsVBAInterOp = SbiRuntime::isVBAEnabled();
	if( bIsVBAInterOp )
	{
		StarBASIC* pMSOMacroRuntimeLib = GetSbData()->pMSOMacroRuntimLib;
		if( pMSOMacroRuntimeLib != NULL )
			pMSOMacroRuntimeLib->ResetFlag( SBX_EXTSEARCH );
	}

	SbxVariable* pElem = NULL;
	if( !pObj )
	{
		Error( SbERR_NO_OBJECT );
		pElem = new SbxVariable;
	}
	else
	{
		sal_Bool bFatalError = sal_False;
		SbxDataType t = (SbxDataType) nOp2;
		String aName( pImg->GetString( static_cast<short>( nOp1 & 0x7FFF ) ) );
		// Hacky capture of Evaluate [] syntax
		// this should be tackled I feel at the pcode level
		if ( bIsVBAInterOp && aName.Search('[') == 0 )
		{
			// emulate pcode here
			StepARGC();
			// pseudo StepLOADSC
			String sArg = aName.Copy( 1, aName.Len() - 2 );
			SbxVariable* p = new SbxVariable;
			p->PutString( sArg );
			PushVar( p );
			//
			StepARGV();
			nOp1 = nOp1 | 0x8000; // indicate params are present
			aName = String::CreateFromAscii("Evaluate");
		}
		if( bLocal )
		{
			if ( bStatic )
			{
				if ( pMeth )
					pElem = pMeth->GetStatics()->Find( aName, SbxCLASS_DONTCARE );
			}

			if ( !pElem )
				pElem = refLocals->Find( aName, SbxCLASS_DONTCARE );
		}
		if( !pElem )
		{
			// Die RTL brauchen wir nicht mehr zu durchsuchen!
			sal_Bool bSave = rBasic.bNoRtl;
			rBasic.bNoRtl = sal_True;
			pElem = pObj->Find( aName, SbxCLASS_DONTCARE );

			// #110004, #112015: Make private really private
			if( bLocal && pElem )	// Local as flag for global search
			{
				if( pElem->IsSet( SBX_PRIVATE ) )
				{
					SbiInstance* pInst_ = pINST;
					if( pInst_ && pInst_->IsCompatibility() && pObj != pElem->GetParent() )
						pElem = NULL;	// Found but in wrong module!

					// Interfaces: Use SBX_EXTFOUND
				}
			}
			rBasic.bNoRtl = bSave;

			// Ist es ein globaler Uno-Bezeichner?
			if( bLocal && !pElem )
			{
				bool bSetName = true; // preserve normal behaviour

				// i#i68894# if VBAInterOp favour searching vba globals
				// over searching for uno classess
				if ( bVBAEnabled )
				{
					// Try Find in VBA symbols space
					pElem = rBasic.VBAFind( aName, SbxCLASS_DONTCARE );
					if ( pElem )
						bSetName = false; // don't overwrite uno name
					else
						pElem = getVBAConstant( aName );
				}

				if( !pElem )
				{
					// #72382 VORSICHT! Liefert jetzt wegen unbekannten
					// Modulen IMMER ein Ergebnis!
					SbUnoClass* pUnoClass = findUnoClass( aName );
					if( pUnoClass )
					{
						pElem = new SbxVariable( t );
						SbxValues aRes( SbxOBJECT );
						aRes.pObj = pUnoClass;
						pElem->SbxVariable::Put( aRes );
					}
				}

				// #62939 Wenn eine Uno-Klasse gefunden wurde, muss
				// das Wrapper-Objekt gehalten werden, da sonst auch
				// die Uno-Klasse, z.B. "stardiv" immer wieder neu
				// aus der Registry gelesen werden muss
				if( pElem )
				{
					// #63774 Darf nicht mit gespeichert werden!!!
					pElem->SetFlag( SBX_DONTSTORE );
					pElem->SetFlag( SBX_NO_MODIFY);

					// #72382 Lokal speichern, sonst werden alle implizit
					// deklarierten Vars automatisch global !
					if ( bSetName )
						pElem->SetName( aName );
					refLocals->Put( pElem, refLocals->Count() );
				}
			}

			if( !pElem )
			{
				// Nicht da und nicht im Objekt?
				// Hat das Ding Parameter, nicht einrichten!
				if( nOp1 & 0x8000 )
					bFatalError = sal_True;
					// ALT: StarBASIC::FatalError( nNotFound );

				// Sonst, falls keine Parameter sind, anderen Error Code verwenden
				if( !bLocal || pImg->GetFlag( SBIMG_EXPLICIT ) )
				{
					// #39108 Bei explizit und als ELEM immer ein Fatal Error
					bFatalError = sal_True;

					// Falls keine Parameter sind, anderen Error Code verwenden
					if( !( nOp1 & 0x8000 ) && nNotFound == SbERR_PROC_UNDEFINED )
						nNotFound = SbERR_VAR_UNDEFINED;
				}
				if( bFatalError )
				{
					// #39108 Statt FatalError zu setzen, Dummy-Variable liefern
					if( !xDummyVar.Is() )
						xDummyVar = new SbxVariable( SbxVARIANT );
					pElem = xDummyVar;

					// Parameter von Hand loeschen
					ClearArgvStack();

					// Normalen Error setzen
					Error( nNotFound, aName );
				}
				else
				{
					if ( bStatic )
						pElem = StepSTATIC_Impl( aName, t );
					if ( !pElem )
					{
						// Sonst Variable neu anlegen
						pElem = new SbxVariable( t );
						if( t != SbxVARIANT )
							pElem->SetFlag( SBX_FIXED );
						pElem->SetName( aName );
						refLocals->Put( pElem, refLocals->Count() );
					}
				}
			}
		}
		// #39108 Args koennen schon geloescht sein!
		if( !bFatalError )
			SetupArgs( pElem, nOp1 );
		// Ein bestimmter Call-Type wurde gewuenscht, daher muessen
		// wir hier den Typ setzen und das Ding anfassen, um den
		// korrekten Returnwert zu erhalten!
		if( pElem->IsA( TYPE(SbxMethod) ) )
		{
			// Soll der Typ konvertiert werden?
			SbxDataType t2 = pElem->GetType();
			sal_Bool bSet = sal_False;
			if( !( pElem->GetFlags() & SBX_FIXED ) )
			{
				if( t != SbxVARIANT && t != t2 &&
					t >= SbxINTEGER && t <= SbxSTRING )
					pElem->SetType( t ), bSet = sal_True;
			}
			// pElem auf eine Ref zuweisen, um ggf. eine Temp-Var zu loeschen
			SbxVariableRef refTemp = pElem;

			// Moegliche Reste vom letzten Aufruf der SbxMethod beseitigen
			// Vorher Schreiben freigeben, damit kein Error gesetzt wird.
			sal_uInt16 nSavFlags = pElem->GetFlags();
			pElem->SetFlag( SBX_READWRITE | SBX_NO_BROADCAST );
			pElem->SbxValue::Clear();
			pElem->SetFlags( nSavFlags );

			// Erst nach dem Setzen anfassen, da z.B. LEFT()
			// den Unterschied zwischen Left$() und Left() kennen muss

			// AB 12.8.96: Da in PopVar() die Parameter von Methoden weggehauen
			// werden, muessen wir hier explizit eine neue SbxMethod anlegen
			SbxVariable* pNew = new SbxMethod( *((SbxMethod*)pElem) ); // das ist der Call!
			//ALT: SbxVariable* pNew = new SbxVariable( *pElem ); // das ist der Call!

			pElem->SetParameters(0); // sonst bleibt Ref auf sich selbst
			pNew->SetFlag( SBX_READWRITE );

			// den Datentypen zuruecksetzen?
			if( bSet )
				pElem->SetType( t2 );
			pElem = pNew;
		}
		// Index-Access bei UnoObjekten beruecksichtigen
		// definitely we want this for VBA where properties are often
		// collections ( which need index access ), but lets only do
		// this if we actually have params following
		else if( bVBAEnabled && pElem->ISA(SbUnoProperty) && pElem->GetParameters() )
		{
			// pElem auf eine Ref zuweisen, um ggf. eine Temp-Var zu loeschen
			SbxVariableRef refTemp = pElem;

			// Variable kopieren und dabei den Notify aufloesen
			SbxVariable* pNew = new SbxVariable( *((SbxVariable*)pElem) ); // das ist der Call!
			pElem->SetParameters( NULL ); // sonst bleibt Ref auf sich selbst
			pElem = pNew;
		}
	}
	return CheckArray( pElem );
}

// Find-Funktion ueber Name fuer aktuellen Scope (z.B. Abfrage aus BASIC-IDE)
SbxBase* SbiRuntime::FindElementExtern( const String& rName )
{
	// Hinweis zu #35281#: Es darf nicht davon ausgegangen werden, dass
	// pMeth != null, da im RunInit noch keine gesetzt ist.

	SbxVariable* pElem = NULL;
	if( !pMod || !rName.Len() )
		return NULL;

	// Lokal suchen
	if( refLocals )
		pElem = refLocals->Find( rName, SbxCLASS_DONTCARE );

	// In Statics suchen
	if ( !pElem && pMeth )
	{
		// Bei Statics, Name der Methode davor setzen
		String aMethName = pMeth->GetName();
		aMethName += ':';
		aMethName += rName;
		pElem = pMod->Find(aMethName, SbxCLASS_DONTCARE);
	}

	// In Parameter-Liste suchen
	if( !pElem && pMeth )
	{
		SbxInfo* pInfo = pMeth->GetInfo();
		if( pInfo && refParams )
		{
        	sal_uInt16 nParamCount = refParams->Count();
			sal_uInt16 j = 1;
			const SbxParamInfo* pParam = pInfo->GetParam( j );
			while( pParam )
			{
				if( pParam->aName.EqualsIgnoreCaseAscii( rName ) )
				{
	                if( j >= nParamCount )
	                {
                        // Parameter is missing
    					pElem = new SbxVariable( SbxSTRING );
                        pElem->PutString( String( RTL_CONSTASCII_USTRINGPARAM("<missing parameter>" ) ) );
                    }
                    else
                    {
    					pElem = refParams->Get( j );
                    }
					break;
				}
				pParam = pInfo->GetParam( ++j );
			}
		}
	}

	// Im Modul suchen
	if( !pElem )
	{
		// RTL nicht durchsuchen!
		sal_Bool bSave = rBasic.bNoRtl;
		rBasic.bNoRtl = sal_True;
		pElem = pMod->Find( rName, SbxCLASS_DONTCARE );
		rBasic.bNoRtl = bSave;
	}
	return pElem;
}


// Argumente eines Elements setzen
// Dabei auch die Argumente umsetzen, falls benannte Parameter
// verwendet wurden

void SbiRuntime::SetupArgs( SbxVariable* p, sal_uInt32 nOp1 )
{
	if( nOp1 & 0x8000 )
	{
		if( !refArgv )
			StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
		sal_Bool bHasNamed = sal_False;
		sal_uInt16 i;
		sal_uInt16 nArgCount = refArgv->Count();
		for( i = 1 ; i < nArgCount ; i++ )
		{
			if( refArgv->GetAlias( i ).Len() )
			{
				bHasNamed = sal_True; break;
			}
		}
		if( bHasNamed )
		{
			// Wir haben mindestens einen benannten Parameter!
			// Wir muessen also umsortieren
			// Gibt es Parameter-Infos?
			SbxInfo* pInfo = p->GetInfo();
			if( !pInfo )
			{
				bool bError_ = true;

				SbUnoMethod* pUnoMethod = PTR_CAST(SbUnoMethod,p);
				SbUnoProperty* pUnoProperty = PTR_CAST(SbUnoProperty,p);
				if( pUnoMethod || pUnoProperty )
				{
					SbUnoObject* pParentUnoObj = PTR_CAST( SbUnoObject,p->GetParent() );
					if( pParentUnoObj )
					{
						Any aUnoAny = pParentUnoObj->getUnoAny();
						Reference< XInvocation > xInvocation;
						aUnoAny >>= xInvocation;
						if( xInvocation.is() )	// TODO: if( xOLEAutomation.is() )
						{
							bError_ = false;

							sal_uInt16 nCurPar = 1;
							AutomationNamedArgsSbxArray* pArg =
								new AutomationNamedArgsSbxArray( nArgCount );
							::rtl::OUString* pNames = pArg->getNames().getArray();
							for( i = 1 ; i < nArgCount ; i++ )
							{
								SbxVariable* pVar = refArgv->Get( i );
								const String& rName = refArgv->GetAlias( i );
								if( rName.Len() )
									pNames[i] = rName;
								pArg->Put( pVar, nCurPar++ );
							}
							refArgv = pArg;
						}
					}
				}
				else if( bVBAEnabled && p->GetType() == SbxOBJECT && (!p->ISA(SbxMethod) || !p->IsBroadcaster()) )
				{
					// Check for default method with named parameters
					SbxBaseRef pObj = (SbxBase*)p->GetObject();
					if( pObj && pObj->ISA(SbUnoObject) )
					{
						SbUnoObject* pUnoObj = (SbUnoObject*)(SbxBase*)pObj;
						Any aAny = pUnoObj->getUnoAny();

						if( aAny.getValueType().getTypeClass() == TypeClass_INTERFACE )
						{
							Reference< XInterface > x = *(Reference< XInterface >*)aAny.getValue();
							Reference< XDefaultMethod > xDfltMethod( x, UNO_QUERY );

							rtl::OUString sDefaultMethod;
							if ( xDfltMethod.is() )
								sDefaultMethod = xDfltMethod->getDefaultMethodName();
							if ( !sDefaultMethod.isEmpty() )
							{
								SbxVariable* meth = pUnoObj->Find( sDefaultMethod, SbxCLASS_METHOD );
								if( meth != NULL )
									pInfo = meth->GetInfo();
								if( pInfo )
									bError_ = false;
							}
						}
					}
				}
				if( bError_ )
					Error( SbERR_NO_NAMED_ARGS );
			}
			else
			{
				sal_uInt16 nCurPar = 1;
				SbxArray* pArg = new SbxArray;
				for( i = 1 ; i < nArgCount ; i++ )
				{
					SbxVariable* pVar = refArgv->Get( i );
					const String& rName = refArgv->GetAlias( i );
					if( rName.Len() )
					{
						// nCurPar wird auf den gefundenen Parameter gesetzt
						sal_uInt16 j = 1;
						const SbxParamInfo* pParam = pInfo->GetParam( j );
						while( pParam )
						{
							if( pParam->aName.EqualsIgnoreCaseAscii( rName ) )
							{
								nCurPar = j;
								break;
							}
							pParam = pInfo->GetParam( ++j );
						}
						if( !pParam )
						{
							Error( SbERR_NAMED_NOT_FOUND ); break;
						}
					}
					pArg->Put( pVar, nCurPar++ );
				}
				refArgv = pArg;
			}
		}
		// Eigene Var als Parameter 0
		refArgv->Put( p, 0 );
		p->SetParameters( refArgv );
		PopArgv();
	}
	else
		p->SetParameters( NULL );
}

// Holen eines Array-Elements

SbxVariable* SbiRuntime::CheckArray( SbxVariable* pElem )
{
	// Falls wir ein Array haben, wollen wir bitte das Array-Element!
	SbxArray* pPar;
	if( pElem->GetType() & SbxARRAY )
	{
		SbxBase* pElemObj = pElem->GetObject();
		SbxDimArray* pDimArray = PTR_CAST(SbxDimArray,pElemObj);
		pPar = pElem->GetParameters();
		if( pDimArray )
		{
			// Die Parameter koennen fehlen, wenn ein Array als
			// Argument uebergeben wird.
			if( pPar )
				pElem = pDimArray->Get( pPar );
		}
		else
		{
			SbxArray* pArray = PTR_CAST(SbxArray,pElemObj);
			if( pArray )
			{
				if( !pPar )
				{
					Error( SbERR_OUT_OF_RANGE );
					pElem = new SbxVariable;
				}
				else
					pElem = pArray->Get( pPar->Get( 1 )->GetInteger() );
			}
		}

		// #42940, 0.Parameter zu NULL setzen, damit sich Var nicht selbst haelt
		if( pPar )
			pPar->Put( NULL, 0 );
	}
	// Index-Access bei UnoObjekten beruecksichtigen
	else if( pElem->GetType() == SbxOBJECT && (!pElem->ISA(SbxMethod) || (bVBAEnabled && !pElem->IsBroadcaster()) ) )
    {
        pPar = pElem->GetParameters();
        if ( pPar )
        {
            // Ist es ein Uno-Objekt?
            SbxBaseRef pObj = (SbxBase*)pElem->GetObject();
            if( pObj )
            {
                if( pObj->ISA(SbUnoObject) )
                {
                    SbUnoObject* pUnoObj = (SbUnoObject*)(SbxBase*)pObj;
                    Any aAny = pUnoObj->getUnoAny();

                    if( aAny.getValueType().getTypeClass() == TypeClass_INTERFACE )
                    {
                        Reference< XInterface > x = *(Reference< XInterface >*)aAny.getValue();
                        Reference< XIndexAccess > xIndexAccess( x, UNO_QUERY );
                        if ( !bVBAEnabled )
                        {
                            // Haben wir Index-Access?
                            if( xIndexAccess.is() )
                            {
                                sal_uInt32 nParamCount = (sal_uInt32)pPar->Count() - 1;
                                if( nParamCount != 1 )
                                {
                                    StarBASIC::Error( SbERR_BAD_ARGUMENT );
                                    return pElem;
                                }

                                // Index holen
                                sal_Int32 nIndex = pPar->Get( 1 )->GetLong();
                                Reference< XInterface > xRet;
                                try
                                {
                                    Any aAny2 = xIndexAccess->getByIndex( nIndex );
                                    TypeClass eType = aAny2.getValueType().getTypeClass();
                                    if( eType == TypeClass_INTERFACE )
                                        xRet = *(Reference< XInterface >*)aAny2.getValue();
                                }
                                catch (IndexOutOfBoundsException&)
                                {
                                    // Bei Exception erstmal immer von Konvertierungs-Problem ausgehen
                                    StarBASIC::Error( SbERR_OUT_OF_RANGE );
                                }

                                // #57847 Immer neue Variable anlegen, sonst Fehler
                                // durch PutObject(NULL) bei ReadOnly-Properties.
                                pElem = new SbxVariable( SbxVARIANT );
                                if( xRet.is() )
                                {
                                    aAny <<= xRet;

                                    // #67173 Kein Namen angeben, damit echter Klassen-Namen eintragen wird
                                    String aName;
                                    SbxObjectRef xWrapper = (SbxObject*)new SbUnoObject( aName, aAny );
                                    pElem->PutObject( xWrapper );
                                }
                                else
                                {
                                    pElem->PutObject( NULL );
                                }
                            }
                        }
                        else
                        {
                            rtl::OUString sDefaultMethod;

                            Reference< XDefaultMethod > xDfltMethod( x, UNO_QUERY );

                            if ( xDfltMethod.is() )
                                sDefaultMethod = xDfltMethod->getDefaultMethodName();
                            else if( xIndexAccess.is() )
                                sDefaultMethod = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getByIndex" ) );

                            if ( !sDefaultMethod.isEmpty() )
                            {
                                SbxVariable* meth = pUnoObj->Find( sDefaultMethod, SbxCLASS_METHOD );
                                SbxVariableRef refTemp = meth;
                                if ( refTemp )
                                {
                                    meth->SetParameters( pPar );
                                    SbxVariable* pNew = new SbxMethod( *(SbxMethod*)meth );
                                    pElem = pNew;
                                }
                            }
                        }
                    }

                    // #42940, 0.Parameter zu NULL setzen, damit sich Var nicht selbst haelt
                    pPar->Put( NULL, 0 );
                }
                else if( pObj->ISA(BasicCollection) )
                {
                    BasicCollection* pCol = (BasicCollection*)(SbxBase*)pObj;
                    pElem = new SbxVariable( SbxVARIANT );
                    pPar->Put( pElem, 0 );
                    pCol->CollItem( pPar );
                }
            }
			else if( bVBAEnabled )	// !pObj
            {
				SbxArray* pParam = pElem->GetParameters();
				if( pParam != NULL && !pElem->IsSet( SBX_VAR_TO_DIM ) )
					Error( SbERR_NO_OBJECT );
			}
        }
    }

	return pElem;
}

// Laden eines Elements aus der Runtime-Library (+StringID+Typ)

void SbiRuntime::StepRTL( sal_uInt32 nOp1, sal_uInt32 nOp2 )
{
	PushVar( FindElement( rBasic.pRtl, nOp1, nOp2, SbERR_PROC_UNDEFINED, sal_False ) );
}

void
SbiRuntime::StepFIND_Impl( SbxObject* pObj, sal_uInt32 nOp1, sal_uInt32 nOp2, SbError nNotFound, sal_Bool bLocal, sal_Bool bStatic )
{
	if( !refLocals )
		refLocals = new SbxArray;
	PushVar( FindElement( pObj, nOp1, nOp2, nNotFound, bLocal, bStatic ) );
}
// Laden einer lokalen/globalen Variablen (+StringID+Typ)

void SbiRuntime::StepFIND( sal_uInt32 nOp1, sal_uInt32 nOp2 )
{
	StepFIND_Impl( pMod, nOp1, nOp2, SbERR_PROC_UNDEFINED, sal_True );
}

// Search inside a class module (CM) to enable global search in time
void SbiRuntime::StepFIND_CM( sal_uInt32 nOp1, sal_uInt32 nOp2 )
{

	SbClassModuleObject* pClassModuleObject = PTR_CAST(SbClassModuleObject,pMod);
	if( pClassModuleObject )
		pMod->SetFlag( SBX_GBLSEARCH );

	StepFIND_Impl( pMod, nOp1, nOp2, SbERR_PROC_UNDEFINED, sal_True );

	if( pClassModuleObject )
		pMod->ResetFlag( SBX_GBLSEARCH );
}

void SbiRuntime::StepFIND_STATIC( sal_uInt32 nOp1, sal_uInt32 nOp2 )
{
	StepFIND_Impl( pMod, nOp1, nOp2, SbERR_PROC_UNDEFINED, sal_True, sal_True );
}

// Laden eines Objekt-Elements (+StringID+Typ)
// Das Objekt liegt auf TOS

void SbiRuntime::StepELEM( sal_uInt32 nOp1, sal_uInt32 nOp2 )
{
	// Liegt auf dem TOS ein Objekt?
	SbxVariableRef pObjVar = PopVar();

	SbxObject* pObj = PTR_CAST(SbxObject,(SbxVariable*) pObjVar);
	if( !pObj )
	{
		SbxBase* pObjVarObj = pObjVar->GetObject();
		pObj = PTR_CAST(SbxObject,pObjVarObj);
	}

	// #56368 Bei StepElem Referenz sichern, sonst koennen Objekte
	// in Qualifizierungsketten wie ActiveComponent.Selection(0).Text
	// zu fueh die Referenz verlieren
	// #74254 Jetzt per Liste
	if( pObj )
		SaveRef( (SbxVariable*)pObj );

	PushVar( FindElement( pObj, nOp1, nOp2, SbERR_NO_METHOD, sal_False ) );
}

// Laden eines Parameters (+Offset+Typ)
// Wenn der Datentyp nicht stimmen sollte, eine Kopie anlegen
// Der Datentyp SbxEMPTY zeigt an, daa kein Parameter angegeben ist.
// Get( 0 ) darf EMPTY sein

void SbiRuntime::StepPARAM( sal_uInt32 nOp1, sal_uInt32 nOp2 )
{
	sal_uInt16 i = static_cast<sal_uInt16>( nOp1 & 0x7FFF );
	SbxDataType t = (SbxDataType) nOp2;
	SbxVariable* p;

	// #57915 Missing sauberer loesen
	sal_uInt16 nParamCount = refParams->Count();
	if( i >= nParamCount )
	{
		sal_Int16 iLoop = i;
		while( iLoop >= nParamCount )
		{
			p = new SbxVariable();

			if( SbiRuntime::isVBAEnabled() &&
				(t == SbxOBJECT || t == SbxSTRING) )
			{
				if( t == SbxOBJECT )
					p->PutObject( NULL );
				else
					p->PutString( String() );
			}
			else
				p->PutErr( 448 );		// Wie in VB: Error-Code 448 (SbERR_NAMED_NOT_FOUND)

			refParams->Put( p, iLoop );
			iLoop--;
		}
	}
	p = refParams->Get( i );

	if( p->GetType() == SbxERROR && ( i ) )
	//if( p->GetType() == SbxEMPTY && ( i ) )
	{
		// Wenn ein Parameter fehlt, kann er OPTIONAL sein
		sal_Bool bOpt = sal_False;
		if( pMeth )
		{
            SbxInfo* pInfo = pMeth->GetInfo();
            if ( pInfo )
            {
                const SbxParamInfo* pParam = pInfo->GetParam( i );
                if( pParam && ( (pParam->nFlags & SBX_OPTIONAL) != 0 ) )
                {
                    // Default value?
                    sal_uInt16 nDefaultId = sal::static_int_cast< sal_uInt16 >(
                        pParam->nUserData & 0xffff );
                    if( nDefaultId > 0 )
                    {
                        String aDefaultStr = pImg->GetString( nDefaultId );
                        p = new SbxVariable();
                        p->PutString( aDefaultStr );
                        refParams->Put( p, i );
                    }
                    bOpt = sal_True;
                }
            }
		}
		if( bOpt == sal_False )
			Error( SbERR_NOT_OPTIONAL );
	}
	else if( t != SbxVARIANT && (SbxDataType)(p->GetType() & 0x0FFF ) != t )
	{
		SbxVariable* q = new SbxVariable( t );
		SaveRef( q );
		*q = *p;
		p = q;
	}
	SetupArgs( p, nOp1 );
	PushVar( CheckArray( p ) );
}

// Case-Test (+True-Target+Test-Opcode)

void SbiRuntime::StepCASEIS( sal_uInt32 nOp1, sal_uInt32 nOp2 )
{
	if( !refCaseStk || !refCaseStk->Count() )
		StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
	else
	{
		SbxVariableRef xComp = PopVar();
		SbxVariableRef xCase = refCaseStk->Get( refCaseStk->Count() - 1 );
		if( xCase->Compare( (SbxOperator) nOp2, *xComp ) )
			StepJUMP( nOp1 );
	}
}

// Aufruf einer DLL-Prozedur (+StringID+Typ)
// Auch hier zeigt das MSB des StringIDs an, dass Argv belegt ist

void SbiRuntime::StepCALL( sal_uInt32 nOp1, sal_uInt32 nOp2 )
{
	String aName = pImg->GetString( static_cast<short>( nOp1 & 0x7FFF ) );
	SbxArray* pArgs = NULL;
	if( nOp1 & 0x8000 )
		pArgs = refArgv;
	DllCall( aName, aLibName, pArgs, (SbxDataType) nOp2, sal_False );
	aLibName = String();
	if( nOp1 & 0x8000 )
		PopArgv();
}

// Aufruf einer DLL-Prozedur nach CDecl (+StringID+Typ)
// Auch hier zeigt das MSB des StringIDs an, dass Argv belegt ist

void SbiRuntime::StepCALLC( sal_uInt32 nOp1, sal_uInt32 nOp2 )
{
	String aName = pImg->GetString( static_cast<short>( nOp1 & 0x7FFF ) );
	SbxArray* pArgs = NULL;
	if( nOp1 & 0x8000 )
		pArgs = refArgv;
	DllCall( aName, aLibName, pArgs, (SbxDataType) nOp2, sal_True );
	aLibName = String();
	if( nOp1 & 0x8000 )
		PopArgv();
}


// Beginn eines Statements (+Line+Col)

void SbiRuntime::StepSTMNT( sal_uInt32 nOp1, sal_uInt32 nOp2 )
{
	// Wenn der Expr-Stack am Anfang einen Statements eine Variable enthaelt,
	// hat ein Trottel X als Funktion aufgerufen, obwohl es eine Variable ist!
	sal_Bool bFatalExpr = sal_False;
    String sUnknownMethodName;
	if( nExprLvl > 1 )
		bFatalExpr = sal_True;
	else if( nExprLvl )
	{
		SbxVariable* p = refExprStk->Get( 0 );
		if( p->GetRefCount() > 1
		 && refLocals.Is() && refLocals->Find( p->GetName(), p->GetClass() ) )
        {
            sUnknownMethodName = p->GetName();
			bFatalExpr = sal_True;
        }
	}
	// Der Expr-Stack ist nun nicht mehr notwendig
	ClearExprStack();

	// #56368 Kuenstliche Referenz fuer StepElem wieder freigeben,
	// damit sie nicht ueber ein Statement hinaus erhalten bleibt
	//refSaveObj = NULL;
	// #74254 Jetzt per Liste
	ClearRefs();

	// Wir muessen hier hart abbrechen, da sonst Zeile und Spalte nicht mehr
	// stimmen!
	if( bFatalExpr)
	{
		StarBASIC::FatalError( SbERR_NO_METHOD, sUnknownMethodName );
		return;
	}
	pStmnt = pCode - 9;
	sal_uInt16 nOld = nLine;
	nLine = static_cast<short>( nOp1 );

	// #29955 & 0xFF, um for-Schleifen-Ebene wegzufiltern
	nCol1 = static_cast<short>( nOp2 & 0xFF );

	// Suchen des naechsten STMNT-Befehls,
	// um die End-Spalte dieses Statements zu setzen
	// Searches of the next STMNT instruction,
	// around the final column of this statement to set

	nCol2 = 0xffff;
	sal_uInt16 n1, n2;
	const sal_uInt8* p = pMod->FindNextStmnt( pCode, n1, n2 );
	if( p )
	{
		if( n1 == nOp1 )
		{
			// #29955 & 0xFF, um for-Schleifen-Ebene wegzufiltern
			nCol2 = (n2 & 0xFF) - 1;
		}
	}

	// #29955 for-Schleifen-Ebene korrigieren, #67452 NICHT im Error-Handler sonst Chaos
	if( !bInError )
	{
		// (Bei Sprüngen aus Schleifen tritt hier eine Differenz auf)
		sal_uInt16 nExspectedForLevel = static_cast<sal_uInt16>( nOp2 / 0x100 );
		if( pGosubStk )
			nExspectedForLevel = nExspectedForLevel + pGosubStk->nStartForLvl;

		// Wenn der tatsaechliche For-Level zu klein ist, wurde aus
		// einer Schleife heraus gesprungen -> korrigieren
		while( nForLvl > nExspectedForLevel )
			PopFor();
	}

	// 16.10.96: #31460 Neues Konzept fuer StepInto/Over/Out
	// Erklärung siehe bei _ImplGetBreakCallLevel.
	if( pInst->nCallLvl <= pInst->nBreakCallLvl )
	//if( nFlags & SbDEBUG_STEPINTO )
	{
		StarBASIC* pStepBasic = GetCurrentBasic( &rBasic );
		sal_uInt16 nNewFlags = pStepBasic->StepPoint( nLine, nCol1, nCol2 );

		// Neuen BreakCallLevel ermitteln
		pInst->CalcBreakCallLevel( nNewFlags );
	}

	// Breakpoints nur bei STMNT-Befehlen in neuer Zeile!
	else if( ( nOp1 != nOld )
		&& ( nFlags & SbDEBUG_BREAK )
		&& pMod->IsBP( static_cast<sal_uInt16>( nOp1 ) ) )
	{
		StarBASIC* pBreakBasic = GetCurrentBasic( &rBasic );
		sal_uInt16 nNewFlags = pBreakBasic->BreakPoint( nLine, nCol1, nCol2 );

		// Neuen BreakCallLevel ermitteln
		pInst->CalcBreakCallLevel( nNewFlags );
		//16.10.96, ALT:
		//if( nNewFlags != SbDEBUG_CONTINUE )
		//	nFlags = nNewFlags;
	}
}

// (+SvStreamFlags+Flags)
// Stack: Blocklaenge
//        Kanalnummer
//        Dateiname

void SbiRuntime::StepOPEN( sal_uInt32 nOp1, sal_uInt32 nOp2 )
{
	SbxVariableRef pName = PopVar();
	SbxVariableRef pChan = PopVar();
	SbxVariableRef pLen  = PopVar();
	short nBlkLen = pLen->GetInteger();
	short nChan   = pChan->GetInteger();
	ByteString aName( pName->GetString(), gsl_getSystemTextEncoding() );
	pIosys->Open( nChan, aName, static_cast<short>( nOp1 ),
		static_cast<short>( nOp2 ), nBlkLen );
	Error( pIosys->GetError() );
}

// Objekt kreieren (+StringID+StringID)

void SbiRuntime::StepCREATE( sal_uInt32 nOp1, sal_uInt32 nOp2 )
{
	String aClass( pImg->GetString( static_cast<short>( nOp2 ) ) );
	SbxObject *pObj = SbxBase::CreateObject( aClass );
	if( !pObj )
		Error( SbERR_INVALID_OBJECT );
	else
	{
		String aName( pImg->GetString( static_cast<short>( nOp1 ) ) );
		pObj->SetName( aName );
	// Das Objekt muss BASIC rufen koennen
		pObj->SetParent( &rBasic );
		SbxVariable* pNew = new SbxVariable;
		pNew->PutObject( pObj );
		PushVar( pNew );
	}
}

void SbiRuntime::StepDCREATE( sal_uInt32 nOp1, sal_uInt32 nOp2 )
{
    StepDCREATE_IMPL( nOp1, nOp2 );
}

void SbiRuntime::StepDCREATE_REDIMP( sal_uInt32 nOp1, sal_uInt32 nOp2 )
{
    StepDCREATE_IMPL( nOp1, nOp2 );
}


// Helper function for StepDCREATE_IMPL / bRedimp = true
void implCopyDimArray_DCREATE( SbxDimArray* pNewArray, SbxDimArray* pOldArray, short nMaxDimIndex,
	short nActualDim, sal_Int32* pActualIndices, sal_Int32* pLowerBounds, sal_Int32* pUpperBounds )
{
	sal_Int32& ri = pActualIndices[nActualDim];
	for( ri = pLowerBounds[nActualDim] ; ri <= pUpperBounds[nActualDim] ; ri++ )
	{
		if( nActualDim < nMaxDimIndex )
		{
			implCopyDimArray_DCREATE( pNewArray, pOldArray, nMaxDimIndex, nActualDim + 1,
				pActualIndices, pLowerBounds, pUpperBounds );
		}
		else
		{
			SbxVariable* pSource = pOldArray->Get32( pActualIndices );
            pNewArray->Put32( pSource, pActualIndices );
		}
	}
}

// #56204 Objekt-Array kreieren (+StringID+StringID), DCREATE == Dim-Create
void SbiRuntime::StepDCREATE_IMPL( sal_uInt32 nOp1, sal_uInt32 nOp2 )
{
	SbxVariableRef refVar = PopVar();

	DimImpl( refVar );

	// Das Array mit Instanzen der geforderten Klasse fuellen
	SbxBaseRef xObj = (SbxBase*)refVar->GetObject();
	if( !xObj )
	{
		StarBASIC::Error( SbERR_INVALID_OBJECT );
		return;
	}

    SbxDimArray* pArray = 0;
	if( xObj->ISA(SbxDimArray) )
	{
		SbxBase* pObj = (SbxBase*)xObj;
		pArray = (SbxDimArray*)pObj;

		// Dimensionen auswerten
		short nDims = pArray->GetDims();
		sal_Int32 nTotalSize = 0;

		// es muss ein eindimensionales Array sein
		sal_Int32 nLower, nUpper, nSize;
		sal_Int32 i;
		for( i = 0 ; i < nDims ; i++ )
		{
			pArray->GetDim32( i+1, nLower, nUpper );
			nSize = nUpper - nLower + 1;
			if( i == 0 )
				nTotalSize = nSize;
			else
				nTotalSize *= nSize;
		}

		// Objekte anlegen und ins Array eintragen
		String aClass( pImg->GetString( static_cast<short>( nOp2 ) ) );
		for( i = 0 ; i < nTotalSize ; i++ )
		{
			SbxObject *pClassObj = SbxBase::CreateObject( aClass );
			if( !pClassObj )
			{
				Error( SbERR_INVALID_OBJECT );
				break;
			}
			else
			{
				String aName( pImg->GetString( static_cast<short>( nOp1 ) ) );
				pClassObj->SetName( aName );
				// Das Objekt muss BASIC rufen koennen
				pClassObj->SetParent( &rBasic );
				pArray->SbxArray::Put32( pClassObj, i );
			}
		}
	}

	SbxDimArray* pOldArray = (SbxDimArray*)(SbxArray*)refRedimpArray;
	if( pArray && pOldArray )
	{
		short nDimsNew = pArray->GetDims();
		short nDimsOld = pOldArray->GetDims();
		short nDims = nDimsNew;
		sal_Bool bRangeError = sal_False;

		// Store dims to use them for copying later
		sal_Int32* pLowerBounds = new sal_Int32[nDims];
		sal_Int32* pUpperBounds = new sal_Int32[nDims];
		sal_Int32* pActualIndices = new sal_Int32[nDims];
		if( nDimsOld != nDimsNew )
		{
			bRangeError = sal_True;
		}
		else
		{
			// Compare bounds
			for( short i = 1 ; i <= nDims ; i++ )
			{
				sal_Int32 lBoundNew, uBoundNew;
				sal_Int32 lBoundOld, uBoundOld;
				pArray->GetDim32( i, lBoundNew, uBoundNew );
				pOldArray->GetDim32( i, lBoundOld, uBoundOld );

				lBoundNew = std::max( lBoundNew, lBoundOld );
				uBoundNew = std::min( uBoundNew, uBoundOld );
				short j = i - 1;
				pActualIndices[j] = pLowerBounds[j] = lBoundNew;
				pUpperBounds[j] = uBoundNew;
			}
		}

		if( bRangeError )
		{
			StarBASIC::Error( SbERR_OUT_OF_RANGE );
		}
		else
		{
			// Copy data from old array by going recursively through all dimensions
			// (It would be faster to work on the flat internal data array of an
			// SbyArray but this solution is clearer and easier)
			implCopyDimArray_DCREATE( pArray, pOldArray, nDims - 1,
				0, pActualIndices, pLowerBounds, pUpperBounds );
		}
		delete [] pUpperBounds;
		delete [] pLowerBounds;
		delete [] pActualIndices;
		refRedimpArray = NULL;
    }
}

// Objekt aus User-Type kreieren  (+StringID+StringID)

SbxObject* createUserTypeImpl( const String& rClassName );	// sb.cxx

void SbiRuntime::StepTCREATE( sal_uInt32 nOp1, sal_uInt32 nOp2 )
{
	String aName( pImg->GetString( static_cast<short>( nOp1 ) ) );
	String aClass( pImg->GetString( static_cast<short>( nOp2 ) ) );

	SbxObject* pCopyObj = createUserTypeImpl( aClass );
	if( pCopyObj )
		pCopyObj->SetName( aName );
	SbxVariable* pNew = new SbxVariable;
	pNew->PutObject( pCopyObj );
	pNew->SetDeclareClassName( aClass );
	PushVar( pNew );
}

void SbiRuntime::implHandleSbxFlags( SbxVariable* pVar, SbxDataType t, sal_uInt32 nOp2 )
{
	bool bWithEvents = ((t & 0xff) == SbxOBJECT && (nOp2 & SBX_TYPE_WITH_EVENTS_FLAG) != 0);
	if( bWithEvents )
		pVar->SetFlag( SBX_WITH_EVENTS );

	bool bDimAsNew = ((nOp2 & SBX_TYPE_DIM_AS_NEW_FLAG) != 0);
	if( bDimAsNew )
		pVar->SetFlag( SBX_DIM_AS_NEW );

	bool bFixedString = ((t & 0xff) == SbxSTRING && (nOp2 & SBX_FIXED_LEN_STRING_FLAG) != 0);
	if( bFixedString )
	{
		sal_uInt16 nCount = static_cast<sal_uInt16>( nOp2 >> 17 );		// len = all bits above 0x10000
		String aStr;
		aStr.Fill( nCount, 0 );
		pVar->PutString( aStr );
	}

	bool bVarToDim = ((nOp2 & SBX_TYPE_VAR_TO_DIM_FLAG) != 0);
	if( bVarToDim )
		pVar->SetFlag( SBX_VAR_TO_DIM );
}

// Einrichten einer lokalen Variablen (+StringID+Typ)

void SbiRuntime::StepLOCAL( sal_uInt32 nOp1, sal_uInt32 nOp2 )
{
	if( !refLocals.Is() )
		refLocals = new SbxArray;
	String aName( pImg->GetString( static_cast<short>( nOp1 ) ) );
	if( refLocals->Find( aName, SbxCLASS_DONTCARE ) == NULL )
	{
		SbxDataType t = (SbxDataType)(nOp2 & 0xffff);
		SbxVariable* p = new SbxVariable( t );
		p->SetName( aName );
		implHandleSbxFlags( p, t, nOp2 );
		refLocals->Put( p, refLocals->Count() );
	}
}

// Einrichten einer modulglobalen Variablen (+StringID+Typ)

void SbiRuntime::StepPUBLIC_Impl( sal_uInt32 nOp1, sal_uInt32 nOp2, bool bUsedForClassModule )
{
	String aName( pImg->GetString( static_cast<short>( nOp1 ) ) );
	SbxDataType t = (SbxDataType)(SbxDataType)(nOp2 & 0xffff);
	sal_Bool bFlag = pMod->IsSet( SBX_NO_MODIFY );
	pMod->SetFlag( SBX_NO_MODIFY );
	SbxVariableRef p = pMod->Find( aName, SbxCLASS_PROPERTY );
	if( p.Is() )
		pMod->Remove (p);
	SbProperty* pProp = pMod->GetProperty( aName, t );
	if( !bUsedForClassModule )
		pProp->SetFlag( SBX_PRIVATE );
	if( !bFlag )
		pMod->ResetFlag( SBX_NO_MODIFY );
	if( pProp )
	{
		pProp->SetFlag( SBX_DONTSTORE );
		// AB: 2.7.1996: HACK wegen 'Referenz kann nicht gesichert werden'
		pProp->SetFlag( SBX_NO_MODIFY);

		implHandleSbxFlags( pProp, t, nOp2 );
	}
}

void SbiRuntime::StepPUBLIC( sal_uInt32 nOp1, sal_uInt32 nOp2 )
{
	StepPUBLIC_Impl( nOp1, nOp2, false );
}

void SbiRuntime::StepPUBLIC_P( sal_uInt32 nOp1, sal_uInt32 nOp2 )
{
    // Creates module variable that isn't reinitialised when
    // between invocations ( for VBASupport & document basic only )
    if( pMod->pImage->bFirstInit )
	{
		bool bUsedForClassModule = pImg->GetFlag( SBIMG_CLASSMODULE );
		StepPUBLIC_Impl( nOp1, nOp2, bUsedForClassModule );
	}
}

// Einrichten einer globalen Variablen (+StringID+Typ)

void SbiRuntime::StepGLOBAL( sal_uInt32 nOp1, sal_uInt32 nOp2 )
{
	if( pImg->GetFlag( SBIMG_CLASSMODULE ) )
		StepPUBLIC_Impl( nOp1, nOp2, true );

	String aName( pImg->GetString( static_cast<short>( nOp1 ) ) );
	SbxDataType t = (SbxDataType)(nOp2 & 0xffff);

	// Store module scope variables at module scope
	// in non vba mode these are stored at the library level :/
	// not sure if this really should not be enabled for ALL basic
	SbxObject* pStorage = &rBasic;
	if ( SbiRuntime::isVBAEnabled() )
	{
		pStorage = pMod;
		pMod->AddVarName( aName );
	}

	sal_Bool bFlag = pStorage->IsSet( SBX_NO_MODIFY );
	rBasic.SetFlag( SBX_NO_MODIFY );
	SbxVariableRef p = pStorage->Find( aName, SbxCLASS_PROPERTY );
	if( p.Is() )
		pStorage->Remove (p);
	p = pStorage->Make( aName, SbxCLASS_PROPERTY, t );
	if( !bFlag )
		pStorage->ResetFlag( SBX_NO_MODIFY );
	if( p )
	{
		p->SetFlag( SBX_DONTSTORE );
		// AB: 2.7.1996: HACK wegen 'Referenz kann nicht gesichert werden'
		p->SetFlag( SBX_NO_MODIFY);
	}
}


// Creates global variable that isn't reinitialised when
// basic is restarted, P=PERSIST (+StringID+Typ)

void SbiRuntime::StepGLOBAL_P( sal_uInt32 nOp1, sal_uInt32 nOp2 )
{
    if( pMod->pImage->bFirstInit )
    {
        StepGLOBAL( nOp1, nOp2 );
    }
}


// Searches for global variable, behavior depends on the fact
// if the variable is initialised for the first time

void SbiRuntime::StepFIND_G( sal_uInt32 nOp1, sal_uInt32 nOp2 )
{
    if( pMod->pImage->bFirstInit )
    {
        // Behave like always during first init
        StepFIND( nOp1, nOp2 );
    }
    else
    {
        // Return dummy variable
		SbxDataType t = (SbxDataType) nOp2;
		String aName( pImg->GetString( static_cast<short>( nOp1 & 0x7FFF ) ) );

        SbxVariable* pDummyVar = new SbxVariable( t );
		pDummyVar->SetName( aName );
    	PushVar( pDummyVar );
    }
}


SbxVariable* SbiRuntime::StepSTATIC_Impl( String& aName, SbxDataType& t )
{
    SbxVariable* p = NULL;
    if ( pMeth )
    {
        SbxArray* pStatics = pMeth->GetStatics();
        if( pStatics && ( pStatics->Find( aName, SbxCLASS_DONTCARE ) == NULL ) )
        {
            p = new SbxVariable( t );
            if( t != SbxVARIANT )
                p->SetFlag( SBX_FIXED );
            p->SetName( aName );
            pStatics->Put( p, pStatics->Count() );
        }
    }
    return p;
}
// Einrichten einer statischen Variablen (+StringID+Typ)
void SbiRuntime::StepSTATIC( sal_uInt32 nOp1, sal_uInt32 nOp2 )
{
    String aName( pImg->GetString( static_cast<short>( nOp1 ) ) );
    SbxDataType t = (SbxDataType) nOp2;
    StepSTATIC_Impl( aName, t );
}
