/**************************************************************
 *
 * 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 <stdlib.h> // getenv
#include <vcl/svapp.hxx>
#include <vcl/mapmod.hxx>
#include <vcl/wrkwin.hxx>
#include <vcl/timer.hxx>
#include <basic/sbxvar.hxx>
#ifndef _SBX_HXX
#include <basic/sbx.hxx>
#endif
#include <svl/zforlist.hxx>
#include <tools/fsys.hxx>
#include <tools/urlobj.hxx>
#include <osl/file.hxx>

#ifdef OS2
#define INCL_DOS
#define INCL_DOSPROCESS
#include <svpm.h>
#endif

#ifndef CLK_TCK
#define CLK_TCK CLOCKS_PER_SEC
#endif

#include <vcl/jobset.hxx>
#include <basic/sbobjmod.hxx>

#include "sbintern.hxx"
#include "runtime.hxx"
#include "stdobj.hxx"
#include "rtlproto.hxx"
#include "dllmgr.hxx"
#include <iosys.hxx>
#include "sbunoobj.hxx"
#include "propacc.hxx"


#include <comphelper/processfactory.hxx>

#include <com/sun/star/uno/Sequence.hxx>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/i18n/XCalendar.hpp>

using namespace comphelper;
using namespace com::sun::star::uno;
using namespace com::sun::star::i18n;


static Reference< XCalendar > getLocaleCalendar( void )
{
	static Reference< XCalendar > xCalendar;
	if( !xCalendar.is() )
	{
		Reference< XMultiServiceFactory > xSMgr = getProcessServiceFactory();
		if( xSMgr.is() )
		{
			xCalendar = Reference< XCalendar >( xSMgr->createInstance
				( ::rtl::OUString::createFromAscii( "com.sun.star.i18n.LocaleCalendar" ) ), UNO_QUERY );
		}
	}

	static com::sun::star::lang::Locale aLastLocale;
	static bool bNeedsInit = true;

	com::sun::star::lang::Locale aLocale = Application::GetSettings().GetLocale();
	bool bNeedsReload = false;
	if( bNeedsInit )
	{
		bNeedsInit = false;
		bNeedsReload = true;
	}
	else if( aLocale.Language != aLastLocale.Language ||
			 aLocale.Country  != aLastLocale.Country )
	{
		bNeedsReload = true;
	}
	if( bNeedsReload )
	{
		aLastLocale = aLocale;
		xCalendar->loadDefaultCalendar( aLocale );
	}
	return xCalendar;
}

RTLFUNC(CallByName)
{
    (void)pBasic;
    (void)bWrite;

	const sal_Int16 vbGet		= 2;
	const sal_Int16 vbLet		= 4;
	const sal_Int16 vbMethod	= 1;
	const sal_Int16 vbSet		= 8;

	// At least 3 parameter needed plus function itself -> 4
	sal_uInt16 nParCount = rPar.Count();
	if ( nParCount < 4 )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}

	// 1. parameter is object
	SbxBase* pObjVar = (SbxObject*)rPar.Get(1)->GetObject();
	SbxObject* pObj = NULL;
	if( pObjVar )
		pObj = PTR_CAST(SbxObject,pObjVar);
	if( !pObj && pObjVar && pObjVar->ISA(SbxVariable) )
	{
		SbxBase* pObjVarObj = ((SbxVariable*)pObjVar)->GetObject();
		pObj = PTR_CAST(SbxObject,pObjVarObj);
	}
	if( !pObj )
	{
		StarBASIC::Error( SbERR_BAD_PARAMETER );
		return;
	}

	// 2. parameter is ProcedureName
	String aNameStr = rPar.Get(2)->GetString();

	// 3. parameter is CallType
	sal_Int16 nCallType = rPar.Get(3)->GetInteger();

	//SbxObject* pFindObj = NULL;
	SbxVariable* pFindVar = pObj->Find( aNameStr, SbxCLASS_DONTCARE );
	if( pFindVar == NULL )
	{
		StarBASIC::Error( SbERR_PROC_UNDEFINED );
		return;
	}

	switch( nCallType )
	{
		case vbGet:
			{
				SbxValues aVals;
				aVals.eType = SbxVARIANT;
				pFindVar->Get( aVals );

				SbxVariableRef refVar = rPar.Get(0);
				refVar->Put( aVals );
			}
			break;
		case vbLet:
		case vbSet:
			{
				if ( nParCount != 5 )
				{
					StarBASIC::Error( SbERR_BAD_ARGUMENT );
					return;
				}
				SbxVariableRef pValVar = rPar.Get(4);
				if( nCallType == vbLet )
				{
					SbxValues aVals;
					aVals.eType = SbxVARIANT;
					pValVar->Get( aVals );
					pFindVar->Put( aVals );
				}
				else
				{
					SbxVariableRef rFindVar = pFindVar;
					SbiInstance* pInst = pINST;
					SbiRuntime* pRT = pInst ? pInst->pRun : NULL;
					if( pRT != NULL )
						pRT->StepSET_Impl( pValVar, rFindVar, false );
				}
			}
			break;
		case vbMethod:
			{
				SbMethod* pMeth = PTR_CAST(SbMethod,pFindVar);
				if( pMeth == NULL )
				{
					StarBASIC::Error( SbERR_PROC_UNDEFINED );
					return;
				}

				// Setup parameters
				SbxArrayRef xArray;
				sal_uInt16 nMethParamCount = nParCount - 4;
				if( nMethParamCount > 0 )
				{
					xArray = new SbxArray;
					for( sal_uInt16 i = 0 ; i < nMethParamCount ; i++ )
					{
						SbxVariable* pPar = rPar.Get( i + 4 );
						xArray->Put( pPar, i + 1 );
					}
				}

				// Call method
				SbxVariableRef refVar = rPar.Get(0);
				if( xArray.Is() )
					pMeth->SetParameters( xArray );
				pMeth->Call( refVar );
				pMeth->SetParameters( NULL );
			}
			break;
		default:
			StarBASIC::Error( SbERR_PROC_UNDEFINED );
	}
}

RTLFUNC(CBool) // JSM
{
    (void)pBasic;
    (void)bWrite;

	sal_Bool bVal = sal_False;
	if ( rPar.Count() == 2 )
	{
		SbxVariable *pSbxVariable = rPar.Get(1);
		bVal = pSbxVariable->GetBool();
	}
	else
		StarBASIC::Error( SbERR_BAD_ARGUMENT );

	rPar.Get(0)->PutBool(bVal);
}

RTLFUNC(CByte) // JSM
{
    (void)pBasic;
    (void)bWrite;

	sal_uInt8 nByte = 0;
	if ( rPar.Count() == 2 )
	{
		SbxVariable *pSbxVariable = rPar.Get(1);
		nByte = pSbxVariable->GetByte();
	}
	else
		StarBASIC::Error( SbERR_BAD_ARGUMENT );

	rPar.Get(0)->PutByte(nByte);
}

RTLFUNC(CCur)  // JSM
{
    (void)pBasic;
    (void)bWrite;

	SbxINT64 nCur;
	if ( rPar.Count() == 2 )
	{
		SbxVariable *pSbxVariable = rPar.Get(1);
		nCur = pSbxVariable->GetCurrency();
	}
	else
		StarBASIC::Error( SbERR_BAD_ARGUMENT );

	rPar.Get(0)->PutCurrency( nCur );
}

RTLFUNC(CDec)  // JSM
{
    (void)pBasic;
    (void)bWrite;

#ifdef WNT
	SbxDecimal* pDec = NULL;
	if ( rPar.Count() == 2 )
	{
		SbxVariable *pSbxVariable = rPar.Get(1);
		pDec = pSbxVariable->GetDecimal();
	}
	else
		StarBASIC::Error( SbERR_BAD_ARGUMENT );

	rPar.Get(0)->PutDecimal( pDec );
#else
	rPar.Get(0)->PutEmpty();
	StarBASIC::Error(SbERR_NOT_IMPLEMENTED);
#endif
}

RTLFUNC(CDate) // JSM
{
    (void)pBasic;
    (void)bWrite;

	double nVal = 0.0;
	if ( rPar.Count() == 2 )
	{
		SbxVariable *pSbxVariable = rPar.Get(1);
		nVal = pSbxVariable->GetDate();
	}
	else
		StarBASIC::Error( SbERR_BAD_ARGUMENT );

	rPar.Get(0)->PutDate(nVal);
}

RTLFUNC(CDbl)  // JSM
{
    (void)pBasic;
    (void)bWrite;

	double nVal = 0.0;
	if ( rPar.Count() == 2 )
	{
		SbxVariable *pSbxVariable = rPar.Get(1);
		if( pSbxVariable->GetType() == SbxSTRING )
		{
			// AB #41690 , String holen
			String aScanStr = pSbxVariable->GetString();
			SbError Error = SbxValue::ScanNumIntnl( aScanStr, nVal );
			if( Error != SbxERR_OK )
				StarBASIC::Error( Error );
		}
		else
		{
			nVal = pSbxVariable->GetDouble();
		}
	}
	else
		StarBASIC::Error( SbERR_BAD_ARGUMENT );

	rPar.Get(0)->PutDouble(nVal);
}

RTLFUNC(CInt)  // JSM
{
    (void)pBasic;
    (void)bWrite;

	sal_Int16 nVal = 0;
	if ( rPar.Count() == 2 )
	{
		SbxVariable *pSbxVariable = rPar.Get(1);
		nVal = pSbxVariable->GetInteger();
	}
	else
		StarBASIC::Error( SbERR_BAD_ARGUMENT );

	rPar.Get(0)->PutInteger(nVal);
}

RTLFUNC(CLng)  // JSM
{
    (void)pBasic;
    (void)bWrite;

	sal_Int32 nVal = 0;
	if ( rPar.Count() == 2 )
	{
		SbxVariable *pSbxVariable = rPar.Get(1);
		nVal = pSbxVariable->GetLong();
	}
	else
		StarBASIC::Error( SbERR_BAD_ARGUMENT );

	rPar.Get(0)->PutLong(nVal);
}

RTLFUNC(CSng)  // JSM
{
    (void)pBasic;
    (void)bWrite;

	float nVal = (float)0.0;
	if ( rPar.Count() == 2 )
	{
		SbxVariable *pSbxVariable = rPar.Get(1);
		if( pSbxVariable->GetType() == SbxSTRING )
		{
			// AB #41690 , String holen
			double dVal = 0.0;
			String aScanStr = pSbxVariable->GetString();
			SbError Error = SbxValue::ScanNumIntnl( aScanStr, dVal, /*bSingle=*/sal_True );
			if( SbxBase::GetError() == SbxERR_OK && Error != SbxERR_OK )
				StarBASIC::Error( Error );
			nVal = (float)dVal;
		}
		else
		{
			nVal = pSbxVariable->GetSingle();
		}
	}
	else
		StarBASIC::Error( SbERR_BAD_ARGUMENT );

	rPar.Get(0)->PutSingle(nVal);
}

RTLFUNC(CStr)  // JSM
{
    (void)pBasic;
    (void)bWrite;

	String aString;
	if ( rPar.Count() == 2 )
	{
		SbxVariable *pSbxVariable = rPar.Get(1);
		aString = pSbxVariable->GetString();
	}
	else
		StarBASIC::Error( SbERR_BAD_ARGUMENT );

	rPar.Get(0)->PutString(aString);
}

RTLFUNC(CVar)  // JSM
{
    (void)pBasic;
    (void)bWrite;

	SbxValues aVals( SbxVARIANT );
	if ( rPar.Count() == 2 )
	{
		SbxVariable *pSbxVariable = rPar.Get(1);
		pSbxVariable->Get( aVals );
	}
	else
		StarBASIC::Error( SbERR_BAD_ARGUMENT );

	rPar.Get(0)->Put( aVals );
}

RTLFUNC(CVErr)
{
    (void)pBasic;
    (void)bWrite;

	sal_Int16 nErrCode = 0;
	if ( rPar.Count() == 2 )
	{
		SbxVariable *pSbxVariable = rPar.Get(1);
		nErrCode = pSbxVariable->GetInteger();
	}
	else
		StarBASIC::Error( SbERR_BAD_ARGUMENT );

	rPar.Get(0)->PutErr( nErrCode );
}

RTLFUNC(Iif) // JSM
{
    (void)pBasic;
    (void)bWrite;

	if ( rPar.Count() == 4 )
	{
		if (rPar.Get(1)->GetBool())
			*rPar.Get(0) = *rPar.Get(2);
		else
			*rPar.Get(0) = *rPar.Get(3);
	}
	else
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
}

RTLFUNC(GetSystemType)
{
    (void)pBasic;
    (void)bWrite;

	if ( rPar.Count() != 1 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
		// Removed for SRC595
		rPar.Get(0)->PutInteger( -1 );
}

RTLFUNC(GetGUIType)
{
    (void)pBasic;
    (void)bWrite;

	if ( rPar.Count() != 1 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
		// 17.7.2000 Make simple solution for testtool / fat office
#if defined (WNT)
		rPar.Get(0)->PutInteger( 1 );
#elif defined OS2
		rPar.Get(0)->PutInteger( 2 );
#elif defined UNX
		rPar.Get(0)->PutInteger( 4 );
#else
		rPar.Get(0)->PutInteger( -1 );
#endif
	}
}

RTLFUNC(Red)
{
    (void)pBasic;
    (void)bWrite;

	if ( rPar.Count() != 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
		sal_uIntPtr nRGB = (sal_uIntPtr)rPar.Get(1)->GetLong();
		nRGB &= 0x00FF0000;
		nRGB >>= 16;
		rPar.Get(0)->PutInteger( (sal_Int16)nRGB );
	}
}

RTLFUNC(Green)
{
    (void)pBasic;
    (void)bWrite;

	if ( rPar.Count() != 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
		sal_uIntPtr nRGB = (sal_uIntPtr)rPar.Get(1)->GetLong();
		nRGB &= 0x0000FF00;
		nRGB >>= 8;
		rPar.Get(0)->PutInteger( (sal_Int16)nRGB );
	}
}

RTLFUNC(Blue)
{
    (void)pBasic;
    (void)bWrite;

	if ( rPar.Count() != 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
		sal_uIntPtr nRGB = (sal_uIntPtr)rPar.Get(1)->GetLong();
		nRGB &= 0x000000FF;
		rPar.Get(0)->PutInteger( (sal_Int16)nRGB );
	}
}


RTLFUNC(Switch)
{
    (void)pBasic;
    (void)bWrite;

	sal_uInt16 nCount = rPar.Count();
	if( !(nCount & 0x0001 ))
		// Anzahl der Argumente muss ungerade sein
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	sal_uInt16 nCurExpr = 1;
	while( nCurExpr < (nCount-1) )
	{
		if( rPar.Get( nCurExpr )->GetBool())
		{
			(*rPar.Get(0)) = *(rPar.Get(nCurExpr+1));
			return;
		}
		nCurExpr += 2;
	}
	rPar.Get(0)->PutNull();
}

//i#64882# Common wait impl for existing Wait and new WaitUntil
// rtl functions
void Wait_Impl( bool bDurationBased, SbxArray& rPar )
{
	if( rPar.Count() != 2 )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}
	long nWait = 0;
	if ( bDurationBased )
	{
		double dWait = rPar.Get(1)->GetDouble();
		double dNow = Now_Impl();
	 	double dSecs = (double)( ( dWait - dNow ) * (double)( 24.0*3600.0) );
		nWait = (long)( dSecs * 1000 ); // wait in thousands of sec
	}
	else
		nWait = rPar.Get(1)->GetLong();
	if( nWait < 0 )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}

    Timer aTimer;
    aTimer.SetTimeout( nWait );
    aTimer.Start();
    while ( aTimer.IsActive() )
        Application::Yield();
}

//i#64882#
RTLFUNC(Wait)
{
	(void)pBasic;
	(void)bWrite;
	Wait_Impl( false, rPar );
}

//i#64882# add new WaitUntil ( for application.wait )
// share wait_impl with 'normal' oobasic wait
RTLFUNC(WaitUntil)
{
	(void)pBasic;
	(void)bWrite;
	Wait_Impl( true, rPar );
}

RTLFUNC(DoEvents)
{
	(void)pBasic;
	(void)bWrite;
	(void)rPar;
	// Dummy implementation as the following code leads
	// to performance problems for unknown reasons
	//Timer aTimer;
	//aTimer.SetTimeout( 1 );
	//aTimer.Start();
	//while ( aTimer.IsActive() )
	//	Application::Reschedule();
    Application::Reschedule( true );
}

RTLFUNC(GetGUIVersion)
{
    (void)pBasic;
    (void)bWrite;

	if ( rPar.Count() != 1 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
		// Removed for SRC595
		rPar.Get(0)->PutLong( -1 );
	}
}

RTLFUNC(Choose)
{
    (void)pBasic;
    (void)bWrite;

	if ( rPar.Count() < 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	sal_Int16 nIndex = rPar.Get(1)->GetInteger();
	sal_uInt16 nCount = rPar.Count();
	nCount--;
	if( nCount == 1 || nIndex > (nCount-1) || nIndex < 1 )
	{
		rPar.Get(0)->PutNull();
		return;
	}
	(*rPar.Get(0)) = *(rPar.Get(nIndex+1));
}


RTLFUNC(Trim)
{
    (void)pBasic;
    (void)bWrite;

	if ( rPar.Count() < 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
		String aStr( rPar.Get(1)->GetString() );
		aStr.EraseLeadingChars();
		aStr.EraseTrailingChars();
		rPar.Get(0)->PutString( aStr );
	}
}

RTLFUNC(GetSolarVersion)
{
    (void)pBasic;
    (void)bWrite;

	rPar.Get(0)->PutLong( (sal_Int32)SUPD );
}

RTLFUNC(TwipsPerPixelX)
{
    (void)pBasic;
    (void)bWrite;

	sal_Int32 nResult = 0;
	Size aSize( 100,0 );
	MapMode aMap( MAP_TWIP );
	OutputDevice* pDevice = Application::GetDefaultDevice();
	if( pDevice )
	{
		aSize = pDevice->PixelToLogic( aSize, aMap );
		nResult = aSize.Width() / 100;
	}
	rPar.Get(0)->PutLong( nResult );
}

RTLFUNC(TwipsPerPixelY)
{
    (void)pBasic;
    (void)bWrite;

	sal_Int32 nResult = 0;
	Size aSize( 0,100 );
	MapMode aMap( MAP_TWIP );
	OutputDevice* pDevice = Application::GetDefaultDevice();
	if( pDevice )
	{
		aSize = pDevice->PixelToLogic( aSize, aMap );
		nResult = aSize.Height() / 100;
	}
	rPar.Get(0)->PutLong( nResult );
}


RTLFUNC(FreeLibrary)
{
    (void)pBasic;
    (void)bWrite;

	if ( rPar.Count() != 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	pINST->GetDllMgr()->FreeDll( rPar.Get(1)->GetString() );
}
bool IsBaseIndexOne()
{
	bool result = false;
	if ( pINST && pINST->pRun )
	{
		sal_uInt16 res = pINST->pRun->GetBase();
		if ( res )
			result = true;
	}
	return result;
}

RTLFUNC(Array)
{
    (void)pBasic;
    (void)bWrite;

	SbxDimArray* pArray = new SbxDimArray( SbxVARIANT );
	sal_uInt16 nArraySize = rPar.Count() - 1;

	// Option Base zunaechst ignorieren (kennt leider nur der Compiler)
	bool bIncIndex = (IsBaseIndexOne() && SbiRuntime::isVBAEnabled() );
	if( nArraySize )
	{
		if ( bIncIndex )
			pArray->AddDim( 1, nArraySize );
		else
			pArray->AddDim( 0, nArraySize-1 );
	}
	else
	{
		pArray->unoAddDim( 0, -1 );
	}

	// Parameter ins Array uebernehmen
	// ATTENTION: Using type sal_uInt16 for loop variable is
	// mandatory to workaround a problem with the
	// Solaris Intel compiler optimizer! See i104354
	for( sal_uInt16 i = 0 ; i < nArraySize ; i++ )
	{
		SbxVariable* pVar = rPar.Get(i+1);
		SbxVariable* pNew = new SbxVariable( *pVar );
		pNew->SetFlag( SBX_WRITE );
		short index = static_cast< short >(i);
		if ( bIncIndex )
			++index;
		pArray->Put( pNew, &index );
	}

	// Array zurueckliefern
	SbxVariableRef refVar = rPar.Get(0);
	sal_uInt16 nFlags = refVar->GetFlags();
	refVar->ResetFlag( SBX_FIXED );
	refVar->PutObject( pArray );
	refVar->SetFlags( nFlags );
	refVar->SetParameters( NULL );
}


// Featurewunsch #57868
// Die Funktion liefert ein Variant-Array, wenn keine Parameter angegeben
// werden, wird ein leeres Array erzeugt (entsprechend dim a(), entspricht
// einer Sequence der Laenge 0 in Uno).
// Wenn Parameter angegeben sind, wird fuer jeden eine Dimension erzeugt
// DimArray( 2, 2, 4 ) entspricht DIM a( 2, 2, 4 )
// Das Array ist immer vom Typ Variant
RTLFUNC(DimArray)
{
    (void)pBasic;
    (void)bWrite;

	SbxDimArray * pArray = new SbxDimArray( SbxVARIANT );
	sal_uInt16 nArrayDims = rPar.Count() - 1;
	if( nArrayDims > 0 )
	{
		for( sal_uInt16 i = 0; i < nArrayDims ; i++ )
		{
			sal_Int32 ub = rPar.Get(i+1)->GetLong();
			if( ub < 0 )
			{
				StarBASIC::Error( SbERR_OUT_OF_RANGE );
				ub = 0;
			}
			pArray->AddDim32( 0, ub );
		}
	}
	else
		pArray->unoAddDim( 0, -1 );

	// Array zurueckliefern
	SbxVariableRef refVar = rPar.Get(0);
	sal_uInt16 nFlags = refVar->GetFlags();
	refVar->ResetFlag( SBX_FIXED );
	refVar->PutObject( pArray );
	refVar->SetFlags( nFlags );
	refVar->SetParameters( NULL );
}

/*
 * FindObject und FindPropertyObject ermoeglichen es,
 * Objekte und Properties vom Typ Objekt zur Laufzeit
 * ueber ihren Namen als String-Parameter anzusprechen.
 *
 * Bsp.:
 * MyObj.Prop1.Bla = 5
 *
 * entspricht:
 * dim ObjVar as Object
 * dim ObjProp as Object
 * ObjName$ = "MyObj"
 * ObjVar = FindObject( ObjName$ )
 * PropName$ = "Prop1"
 * ObjProp = FindPropertyObject( ObjVar, PropName$ )
 * ObjProp.Bla = 5
 *
 * Dabei koennen die Namen zur Laufzeit dynamisch
 * erzeugt werden und, so dass z.B. ueber Controls
 * "TextEdit1" bis "TextEdit5" in einem Dialog in
 * einer Schleife iteriert werden kann.
 */

// Objekt ueber den Namen ansprechen
// 1. Parameter = Name des Objekts als String
RTLFUNC(FindObject)
{
    (void)pBasic;
    (void)bWrite;

	// Wir brauchen einen Parameter
	if ( rPar.Count() < 2 )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}

	// 1. Parameter ist der Name
	String aNameStr = rPar.Get(1)->GetString();

	// Basic-Suchfunktion benutzen
	SbxBase* pFind =  StarBASIC::FindSBXInCurrentScope( aNameStr );
	SbxObject* pFindObj = NULL;
	if( pFind )
		pFindObj = PTR_CAST(SbxObject,pFind);
	/*
	if( !pFindObj )
	{
		StarBASIC::Error( SbERR_VAR_UNDEFINED );
		return;
	}
	*/

	// Objekt zurueckliefern
	SbxVariableRef refVar = rPar.Get(0);
	refVar->PutObject( pFindObj );
}

// Objekt-Property in einem Objekt ansprechen
// 1. Parameter = Objekt
// 2. Parameter = Name der Property als String
RTLFUNC(FindPropertyObject)
{
    (void)pBasic;
    (void)bWrite;

	// Wir brauchen 2 Parameter
	if ( rPar.Count() < 3 )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}

	// 1. Parameter holen, muss Objekt sein
	SbxBase* pObjVar = (SbxObject*)rPar.Get(1)->GetObject();
	SbxObject* pObj = NULL;
	if( pObjVar )
		pObj = PTR_CAST(SbxObject,pObjVar);
	if( !pObj && pObjVar && pObjVar->ISA(SbxVariable) )
	{
		SbxBase* pObjVarObj = ((SbxVariable*)pObjVar)->GetObject();
		pObj = PTR_CAST(SbxObject,pObjVarObj);
	}
	/*
	if( !pObj )
	{
		StarBASIC::Error( SbERR_VAR_UNDEFINED );
		return;
	}
	*/

	// 2. Parameter ist der Name
	String aNameStr = rPar.Get(2)->GetString();

	// Jetzt muss ein Objekt da sein, sonst Error
	SbxObject* pFindObj = NULL;
	if( pObj )
	{
		// Im Objekt nach Objekt suchen
		SbxVariable* pFindVar = pObj->Find( aNameStr, SbxCLASS_OBJECT );
		pFindObj = PTR_CAST(SbxObject,pFindVar);
	}
	else
		StarBASIC::Error( SbERR_BAD_PARAMETER );

	// Objekt zurueckliefern
	SbxVariableRef refVar = rPar.Get(0);
	refVar->PutObject( pFindObj );
}



sal_Bool lcl_WriteSbxVariable( const SbxVariable& rVar, SvStream* pStrm,
	sal_Bool bBinary, short nBlockLen, sal_Bool bIsArray )
{
	sal_uIntPtr nFPos = pStrm->Tell();

	sal_Bool bIsVariant = !rVar.IsFixed();
	SbxDataType eType = rVar.GetType();

	switch( eType )
	{
		case SbxBOOL:
		case SbxCHAR:
		case SbxBYTE:
				if( bIsVariant )
					*pStrm << (sal_uInt16)SbxBYTE; // VarType Id
				*pStrm << rVar.GetByte();
				break;

		case SbxEMPTY:
		case SbxNULL:
		case SbxVOID:
		case SbxINTEGER:
		case SbxUSHORT:
		case SbxINT:
		case SbxUINT:
				if( bIsVariant )
					*pStrm << (sal_uInt16)SbxINTEGER; // VarType Id
				*pStrm << rVar.GetInteger();
				break;

		case SbxLONG:
		case SbxULONG:
		case SbxLONG64:
		case SbxULONG64:
				if( bIsVariant )
					*pStrm << (sal_uInt16)SbxLONG; // VarType Id
				*pStrm << rVar.GetLong();
				break;

		case SbxSINGLE:
				if( bIsVariant )
					*pStrm << (sal_uInt16)eType; // VarType Id
				*pStrm << rVar.GetSingle();
				break;

		case SbxDOUBLE:
		case SbxCURRENCY:
		case SbxDATE:
				if( bIsVariant )
					*pStrm << (sal_uInt16)eType; // VarType Id
				*pStrm << rVar.GetDouble();
				break;

		case SbxSTRING:
		case SbxLPSTR:
				{
				const String& rStr = rVar.GetString();
				if( !bBinary || bIsArray )
				{
					if( bIsVariant )
						*pStrm << (sal_uInt16)SbxSTRING;
					pStrm->WriteByteString( rStr, gsl_getSystemTextEncoding() );
					//*pStrm << rStr;
				}
				else
				{
					// ohne Laengenangabe! ohne Endekennung!
					// What does that mean for Unicode?! Choosing conversion to ByteString...
					ByteString aByteStr( rStr, gsl_getSystemTextEncoding() );
					*pStrm << (const char*)aByteStr.GetBuffer();
					//*pStrm << (const char*)rStr.GetStr();
				}
				}
				break;

		default:
				StarBASIC::Error( SbERR_BAD_ARGUMENT );
				return sal_False;
	}

	if( nBlockLen )
		pStrm->Seek( nFPos + nBlockLen );
	return pStrm->GetErrorCode() ? sal_False : sal_True;
}

sal_Bool lcl_ReadSbxVariable( SbxVariable& rVar, SvStream* pStrm,
	sal_Bool bBinary, short nBlockLen, sal_Bool bIsArray )
{
    (void)bBinary;
    (void)bIsArray;

	double aDouble;

	sal_uIntPtr nFPos = pStrm->Tell();

	sal_Bool bIsVariant = !rVar.IsFixed();
	SbxDataType eVarType = rVar.GetType();

	SbxDataType eSrcType = eVarType;
	if( bIsVariant )
	{
		sal_uInt16 nTemp;
		*pStrm >> nTemp;
		eSrcType = (SbxDataType)nTemp;
	}

	switch( eSrcType )
	{
		case SbxBOOL:
		case SbxCHAR:
		case SbxBYTE:
				{
				sal_uInt8 aByte;
				*pStrm >> aByte;

				if( bBinary && SbiRuntime::isVBAEnabled() && aByte == 1 && pStrm->IsEof() )
					aByte = 0;

				rVar.PutByte( aByte );
				}
				break;

		case SbxEMPTY:
		case SbxNULL:
		case SbxVOID:
		case SbxINTEGER:
		case SbxUSHORT:
		case SbxINT:
		case SbxUINT:
				{
				sal_Int16 aInt;
				*pStrm >> aInt;
				rVar.PutInteger( aInt );
				}
				break;

		case SbxLONG:
		case SbxULONG:
		case SbxLONG64:
		case SbxULONG64:
				{
				sal_Int32 aInt;
				*pStrm >> aInt;
				rVar.PutLong( aInt );
				}
				break;

		case SbxSINGLE:
				{
				float nS;
				*pStrm >> nS;
				rVar.PutSingle( nS );
				}
				break;

		case SbxDOUBLE:
		case SbxCURRENCY:
				{
				*pStrm >> aDouble;
				rVar.PutDouble( aDouble );
				}
				break;

		case SbxDATE:
				{
				*pStrm >> aDouble;
				rVar.PutDate( aDouble );
				}
				break;

		case SbxSTRING:
		case SbxLPSTR:
				{
				String aStr;
				pStrm->ReadByteString( aStr, gsl_getSystemTextEncoding() );
				rVar.PutString( aStr );
				}
				break;

		default:
				StarBASIC::Error( SbERR_BAD_ARGUMENT );
				return sal_False;
	}

	if( nBlockLen )
		pStrm->Seek( nFPos + nBlockLen );
	return pStrm->GetErrorCode() ? sal_False : sal_True;
}


// nCurDim = 1...n
sal_Bool lcl_WriteReadSbxArray( SbxDimArray& rArr, SvStream* pStrm,
	sal_Bool bBinary, short nCurDim, short* pOtherDims, sal_Bool bWrite )
{
	DBG_ASSERT( nCurDim > 0,"Bad Dim");
	short nLower, nUpper;
	if( !rArr.GetDim( nCurDim, nLower, nUpper ) )
		return sal_False;
	for( short nCur = nLower; nCur <= nUpper; nCur++ )
	{
		pOtherDims[ nCurDim-1 ] = nCur;
		if( nCurDim != 1 )
			lcl_WriteReadSbxArray(rArr, pStrm, bBinary, nCurDim-1, pOtherDims, bWrite);
		else
		{
			SbxVariable* pVar = rArr.Get( (const short*)pOtherDims );
			sal_Bool bRet;
			if( bWrite )
				bRet = lcl_WriteSbxVariable(*pVar, pStrm, bBinary, 0, sal_True );
			else
				bRet = lcl_ReadSbxVariable(*pVar, pStrm, bBinary, 0, sal_True );
			if( !bRet )
				return sal_False;
		}
	}
	return sal_True;
}

void PutGet( SbxArray& rPar, sal_Bool bPut )
{
	// Wir brauchen 3 Parameter
	if ( rPar.Count() != 4 )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}
	sal_Int16 nFileNo = rPar.Get(1)->GetInteger();
	SbxVariable* pVar2 = rPar.Get(2);
	SbxDataType eType2 = pVar2->GetType();
	sal_Bool bHasRecordNo = (sal_Bool)(eType2 != SbxEMPTY && eType2 != SbxERROR);
	long nRecordNo = pVar2->GetLong();
	if ( nFileNo < 1 || ( bHasRecordNo && nRecordNo < 1 ) )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}
	nRecordNo--; // wir moegen's ab 0!
	SbiIoSystem* pIO = pINST->GetIoSystem();
	SbiStream* pSbStrm = pIO->GetStream( nFileNo );
	// das File muss Random (feste Record-Laenge) oder Binary sein
	if ( !pSbStrm || !(pSbStrm->GetMode() & (SBSTRM_BINARY | SBSTRM_RANDOM)) )
	{
		StarBASIC::Error( SbERR_BAD_CHANNEL );
		return;
	}

	SvStream* pStrm = pSbStrm->GetStrm();
	sal_Bool bRandom = pSbStrm->IsRandom();
	short nBlockLen = bRandom ? pSbStrm->GetBlockLen() : 0;

	if( bPut )
	{
		// Datei aufplustern, falls jemand uebers Dateiende hinaus geseekt hat
		pSbStrm->ExpandFile();
	}

	// auf die Startposition seeken
	if( bHasRecordNo )
	{
		sal_uIntPtr nFilePos = bRandom ? (sal_uIntPtr)(nBlockLen*nRecordNo) : (sal_uIntPtr)nRecordNo;
		pStrm->Seek( nFilePos );
	}

	SbxDimArray* pArr = 0;
	SbxVariable* pVar = rPar.Get(3);
	if( pVar->GetType() & SbxARRAY )
	{
		SbxBase* pParObj = pVar->GetObject();
		pArr = PTR_CAST(SbxDimArray,pParObj);
	}

	sal_Bool bRet;

	if( pArr )
	{
		sal_uIntPtr nFPos = pStrm->Tell();
		short nDims = pArr->GetDims();
		short* pDims = new short[ nDims ];
		bRet = lcl_WriteReadSbxArray(*pArr,pStrm,!bRandom,nDims,pDims,bPut);
		delete [] pDims;
		if( nBlockLen )
			pStrm->Seek( nFPos + nBlockLen );
	}
	else
	{
		if( bPut )
			bRet = lcl_WriteSbxVariable(*pVar, pStrm, !bRandom, nBlockLen, sal_False);
		else
			bRet = lcl_ReadSbxVariable(*pVar, pStrm, !bRandom, nBlockLen, sal_False);
	}
	if( !bRet || pStrm->GetErrorCode() )
		StarBASIC::Error( SbERR_IO_ERROR );
}

RTLFUNC(Put)
{
    (void)pBasic;
    (void)bWrite;

	PutGet( rPar, sal_True );
}

RTLFUNC(Get)
{
    (void)pBasic;
    (void)bWrite;

	PutGet( rPar, sal_False );
}

RTLFUNC(Environ)
{
    (void)pBasic;
    (void)bWrite;

	if ( rPar.Count() != 2 )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}
	String aResult;
	// sollte ANSI sein, aber unter Win16 in DLL nicht moeglich
	ByteString aByteStr( rPar.Get(1)->GetString(), gsl_getSystemTextEncoding() );
	const char* pEnvStr = getenv( aByteStr.GetBuffer() );
	if ( pEnvStr )
		aResult = String::CreateFromAscii( pEnvStr );
	rPar.Get(0)->PutString( aResult );
}

static double GetDialogZoomFactor( sal_Bool bX, long nValue )
{
	OutputDevice* pDevice = Application::GetDefaultDevice();
	double nResult = 0;
	if( pDevice )
	{
		Size aRefSize( nValue, nValue );
		Fraction aFracX( 1, 26 );
		Fraction aFracY( 1, 24 );
		MapMode aMap( MAP_APPFONT, Point(), aFracX, aFracY );
		Size aScaledSize = pDevice->LogicToPixel( aRefSize, aMap );
		aRefSize = pDevice->LogicToPixel( aRefSize, MapMode(MAP_TWIP) );

		double nRef, nScaled;
		if( bX )
		{
			nRef = aRefSize.Width();
			nScaled = aScaledSize.Width();
		}
		else
		{
			nRef = aRefSize.Height();
			nScaled = aScaledSize.Height();
		}
		nResult = nScaled / nRef;
	}
	return nResult;
}


RTLFUNC(GetDialogZoomFactorX)
{
    (void)pBasic;
    (void)bWrite;

	if ( rPar.Count() != 2 )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}
	rPar.Get(0)->PutDouble( GetDialogZoomFactor( sal_True, rPar.Get(1)->GetLong() ));
}

RTLFUNC(GetDialogZoomFactorY)
{
    (void)pBasic;
    (void)bWrite;

	if ( rPar.Count() != 2 )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}
	rPar.Get(0)->PutDouble( GetDialogZoomFactor( sal_False, rPar.Get(1)->GetLong()));
}


RTLFUNC(EnableReschedule)
{
    (void)pBasic;
    (void)bWrite;

	rPar.Get(0)->PutEmpty();
	if ( rPar.Count() != 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	if( pINST )
		pINST->EnableReschedule( rPar.Get(1)->GetBool() );
}

RTLFUNC(GetSystemTicks)
{
    (void)pBasic;
    (void)bWrite;

	if ( rPar.Count() != 1 )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}
	rPar.Get(0)->PutLong( Time::GetSystemTicks() );
}

RTLFUNC(GetPathSeparator)
{
    (void)pBasic;
    (void)bWrite;

	if ( rPar.Count() != 1 )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}
	rPar.Get(0)->PutString( DirEntry::GetAccessDelimiter() );
}

RTLFUNC(ResolvePath)
{
    (void)pBasic;
    (void)bWrite;

	if ( rPar.Count() == 2 )
	{
		String aStr = rPar.Get(1)->GetString();
		DirEntry aEntry( aStr );
		//if( aEntry.IsVirtual() )
			//aStr = aEntry.GetRealPathFromVirtualURL();
		rPar.Get(0)->PutString( aStr );
	}
	else
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
}

RTLFUNC(TypeLen)
{
    (void)pBasic;
    (void)bWrite;

	if ( rPar.Count() != 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
		SbxDataType eType = rPar.Get(1)->GetType();
		sal_Int16 nLen = 0;
		switch( eType )
		{
			case SbxEMPTY:
			case SbxNULL:
			case SbxVECTOR:
			case SbxARRAY:
			case SbxBYREF:
			case SbxVOID:
			case SbxHRESULT:
			case SbxPOINTER:
			case SbxDIMARRAY:
			case SbxCARRAY:
			case SbxUSERDEF:
				nLen = 0;
				break;

			case SbxINTEGER:
			case SbxERROR:
			case SbxUSHORT:
			case SbxINT:
			case SbxUINT:
				nLen = 2;
				break;

			case SbxLONG:
			case SbxSINGLE:
			case SbxULONG:
				nLen = 4;
				break;

			case SbxDOUBLE:
			case SbxCURRENCY:
			case SbxDATE:
			case SbxLONG64:
			case SbxULONG64:
				nLen = 8;
				break;

			case SbxOBJECT:
			case SbxVARIANT:
			case SbxDATAOBJECT:
				nLen = 0;
				break;

			case SbxCHAR:
			case SbxBYTE:
			case SbxBOOL:
				nLen = 1;
				break;

			case SbxLPSTR:
			case SbxLPWSTR:
			case SbxCoreSTRING:
			case SbxSTRING:
				nLen = (sal_Int16)rPar.Get(1)->GetString().Len();
				break;

			default:
				nLen = 0;
		}
		rPar.Get(0)->PutInteger( nLen );
	}
}


// Uno-Struct eines beliebigen Typs erzeugen
// 1. Parameter == Klassename, weitere Parameter zur Initialisierung
RTLFUNC(CreateUnoStruct)
{
    (void)pBasic;
    (void)bWrite;

	RTL_Impl_CreateUnoStruct( pBasic, rPar, bWrite );
}

// Uno-Service erzeugen
// 1. Parameter == Service-Name
RTLFUNC(CreateUnoService)
{
    (void)pBasic;
    (void)bWrite;

	RTL_Impl_CreateUnoService( pBasic, rPar, bWrite );
}

RTLFUNC(CreateUnoServiceWithArguments)
{
    (void)pBasic;
    (void)bWrite;

	RTL_Impl_CreateUnoServiceWithArguments( pBasic, rPar, bWrite );
}


RTLFUNC(CreateUnoValue)
{
    (void)pBasic;
    (void)bWrite;

	RTL_Impl_CreateUnoValue( pBasic, rPar, bWrite );
}


// ServiceManager liefern (keine Parameter)
RTLFUNC(GetProcessServiceManager)
{
    (void)pBasic;
    (void)bWrite;

	RTL_Impl_GetProcessServiceManager( pBasic, rPar, bWrite );
}

// PropertySet erzeugen
// 1. Parameter == Sequence<PropertyValue>
RTLFUNC(CreatePropertySet)
{
    (void)pBasic;
    (void)bWrite;

	RTL_Impl_CreatePropertySet( pBasic, rPar, bWrite );
}

// Abfragen, ob ein Interface unterstuetzt wird
// Mehrere Interface-Namen als Parameter
RTLFUNC(HasUnoInterfaces)
{
    (void)pBasic;
    (void)bWrite;

	RTL_Impl_HasInterfaces( pBasic, rPar, bWrite );
}

// Abfragen, ob ein Basic-Objekt ein Uno-Struct repraesentiert
RTLFUNC(IsUnoStruct)
{
    (void)pBasic;
    (void)bWrite;

	RTL_Impl_IsUnoStruct( pBasic, rPar, bWrite );
}

// Abfragen, ob zwei Uno-Objekte identisch sind
RTLFUNC(EqualUnoObjects)
{
    (void)pBasic;
    (void)bWrite;

	RTL_Impl_EqualUnoObjects( pBasic, rPar, bWrite );
}

// Instantiate "com.sun.star.awt.UnoControlDialog" on basis
// of a DialogLibrary entry: Convert from XML-ByteSequence
// and attach events. Implemented in classes\eventatt.cxx
void RTL_Impl_CreateUnoDialog( StarBASIC* pBasic, SbxArray& rPar, sal_Bool bWrite );

RTLFUNC(CreateUnoDialog)
{
    (void)pBasic;
    (void)bWrite;

	RTL_Impl_CreateUnoDialog( pBasic, rPar, bWrite );
}

// Return the application standard lib as root scope
RTLFUNC(GlobalScope)
{
    (void)pBasic;
    (void)bWrite;

    SbxObject* p = pBasic;
    while( p->GetParent() )
	    p = p->GetParent();

    SbxVariableRef refVar = rPar.Get(0);
    refVar->PutObject( p );
}

// Helper functions to convert Url from/to system paths
RTLFUNC(ConvertToUrl)
{
    (void)pBasic;
    (void)bWrite;

	if ( rPar.Count() == 2 )
	{
		String aStr = rPar.Get(1)->GetString();
        INetURLObject aURLObj( aStr, INET_PROT_FILE );
	    ::rtl::OUString aFileURL = aURLObj.GetMainURL( INetURLObject::NO_DECODE );
	    if( aFileURL.isEmpty() )
            ::osl::File::getFileURLFromSystemPath( aFileURL, aFileURL );
	    if( aFileURL.isEmpty() )
            aFileURL = aStr;
		rPar.Get(0)->PutString( String(aFileURL) );
	}
	else
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
}

RTLFUNC(ConvertFromUrl)
{
    (void)pBasic;
    (void)bWrite;

	if ( rPar.Count() == 2 )
	{
		String aStr = rPar.Get(1)->GetString();
	    ::rtl::OUString aSysPath;
	    ::osl::File::getSystemPathFromFileURL( aStr, aSysPath );
	    if( aSysPath.isEmpty() )
            aSysPath = aStr;
		rPar.Get(0)->PutString( String(aSysPath) );
	}
	else
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
}


// Provide DefaultContext
RTLFUNC(GetDefaultContext)
{
    (void)pBasic;
    (void)bWrite;

	RTL_Impl_GetDefaultContext( pBasic, rPar, bWrite );
}

#ifdef DBG_TRACE_BASIC
RTLFUNC(TraceCommand)
{
	RTL_Impl_TraceCommand( pBasic, rPar, bWrite );
}
#endif

RTLFUNC(Join)
{
    (void)pBasic;
    (void)bWrite;

	sal_uInt16 nParCount = rPar.Count();
	if ( nParCount != 3 && nParCount != 2 )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}
	SbxBase* pParObj = rPar.Get(1)->GetObject();
	SbxDimArray* pArr = PTR_CAST(SbxDimArray,pParObj);
	if( pArr )
	{
		if( pArr->GetDims() != 1 )
			StarBASIC::Error( SbERR_WRONG_DIMS );	// Syntax Error?!

		String aDelim;
		if( nParCount == 3 )
			aDelim = rPar.Get(2)->GetString();
		else
			aDelim = String::CreateFromAscii( " " );

		String aRetStr;
		short nLower, nUpper;
		pArr->GetDim( 1, nLower, nUpper );
		for( short i = nLower ; i <= nUpper ; ++i )
		{
			String aStr = pArr->Get( &i )->GetString();
			aRetStr += aStr;
			if( i != nUpper )
				aRetStr += aDelim;
		}
		rPar.Get(0)->PutString( aRetStr );
	}
	else
		StarBASIC::Error( SbERR_MUST_HAVE_DIMS );
}


RTLFUNC(Split)
{
    (void)pBasic;
    (void)bWrite;

	sal_uInt16 nParCount = rPar.Count();
	if ( nParCount < 2 )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}

	String aExpression = rPar.Get(1)->GetString();
	short nArraySize = 0;
	StringVector vRet;
	if( aExpression.Len() )
	{
		String aDelim;
		if( nParCount >= 3 )
			aDelim = rPar.Get(2)->GetString();
		else
			aDelim = String::CreateFromAscii( " " );

		sal_Int32 nCount = -1;
		if( nParCount == 4 )
			nCount = rPar.Get(3)->GetLong();

		xub_StrLen nDelimLen = aDelim.Len();
		if( nDelimLen )
		{
			xub_StrLen iSearch = STRING_NOTFOUND;
			xub_StrLen iStart = 0;
			do
			{
				bool bBreak = false;
				if( nCount >= 0 && nArraySize == nCount - 1 )
					bBreak = true;

				iSearch = aExpression.Search( aDelim, iStart );
				String aSubStr;
				if( iSearch != STRING_NOTFOUND && !bBreak )
				{
					aSubStr = aExpression.Copy( iStart, iSearch - iStart );
					iStart = iSearch + nDelimLen;
				}
				else
				{
					aSubStr = aExpression.Copy( iStart );
				}
				vRet.push_back( aSubStr );
				nArraySize++;

				if( bBreak )
					break;
			}
			while( iSearch != STRING_NOTFOUND );
		}
		else
		{
			vRet.push_back( aExpression );
			nArraySize = 1;
		}
	}

	SbxDimArray* pArray = new SbxDimArray( SbxVARIANT );
	pArray->unoAddDim( 0, nArraySize-1 );

	// Parameter ins Array uebernehmen
	for( short i = 0 ; i < nArraySize ; i++ )
	{
		SbxVariableRef xVar = new SbxVariable( SbxVARIANT );
		xVar->PutString( vRet[i] );
		pArray->Put( (SbxVariable*)xVar, &i );
	}

	// Array zurueckliefern
	SbxVariableRef refVar = rPar.Get(0);
	sal_uInt16 nFlags = refVar->GetFlags();
	refVar->ResetFlag( SBX_FIXED );
	refVar->PutObject( pArray );
	refVar->SetFlags( nFlags );
	refVar->SetParameters( NULL );
}

// MonthName(month[, abbreviate])
RTLFUNC(MonthName)
{
    (void)pBasic;
    (void)bWrite;

	sal_uInt16 nParCount = rPar.Count();
	if( nParCount != 2 && nParCount != 3 )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}

	Reference< XCalendar > xCalendar = getLocaleCalendar();
	if( !xCalendar.is() )
	{
		StarBASIC::Error( SbERR_INTERNAL_ERROR );
		return;
	}
	Sequence< CalendarItem > aMonthSeq = xCalendar->getMonths();
	sal_Int32 nMonthCount = aMonthSeq.getLength();

	sal_Int16 nVal = rPar.Get(1)->GetInteger();
	if( nVal < 1 || nVal > nMonthCount )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}

	sal_Bool bAbbreviate = false;
	if( nParCount == 3 )
		bAbbreviate = rPar.Get(2)->GetBool();

	const CalendarItem* pCalendarItems = aMonthSeq.getConstArray();
	const CalendarItem& rItem = pCalendarItems[nVal - 1];

	::rtl::OUString aRetStr = ( bAbbreviate ? rItem.AbbrevName : rItem.FullName );
	rPar.Get(0)->PutString( String(aRetStr) );
}

// WeekdayName(weekday, abbreviate, firstdayofweek)
RTLFUNC(WeekdayName)
{
    (void)pBasic;
    (void)bWrite;

	sal_uInt16 nParCount = rPar.Count();
	if( nParCount < 2 || nParCount > 4 )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}

	Reference< XCalendar > xCalendar = getLocaleCalendar();
	if( !xCalendar.is() )
	{
		StarBASIC::Error( SbERR_INTERNAL_ERROR );
		return;
	}

	Sequence< CalendarItem > aDaySeq = xCalendar->getDays();
	sal_Int16 nDayCount = (sal_Int16)aDaySeq.getLength();
	sal_Int16 nDay = rPar.Get(1)->GetInteger();
	sal_Int16 nFirstDay = 0;
	if( nParCount == 4 )
	{
		nFirstDay = rPar.Get(3)->GetInteger();
		if( nFirstDay < 0 || nFirstDay > 7 )
		{
			StarBASIC::Error( SbERR_BAD_ARGUMENT );
			return;
		}
	}
	if( nFirstDay == 0 )
		nFirstDay = sal_Int16( xCalendar->getFirstDayOfWeek() + 1 );

	nDay = 1 + (nDay + nDayCount + nFirstDay - 2) % nDayCount;
	if( nDay < 1 || nDay > nDayCount )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}

	sal_Bool bAbbreviate = false;
	if( nParCount >= 3 )
	{
		SbxVariable* pPar2 = rPar.Get(2);
		if( !pPar2->IsErr() )
			bAbbreviate = pPar2->GetBool();
	}

	const CalendarItem* pCalendarItems = aDaySeq.getConstArray();
	const CalendarItem& rItem = pCalendarItems[nDay - 1];

	::rtl::OUString aRetStr = ( bAbbreviate ? rItem.AbbrevName : rItem.FullName );
	rPar.Get(0)->PutString( String(aRetStr) );
}

sal_Int16 implGetWeekDay( double aDate, bool bFirstDayParam = false, sal_Int16 nFirstDay = 0 )
{
	Date aRefDate( 1,1,1900 );
	long nDays = (long) aDate;
	nDays -= 2;	// normieren: 1.1.1900 => 0
	aRefDate += nDays;
	DayOfWeek aDay = aRefDate.GetDayOfWeek();
	sal_Int16 nDay;
	if ( aDay != SUNDAY )
		nDay = (sal_Int16)aDay + 2;
	else
		nDay = 1;	// 1==Sonntag

	// #117253 Optional 2. parameter "firstdayofweek"
	if( bFirstDayParam )
	{
		if( nFirstDay < 0 || nFirstDay > 7 )
		{
			StarBASIC::Error( SbERR_BAD_ARGUMENT );
			return 0;
		}
		if( nFirstDay == 0 )
		{
			Reference< XCalendar > xCalendar = getLocaleCalendar();
			if( !xCalendar.is() )
			{
				StarBASIC::Error( SbERR_INTERNAL_ERROR );
				return 0;
			}
			nFirstDay = sal_Int16( xCalendar->getFirstDayOfWeek() + 1 );
		}
		nDay = 1 + (nDay + 7 - nFirstDay) % 7;
	}
	return nDay;
}

RTLFUNC(Weekday)
{
    (void)pBasic;
    (void)bWrite;

	sal_uInt16 nParCount = rPar.Count();
	if ( nParCount < 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
		double aDate = rPar.Get(1)->GetDate();

		bool bFirstDay = false;
		sal_Int16 nFirstDay = 0;
		if ( nParCount > 2 )
		{
			nFirstDay = rPar.Get(2)->GetInteger();
			bFirstDay = true;
		}
		sal_Int16 nDay = implGetWeekDay( aDate, bFirstDay, nFirstDay );
		rPar.Get(0)->PutInteger( nDay );
	}
}


enum Interval
{
	INTERVAL_NONE,
	INTERVAL_YYYY,
	INTERVAL_Q,
	INTERVAL_M,
	INTERVAL_Y,
	INTERVAL_D,
	INTERVAL_W,
	INTERVAL_WW,
	INTERVAL_H,
	INTERVAL_N,
	INTERVAL_S
};

struct IntervalInfo
{
	Interval	meInterval;
	const char* mpStringCode;
	double		mdValue;
	bool		mbSimple;

	IntervalInfo( Interval eInterval, const char* pStringCode, double dValue, bool bSimple )
		: meInterval( eInterval )
		, mpStringCode( pStringCode )
		, mdValue( dValue )
		, mbSimple( bSimple )
	{}
};

static IntervalInfo pIntervalTable[] =
{
	IntervalInfo( INTERVAL_YYYY,	"yyyy",		 0.0,				false ),	// Year
	IntervalInfo( INTERVAL_Q,		"q",		 0.0,				false ),	// Quarter
	IntervalInfo( INTERVAL_M,		"m",		 0.0,				false ),	// Month
	IntervalInfo( INTERVAL_Y,		"y",		 1.0,				true ),		// Day of year
	IntervalInfo( INTERVAL_D,		"d",		 1.0,				true ),		// Day
	IntervalInfo( INTERVAL_W,		"w",		 1.0,				true ),		// Weekday
	IntervalInfo( INTERVAL_WW,		"ww",		 7.0,				true ),		// Week
	IntervalInfo( INTERVAL_H,		"h",		(1.0 /    24.0),	true ),		// Hour
	IntervalInfo( INTERVAL_N,		"n",		(1.0 /  1440.0),	true),		// Minute
	IntervalInfo( INTERVAL_S,		"s",		(1.0 / 86400.0),	true ),		// Second
	IntervalInfo( INTERVAL_NONE, NULL, 0.0, false )
};

IntervalInfo* getIntervalInfo( const String& rStringCode )
{
	IntervalInfo* pInfo = NULL;
	sal_Int16 i = 0;
	while( (pInfo = pIntervalTable + i)->mpStringCode != NULL )
	{
		if( rStringCode.EqualsIgnoreCaseAscii( pInfo->mpStringCode ) )
			break;
		i++;
	}
	return pInfo;
}

// From methods.cxx
sal_Bool implDateSerial( sal_Int16 nYear, sal_Int16 nMonth, sal_Int16 nDay, double& rdRet );
sal_Int16 implGetDateDay( double aDate );
sal_Int16 implGetDateMonth( double aDate );
sal_Int16 implGetDateYear( double aDate );

sal_Int16 implGetHour( double dDate );
sal_Int16 implGetMinute( double dDate );
sal_Int16 implGetSecond( double dDate );


inline void implGetDayMonthYear( sal_Int16& rnYear, sal_Int16& rnMonth, sal_Int16& rnDay, double dDate )
{
	rnDay   = implGetDateDay( dDate );
	rnMonth = implGetDateMonth( dDate );
	rnYear  = implGetDateYear( dDate );
}

inline sal_Int16 limitToINT16( sal_Int32 n32 )
{
	if( n32 > 32767 )
		n32 = 32767;
	else if( n32 < -32768 )
		n32 = -32768;
	return (sal_Int16)n32;
}

RTLFUNC(DateAdd)
{
    (void)pBasic;
    (void)bWrite;

	sal_uInt16 nParCount = rPar.Count();
	if( nParCount != 4 )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}

	String aStringCode = rPar.Get(1)->GetString();
	IntervalInfo* pInfo = getIntervalInfo( aStringCode );
	if( !pInfo )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}

	sal_Int32 lNumber = rPar.Get(2)->GetLong();
	double dDate = rPar.Get(3)->GetDate();
	double dNewDate = 0;
	if( pInfo->mbSimple )
	{
		double dAdd = pInfo->mdValue * lNumber;
		dNewDate = dDate + dAdd;
	}
	else
	{
		// Keep hours, minutes, seconds
		double dHoursMinutesSeconds = dDate - floor( dDate );

		sal_Bool bOk = sal_True;
		sal_Int16 nYear, nMonth, nDay;
		sal_Int16 nTargetYear16 = 0, nTargetMonth = 0;
		implGetDayMonthYear( nYear, nMonth, nDay, dDate );
		switch( pInfo->meInterval )
		{
			case INTERVAL_YYYY:
			{
				sal_Int32 nTargetYear = lNumber + nYear;
				nTargetYear16 = limitToINT16( nTargetYear );
				nTargetMonth = nMonth;
				bOk = implDateSerial( nTargetYear16, nTargetMonth, nDay, dNewDate );
				break;
			}
			case INTERVAL_Q:
			case INTERVAL_M:
			{
				bool bNeg = (lNumber < 0);
				if( bNeg )
					lNumber = -lNumber;
				sal_Int32 nYearsAdd;
				sal_Int16 nMonthAdd;
				if( pInfo->meInterval == INTERVAL_Q )
				{
					nYearsAdd = lNumber / 4;
					nMonthAdd = (sal_Int16)( 3 * (lNumber % 4) );
				}
				else
				{
					nYearsAdd = lNumber / 12;
					nMonthAdd = (sal_Int16)( lNumber % 12 );
				}

				sal_Int32 nTargetYear;
				if( bNeg )
				{
					nTargetMonth = nMonth - nMonthAdd;
					if( nTargetMonth <= 0 )
					{
						nTargetMonth += 12;
						nYearsAdd++;
					}
					nTargetYear = (sal_Int32)nYear - nYearsAdd;
				}
				else
				{
					nTargetMonth = nMonth + nMonthAdd;
					if( nTargetMonth > 12 )
					{
						nTargetMonth -= 12;
						nYearsAdd++;
					}
					nTargetYear = (sal_Int32)nYear + nYearsAdd;
				}
				nTargetYear16 = limitToINT16( nTargetYear );
				bOk = implDateSerial( nTargetYear16, nTargetMonth, nDay, dNewDate );
				break;
			}
			default: break;
		}

		if( bOk )
		{
			// Overflow?
			sal_Int16 nNewYear, nNewMonth, nNewDay;
			implGetDayMonthYear( nNewYear, nNewMonth, nNewDay, dNewDate );
			if( nNewYear > 9999 || nNewYear < 100 )
			{
				StarBASIC::Error( SbERR_BAD_ARGUMENT );
				return;
			}
			sal_Int16 nCorrectionDay = nDay;
			while( nNewMonth > nTargetMonth )
			{
				nCorrectionDay--;
				implDateSerial( nTargetYear16, nTargetMonth, nCorrectionDay, dNewDate );
				implGetDayMonthYear( nNewYear, nNewMonth, nNewDay, dNewDate );
			}
			dNewDate += dHoursMinutesSeconds;
		}
	}

	rPar.Get(0)->PutDate( dNewDate );
}

inline double RoundImpl( double d )
{
	return ( d >= 0 ) ? floor( d + 0.5 ) : -floor( -d + 0.5 );
}

RTLFUNC(DateDiff)
{
    (void)pBasic;
    (void)bWrite;

	// DateDiff(interval, date1, date2[, firstdayofweek[, firstweekofyear]])

	sal_uInt16 nParCount = rPar.Count();
	if( nParCount < 4 || nParCount > 6 )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}

	String aStringCode = rPar.Get(1)->GetString();
	IntervalInfo* pInfo = getIntervalInfo( aStringCode );
	if( !pInfo )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}

	double dDate1 = rPar.Get(2)->GetDate();
	double dDate2 = rPar.Get(3)->GetDate();

	double dRet = 0.0;
	switch( pInfo->meInterval )
	{
		case INTERVAL_YYYY:
		{
			sal_Int16 nYear1 = implGetDateYear( dDate1 );
			sal_Int16 nYear2 = implGetDateYear( dDate2 );
			dRet = nYear2 - nYear1;
			break;
		}
		case INTERVAL_Q:
		{
			sal_Int16 nYear1 = implGetDateYear( dDate1 );
			sal_Int16 nYear2 = implGetDateYear( dDate2 );
			sal_Int16 nQ1 = 1 + (implGetDateMonth( dDate1 ) - 1) / 3;
			sal_Int16 nQ2 = 1 + (implGetDateMonth( dDate2 ) - 1) / 3;
			sal_Int16 nQGes1 = 4 * nYear1 + nQ1;
			sal_Int16 nQGes2 = 4 * nYear2 + nQ2;
			dRet = nQGes2 - nQGes1;
			break;
		}
		case INTERVAL_M:
		{
			sal_Int16 nYear1 = implGetDateYear( dDate1 );
			sal_Int16 nYear2 = implGetDateYear( dDate2 );
			sal_Int16 nMonth1 = implGetDateMonth( dDate1 );
			sal_Int16 nMonth2 = implGetDateMonth( dDate2 );
			sal_Int16 nMonthGes1 = 12 * nYear1 + nMonth1;
			sal_Int16 nMonthGes2 = 12 * nYear2 + nMonth2;
			dRet = nMonthGes2 - nMonthGes1;
			break;
		}
		case INTERVAL_Y:
		case INTERVAL_D:
		{
			double dDays1 = floor( dDate1 );
			double dDays2 = floor( dDate2 );
			dRet = dDays2 - dDays1;
			break;
		}
		case INTERVAL_W:
		case INTERVAL_WW:
		{
			double dDays1 = floor( dDate1 );
			double dDays2 = floor( dDate2 );
			if( pInfo->meInterval == INTERVAL_WW )
			{
				sal_Int16 nFirstDay = 1;	// Default
				if( nParCount >= 5 )
				{
					nFirstDay = rPar.Get(4)->GetInteger();
					if( nFirstDay < 0 || nFirstDay > 7 )
					{
						StarBASIC::Error( SbERR_BAD_ARGUMENT );
						return;
					}
					if( nFirstDay == 0 )
					{
						Reference< XCalendar > xCalendar = getLocaleCalendar();
						if( !xCalendar.is() )
						{
							StarBASIC::Error( SbERR_INTERNAL_ERROR );
							return;
						}
						nFirstDay = sal_Int16( xCalendar->getFirstDayOfWeek() + 1 );
					}
				}
				sal_Int16 nDay1 = implGetWeekDay( dDate1 );
				sal_Int16 nDay1_Diff = nDay1 - nFirstDay;
				if( nDay1_Diff < 0 )
					nDay1_Diff += 7;
				dDays1 -= nDay1_Diff;

				sal_Int16 nDay2 = implGetWeekDay( dDate2 );
				sal_Int16 nDay2_Diff = nDay2 - nFirstDay;
				if( nDay2_Diff < 0 )
					nDay2_Diff += 7;
				dDays2 -= nDay2_Diff;
			}

			double dDiff = dDays2 - dDays1;
			dRet = ( dDiff >= 0 ) ? floor( dDiff / 7.0 ) : -floor( -dDiff / 7.0 );
			break;
		}
		case INTERVAL_H:
		{
			double dFactor = 24.0;
			dRet = RoundImpl( dFactor * (dDate2 - dDate1) );
			break;
		}
		case INTERVAL_N:
		{
			double dFactor =1440.0;
			dRet = RoundImpl( dFactor * (dDate2 - dDate1) );
			break;
		}
		case INTERVAL_S:
		{
			double dFactor = 86400.0;
			dRet = RoundImpl( dFactor * (dDate2 - dDate1) );
			break;
		}
		case INTERVAL_NONE:
			break;
	}
	rPar.Get(0)->PutDouble( dRet );
}

double implGetDateOfFirstDayInFirstWeek
	( sal_Int16 nYear, sal_Int16& nFirstDay, sal_Int16& nFirstWeek, bool* pbError = NULL )
{
	SbError nError = 0;
	if( nFirstDay < 0 || nFirstDay > 7 )
		nError = SbERR_BAD_ARGUMENT;

	if( nFirstWeek < 0 || nFirstWeek > 3 )
		nError = SbERR_BAD_ARGUMENT;

	Reference< XCalendar > xCalendar;
	if( nFirstDay == 0 || nFirstWeek == 0 )
	{
		xCalendar = getLocaleCalendar();
		if( !xCalendar.is() )
			nError = SbERR_BAD_ARGUMENT;
	}

	if( nError != 0 )
	{
		StarBASIC::Error( nError );
		if( pbError )
			*pbError = true;
		return 0.0;
	}

	if( nFirstDay == 0 )
		nFirstDay = sal_Int16( xCalendar->getFirstDayOfWeek() + 1 );

	sal_Int16 nFirstWeekMinDays = 0;	// Not used for vbFirstJan1 = default
	if( nFirstWeek == 0 )
	{
		nFirstWeekMinDays =	xCalendar->getMinimumNumberOfDaysForFirstWeek();
		if( nFirstWeekMinDays == 1 )
		{
			nFirstWeekMinDays = 0;
			nFirstWeek = 1;
		}
		else if( nFirstWeekMinDays == 4 )
			nFirstWeek = 2;
		else if( nFirstWeekMinDays == 7 )
			nFirstWeek = 3;
	}
	else if( nFirstWeek == 2 )
		nFirstWeekMinDays =	4;		// vbFirstFourDays
	else if( nFirstWeek == 3 )
		nFirstWeekMinDays =	7;		// vbFirstFourDays

	double dBaseDate;
	implDateSerial( nYear, 1, 1, dBaseDate );
	double dRetDate = dBaseDate;

	sal_Int16 nWeekDay0101 = implGetWeekDay( dBaseDate );
	sal_Int16 nDayDiff = nWeekDay0101 - nFirstDay;
	if( nDayDiff < 0 )
		nDayDiff += 7;

	if( nFirstWeekMinDays )
	{
		sal_Int16 nThisWeeksDaysInYearCount = 7 - nDayDiff;
		if( nThisWeeksDaysInYearCount < nFirstWeekMinDays )
			nDayDiff -= 7;
	}
	dRetDate = dBaseDate - nDayDiff;
	return dRetDate;
}

RTLFUNC(DatePart)
{
    (void)pBasic;
    (void)bWrite;

	// DatePart(interval, date[,firstdayofweek[, firstweekofyear]])

	sal_uInt16 nParCount = rPar.Count();
	if( nParCount < 3 || nParCount > 5 )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}

	String aStringCode = rPar.Get(1)->GetString();
	IntervalInfo* pInfo = getIntervalInfo( aStringCode );
	if( !pInfo )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}

	double dDate = rPar.Get(2)->GetDate();

	sal_Int32 nRet = 0;
	switch( pInfo->meInterval )
	{
		case INTERVAL_YYYY:
		{
			nRet = implGetDateYear( dDate );
			break;
		}
		case INTERVAL_Q:
		{
			nRet = 1 + (implGetDateMonth( dDate ) - 1) / 3;
			break;
		}
		case INTERVAL_M:
		{
			nRet = implGetDateMonth( dDate );
			break;
		}
		case INTERVAL_Y:
		{
			sal_Int16 nYear = implGetDateYear( dDate );
			double dBaseDate;
			implDateSerial( nYear, 1, 1, dBaseDate );
			nRet = 1 + sal_Int32( dDate - dBaseDate );
			break;
		}
		case INTERVAL_D:
		{
			nRet = implGetDateDay( dDate );
			break;
		}
		case INTERVAL_W:
		{
			bool bFirstDay = false;
			sal_Int16 nFirstDay = 1;	// Default
			if( nParCount >= 4 )
			{
				nFirstDay = rPar.Get(3)->GetInteger();
				bFirstDay = true;
			}
			nRet = implGetWeekDay( dDate, bFirstDay, nFirstDay );
			break;
		}
		case INTERVAL_WW:
		{
			sal_Int16 nFirstDay = 1;	// Default
			if( nParCount >= 4 )
				nFirstDay = rPar.Get(3)->GetInteger();

			sal_Int16 nFirstWeek = 1;	// Default
			if( nParCount == 5 )
				nFirstWeek = rPar.Get(4)->GetInteger();

			sal_Int16 nYear = implGetDateYear( dDate );
			bool bError = false;
			double dYearFirstDay = implGetDateOfFirstDayInFirstWeek( nYear, nFirstDay, nFirstWeek, &bError );
			if( !bError )
			{
				if( dYearFirstDay > dDate )
				{
					// Date belongs to last year's week
					dYearFirstDay = implGetDateOfFirstDayInFirstWeek( nYear - 1, nFirstDay, nFirstWeek );
				}
				else if( nFirstWeek != 1 )
				{
					// Check if date belongs to next year
					double dNextYearFirstDay = implGetDateOfFirstDayInFirstWeek( nYear + 1, nFirstDay, nFirstWeek );
					if( dDate >= dNextYearFirstDay )
						dYearFirstDay = dNextYearFirstDay;
				}

				// Calculate week
				double dDiff = dDate - dYearFirstDay;
				nRet = 1 + sal_Int32( dDiff / 7 );
			}
			break;
		}
		case INTERVAL_H:
		{
			nRet = implGetHour( dDate );
			break;
		}
		case INTERVAL_N:
		{
			nRet = implGetMinute( dDate );
			break;
		}
		case INTERVAL_S:
		{
			nRet = implGetSecond( dDate );
			break;
		}
		case INTERVAL_NONE:
			break;
	}
	rPar.Get(0)->PutLong( nRet );
}

// FormatDateTime(Date[,NamedFormat])
RTLFUNC(FormatDateTime)
{
    (void)pBasic;
    (void)bWrite;

	sal_uInt16 nParCount = rPar.Count();
	if( nParCount < 2 || nParCount > 3 )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}

	double dDate = rPar.Get(1)->GetDate();
	sal_Int16 nNamedFormat = 0;
	if( nParCount > 2 )
	{
		nNamedFormat = rPar.Get(2)->GetInteger();
		if( nNamedFormat < 0 || nNamedFormat > 4 )
		{
			StarBASIC::Error( SbERR_BAD_ARGUMENT );
			return;
		}
	}

	Reference< XCalendar > xCalendar = getLocaleCalendar();
	if( !xCalendar.is() )
	{
		StarBASIC::Error( SbERR_INTERNAL_ERROR );
		return;
	}

	String aRetStr;
	SbxVariableRef pSbxVar = new SbxVariable( SbxSTRING );
	switch( nNamedFormat )
	{
		// GeneralDate:
		// Display a date and/or time. If there is a date part,
		// display it as a short date. If there is a time part,
		// display it as a long time. If present, both parts are displayed.

		// 12/21/2004 11:24:50 AM
		// 21.12.2004 12:13:51
		case 0:
			pSbxVar->PutDate( dDate );
			aRetStr = pSbxVar->GetString();
			break;

		// LongDate: Display a date using the long date format specified
		// in your computer's regional settings.
		// Tuesday, December 21, 2004
		// Dienstag, 21. December 2004
		case 1:
		{
			SvNumberFormatter* pFormatter = NULL;
			if( pINST )
				pFormatter = pINST->GetNumberFormatter();
			else
			{
				sal_uInt32 n;	// Dummy
				SbiInstance::PrepareNumberFormatter( pFormatter, n, n, n );
			}

	        LanguageType eLangType = GetpApp()->GetSettings().GetLanguage();
			sal_uIntPtr nIndex = pFormatter->GetFormatIndex( NF_DATE_SYSTEM_LONG, eLangType );
			Color* pCol;
			pFormatter->GetOutputString( dDate, nIndex, aRetStr, &pCol );

			if( !pINST )
				delete pFormatter;

			break;
		}

		// ShortDate: Display a date using the short date format specified
		// in your computer's regional settings.
		// 12/21/2004
		// 21.12.2004
		case 2:
			pSbxVar->PutDate( floor(dDate) );
			aRetStr = pSbxVar->GetString();
			break;

		// LongTime: Display a time using the time format specified
		// in your computer's regional settings.
		// 11:24:50 AM
		// 12:13:51
		case 3:
		// ShortTime: Display a time using the 24-hour format (hh:mm).
		// 11:24
		case 4:
			double n;
			double dTime = modf( dDate, &n );
			pSbxVar->PutDate( dTime );
			if( nNamedFormat == 3 )
				aRetStr = pSbxVar->GetString();
			else
				aRetStr = pSbxVar->GetString().Copy( 0, 5 );
			break;
	}

	rPar.Get(0)->PutString( aRetStr );
}

RTLFUNC(Round)
{
    (void)pBasic;
    (void)bWrite;

	sal_uInt16 nParCount = rPar.Count();
	if( nParCount != 2 && nParCount != 3 )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}

	SbxVariable *pSbxVariable = rPar.Get(1);
	double dVal = pSbxVariable->GetDouble();
	double dRes = 0.0;
	if( dVal != 0.0 )
	{
		bool bNeg = false;
		if( dVal < 0.0 )
		{
			bNeg = true;
			dVal = -dVal;
		}

		sal_Int16 numdecimalplaces = 0;
		if( nParCount == 3 )
		{
			numdecimalplaces = rPar.Get(2)->GetInteger();
			if( numdecimalplaces < 0 || numdecimalplaces > 22 )
			{
				StarBASIC::Error( SbERR_BAD_ARGUMENT );
				return;
			}
		}

		if( numdecimalplaces == 0 )
		{
			dRes = floor( dVal + 0.5 );
		}
		else
		{
			double dFactor = pow( 10.0, numdecimalplaces );
			dVal *= dFactor;
			dRes = floor( dVal + 0.5 );
			dRes /= dFactor;
		}

		if( bNeg )
			dRes = -dRes;
	}
	rPar.Get(0)->PutDouble( dRes );
}

RTLFUNC(StrReverse)
{
    (void)pBasic;
    (void)bWrite;

	if ( rPar.Count() != 2 )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}

	SbxVariable *pSbxVariable = rPar.Get(1);
	if( pSbxVariable->IsNull() )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}

	String aStr = pSbxVariable->GetString();
	aStr.Reverse();
	rPar.Get(0)->PutString( aStr );
}

RTLFUNC(CompatibilityMode)
{
    (void)pBasic;
    (void)bWrite;

	bool bEnabled = false;
	sal_uInt16 nCount = rPar.Count();
	if ( nCount != 1 && nCount != 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );

	SbiInstance* pInst = pINST;
	if( pInst )
	{
		if ( nCount == 2 )
			pInst->EnableCompatibility( rPar.Get(1)->GetBool() );

		bEnabled = pInst->IsCompatibility();
	}
	rPar.Get(0)->PutBool( bEnabled );
}

RTLFUNC(Input)
{
    (void)pBasic;
    (void)bWrite;

	// 2 parameters needed
	if ( rPar.Count() < 3 )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}

	sal_uInt16 nByteCount  = rPar.Get(1)->GetUShort();
	sal_Int16  nFileNumber = rPar.Get(2)->GetInteger();

	SbiIoSystem* pIosys = pINST->GetIoSystem();
	SbiStream* pSbStrm = pIosys->GetStream( nFileNumber );
	if ( !pSbStrm || !(pSbStrm->GetMode() & (SBSTRM_BINARY | SBSTRM_INPUT)) )
	{
		StarBASIC::Error( SbERR_BAD_CHANNEL );
		return;
	}

	ByteString aByteBuffer;
	SbError err = pSbStrm->Read( aByteBuffer, nByteCount, true );
	if( !err )
		err = pIosys->GetError();

	if( err )
	{
		StarBASIC::Error( err );
		return;
	}
	rPar.Get(0)->PutString( String( aByteBuffer, gsl_getSystemTextEncoding() ) );
}

// #115824
RTLFUNC(Me)
{
    (void)pBasic;
    (void)bWrite;

	SbModule* pActiveModule = pINST->GetActiveModule();
	SbClassModuleObject* pClassModuleObject = PTR_CAST(SbClassModuleObject,pActiveModule);
	SbxVariableRef refVar = rPar.Get(0);
	if( pClassModuleObject == NULL )
	{
		SbObjModule* pMod = PTR_CAST(SbObjModule,pActiveModule);
		if ( pMod )
			refVar->PutObject( pMod );
		else
			StarBASIC::Error( SbERR_INVALID_USAGE_OBJECT );
	}
	else
		refVar->PutObject( pClassModuleObject );
}
