/**************************************************************
 *
 * 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 <tools/date.hxx>
#include <basic/sbxvar.hxx>
#include <vos/process.hxx>
#include <vcl/svapp.hxx>
#include <vcl/settings.hxx>
#include <vcl/sound.hxx>
#include <tools/wintypes.hxx>
#include <vcl/msgbox.hxx>
#include <basic/sbx.hxx>
#include <svl/zforlist.hxx>
#include <rtl/math.hxx>
#include <tools/urlobj.hxx>
#include <osl/time.h>
#include <unotools/charclass.hxx>
#include <unotools/ucbstreamhelper.hxx>
#include <tools/wldcrd.hxx>
#include <i18npool/lang.h>
#include <vcl/dibtools.hxx>

#include "runtime.hxx"
#include "sbunoobj.hxx"
#ifdef WNT
#include <tools/prewin.h>
#include "winbase.h"
#include <tools/postwin.h>
#ifndef _FSYS_HXX //autogen
#include <tools/fsys.hxx>
#endif
#else
#include <osl/file.hxx>
#endif
#include "errobject.hxx"

#ifdef _USE_UNO
#include <comphelper/processfactory.hxx>

#include <com/sun/star/uno/Sequence.hxx>
#include <com/sun/star/util/DateTime.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/lang/Locale.hpp>
#include <com/sun/star/ucb/XSimpleFileAccess3.hpp>
#include <com/sun/star/io/XInputStream.hpp>
#include <com/sun/star/io/XOutputStream.hpp>
#include <com/sun/star/io/XStream.hpp>
#include <com/sun/star/io/XSeekable.hpp>

using namespace comphelper;
using namespace osl;
using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::ucb;
using namespace com::sun::star::io;
using namespace com::sun::star::frame;

#endif /* _USE_UNO */

//#define _ENABLE_CUR_DIR

#include "stdobj.hxx"
#include <basic/sbstdobj.hxx>
#include "rtlproto.hxx"
#include "basrid.hxx"
#include "image.hxx"
#include "sb.hrc"
#include "iosys.hxx"
#include "ddectrl.hxx"
#include <sbintern.hxx>
#include <basic/vbahelper.hxx>

#include <list>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

#if defined (WNT) || defined (OS2)
#include <direct.h>   // _getdcwd get current work directory, _chdrive
#endif

#ifdef UNX
#include <errno.h>
#include <unistd.h>
#endif

#ifdef WNT
#include <io.h>
#endif

#include <basic/sbobjmod.hxx>

// from source/classes/sbxmod.cxx
Reference< XModel > getDocumentModel( StarBASIC* );

static void FilterWhiteSpace( String& rStr )
{
	rStr.EraseAllChars( ' ' );
	rStr.EraseAllChars( '\t' );
	rStr.EraseAllChars( '\n' );
	rStr.EraseAllChars( '\r' );
}

static long GetDayDiff( const Date& rDate )
{
	Date aRefDate( 1,1,1900 );
	long nDiffDays;
	if ( aRefDate > rDate )
	{
		nDiffDays = (long)(aRefDate - rDate);
		nDiffDays *= -1;
	}
	else
		nDiffDays = (long)(rDate - aRefDate);
	nDiffDays += 2; // Anpassung VisualBasic: 1.Jan.1900 == 2
	return nDiffDays;
}

static CharClass& GetCharClass( void )
{
	static sal_Bool bNeedsInit = sal_True;
	static ::com::sun::star::lang::Locale aLocale;
	if( bNeedsInit )
	{
        bNeedsInit = sal_False;
		aLocale = Application::GetSettings().GetLocale();
	}
	static CharClass aCharClass( aLocale );
	return aCharClass;
}

static inline sal_Bool isFolder( FileStatus::Type aType )
{
    return ( aType == FileStatus::Directory || aType == FileStatus::Volume );
}


//*** UCB file access ***

// Converts possibly relative paths to absolute paths
// according to the setting done by ChDir/ChDrive
String getFullPath( const String& aRelPath )
{
	::rtl::OUString aFileURL;

	// #80204 Try first if it already is a valid URL
	INetURLObject aURLObj( aRelPath );
	aFileURL = aURLObj.GetMainURL( INetURLObject::NO_DECODE );

	if( aFileURL.isEmpty() )
	{
		File::getFileURLFromSystemPath( aRelPath, aFileURL );
	}

    return aFileURL;
}

// Sets (virtual) current path for UCB file access
void implChDir( const String& aDir )
{
    (void)aDir;
	// TODO
}

// Sets (virtual) current drive for UCB file access
void implChDrive( const String& aDrive )
{
    (void)aDrive;
	// TODO
}

// Returns (virtual) current path for UCB file access
String implGetCurDir( void )
{
	String aRetStr;

	return aRetStr;
}

// TODO: -> SbiGlobals
static com::sun::star::uno::Reference< XSimpleFileAccess3 > getFileAccess( void )
{
	static com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI;
	if( !xSFI.is() )
	{
		com::sun::star::uno::Reference< XMultiServiceFactory > xSMgr = getProcessServiceFactory();
		if( xSMgr.is() )
		{
			xSFI = com::sun::star::uno::Reference< XSimpleFileAccess3 >( xSMgr->createInstance
				( ::rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ), UNO_QUERY );
		}
	}
	return xSFI;
}



// Properties und Methoden legen beim Get (bPut = sal_False) den Returnwert
// im Element 0 des Argv ab; beim Put (bPut = sal_True) wird der Wert aus
// Element 0 gespeichert.

// CreateObject( class )

RTLFUNC(CreateObject)
{
    (void)bWrite;

	String aClass( rPar.Get( 1 )->GetString() );
	SbxObjectRef p = SbxBase::CreateObject( aClass );
	if( !p )
		StarBASIC::Error( SbERR_CANNOT_LOAD );
	else
	{
		// Convenience: BASIC als Parent eintragen
		p->SetParent( pBasic );
		rPar.Get( 0 )->PutObject( p );
	}
}

// Error( n )

RTLFUNC(Error)
{
    (void)bWrite;

	if( !pBasic )
		StarBASIC::Error( SbERR_INTERNAL_ERROR );
	else
	{
		String aErrorMsg;
		SbError nErr = 0L;
		sal_Int32 nCode = 0;
		if( rPar.Count() == 1 )
		{
			nErr = StarBASIC::GetErrBasic();
			aErrorMsg = StarBASIC::GetErrorMsg();
		}
		else
		{
			nCode = rPar.Get( 1 )->GetLong();
			if( nCode > 65535L )
				StarBASIC::Error( SbERR_CONVERSION );
			else
				nErr = StarBASIC::GetSfxFromVBError( (sal_uInt16)nCode );
		}

		bool bVBA = SbiRuntime::isVBAEnabled();
		String tmpErrMsg;
		if( bVBA && aErrorMsg.Len() > 0 )
		{
			tmpErrMsg = aErrorMsg;
		}
		else
		{
			pBasic->MakeErrorText( nErr, aErrorMsg );
			tmpErrMsg = pBasic->GetErrorText();
		}
		// If this rtlfunc 'Error'  passed a errcode the same as the active Err Objects's
		// current err then  return the description for the error message if it is set
		// ( complicated isn't it ? )
		if ( bVBA && rPar.Count() > 1 )
		{
			com::sun::star::uno::Reference< ooo::vba::XErrObject > xErrObj( SbxErrObject::getUnoErrObject() );
			if ( xErrObj.is() && xErrObj->getNumber() == nCode && !xErrObj->getDescription().isEmpty() )
				tmpErrMsg = xErrObj->getDescription();
		}
		rPar.Get( 0 )->PutString( tmpErrMsg );
	}
}

// Sinus

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

	if ( rPar.Count() < 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
		SbxVariableRef pArg = rPar.Get( 1 );
		rPar.Get( 0 )->PutDouble( sin( pArg->GetDouble() ) );
	}
}

// Cosinus

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

	if ( rPar.Count() < 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
		SbxVariableRef pArg = rPar.Get( 1 );
		rPar.Get( 0 )->PutDouble( cos( pArg->GetDouble() ) );
	}
}

// Atn

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

	if ( rPar.Count() < 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
		SbxVariableRef pArg = rPar.Get( 1 );
		rPar.Get( 0 )->PutDouble( atan( pArg->GetDouble() ) );
	}
}



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

	if ( rPar.Count() < 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
		SbxVariableRef pArg = rPar.Get( 1 );
		rPar.Get( 0 )->PutDouble( fabs( pArg->GetDouble() ) );
	}
}


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

	if ( rPar.Count() < 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
		SbxVariableRef pArg = rPar.Get( 1 );
		String aStr( pArg->GetString() );
		if ( aStr.Len() == 0 )
		{
			StarBASIC::Error( SbERR_BAD_ARGUMENT );
			rPar.Get(0)->PutEmpty();
		}
		else
		{
			sal_Unicode aCh = aStr.GetBuffer()[0];
			rPar.Get(0)->PutLong( aCh );
		}
	}
}

void implChr( SbxArray& rPar, bool bChrW )
{
	if ( rPar.Count() < 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
		SbxVariableRef pArg = rPar.Get( 1 );

		String aStr;
		if( !bChrW && SbiRuntime::isVBAEnabled() )
		{
			sal_Char c = (sal_Char)pArg->GetByte();
			ByteString s( c );
			aStr = String( s, gsl_getSystemTextEncoding() );
		}
		else
		{
			sal_Unicode aCh = (sal_Unicode)pArg->GetUShort();
			aStr = String( aCh );
		}
		rPar.Get(0)->PutString( aStr );
	}
}

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

	bool bChrW = false;
	implChr( rPar, bChrW );
}

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

	bool bChrW = true;
	implChr( rPar, bChrW );
}


#ifdef UNX
#define _MAX_PATH 260
#define _PATH_INCR 250
#endif

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

	// #57064 Obwohl diese Funktion nicht mit DirEntry arbeitet, ist sie von
	// der Anpassung an virtuelle URLs nich betroffen, da bei Nutzung der
	// DirEntry-Funktionalitaet keine Moeglichkeit besteht, das aktuelle so
	// zu ermitteln, dass eine virtuelle URL geliefert werden koennte.

//	rPar.Get(0)->PutEmpty();
#if defined (WNT) || defined (OS2)
	int nCurDir = 0;  // Current dir // JSM
	if ( rPar.Count() == 2 )
	{
		String aDrive = rPar.Get(1)->GetString();
		if ( aDrive.Len() != 1 )
		{
			StarBASIC::Error( SbERR_BAD_ARGUMENT );
			return;
		}
		else
		{
			nCurDir = (int)aDrive.GetBuffer()[0];
			if ( !isalpha( nCurDir ) )
			{
				StarBASIC::Error( SbERR_BAD_ARGUMENT );
				return;
			}
			else
				nCurDir -= ( 'A' - 1 );
		}
	}
	char* pBuffer = new char[ _MAX_PATH ];
#ifdef OS2
	if( !nCurDir )
		nCurDir = _getdrive();
#endif
	if ( _getdcwd( nCurDir, pBuffer, _MAX_PATH ) != 0 )
		rPar.Get(0)->PutString( String::CreateFromAscii( pBuffer ) );
	else
		StarBASIC::Error( SbERR_NO_DEVICE );
	delete [] pBuffer;

#elif defined( UNX )

	int nSize = _PATH_INCR;
	char* pMem;
	while( sal_True )
	  {
		pMem = new char[nSize];
		if( !pMem )
		  {
			StarBASIC::Error( SbERR_NO_MEMORY );
			return;
		  }
		if( getcwd( pMem, nSize-1 ) != NULL )
		  {
			rPar.Get(0)->PutString( String::CreateFromAscii(pMem) );
			delete [] pMem;
			return;
		  }
		if( errno != ERANGE )
		  {
			StarBASIC::Error( SbERR_INTERNAL_ERROR );
			delete [] pMem;
			return;
		  }
		delete [] pMem;
		nSize += _PATH_INCR;
	  };

#endif
}

RTLFUNC(ChDir) // JSM
{
    (void)bWrite;

	rPar.Get(0)->PutEmpty();
	if (rPar.Count() == 2)
	{
#ifdef _ENABLE_CUR_DIR
		String aPath = rPar.Get(1)->GetString();
		sal_Bool bError = sal_False;
#ifdef WNT
		// #55997 Laut MI hilft es bei File-URLs einen DirEntry zwischenzuschalten
		// #40996 Harmoniert bei Verwendung der WIN32-Funktion nicht mit getdir
		DirEntry aEntry( aPath );
		ByteString aFullPath( aEntry.GetFull(), gsl_getSystemTextEncoding() );
		if( chdir( aFullPath.GetBuffer()) )
			bError = sal_True;
#else
		if (!DirEntry(aPath).SetCWD())
			bError = sal_True;
#endif
		if( bError )
			StarBASIC::Error( SbERR_PATH_NOT_FOUND );
#endif
        // VBA: track current directory per document type (separately for Writer, Calc, Impress, etc.)
        if( SbiRuntime::isVBAEnabled() )
            ::basic::vba::registerCurrentDirectory( getDocumentModel( pBasic ), rPar.Get(1)->GetString() );
	}
	else
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
}

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

	rPar.Get(0)->PutEmpty();
	if (rPar.Count() == 2)
	{
#ifdef _ENABLE_CUR_DIR
		// Keine Laufwerke in Unix
#ifndef UNX
		String aPar1 = rPar.Get(1)->GetString();

#if defined (WNT) || defined (OS2)
		if (aPar1.Len() > 0)
		{
			int nCurDrive = (int)aPar1.GetBuffer()[0]; ;
			if ( !isalpha( nCurDrive ) )
			{
				StarBASIC::Error( SbERR_BAD_ARGUMENT );
				return;
			}
			else
				nCurDrive -= ( 'A' - 1 );
			if (_chdrive(nCurDrive))
				StarBASIC::Error( SbERR_NO_DEVICE );
		}
#endif

#endif
		// #ifndef UNX
#endif
	}
	else
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
}


// Implementation of StepRENAME with UCB
void implStepRenameUCB( const String& aSource, const String& aDest )
{
	com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess();
	if( xSFI.is() )
	{
		try
		{
			String aSourceFullPath = getFullPath( aSource );
			if( !xSFI->exists( aSourceFullPath ) )
			{
				StarBASIC::Error( SbERR_FILE_NOT_FOUND );
				return;
			}

			String aDestFullPath = getFullPath( aDest );
			if( xSFI->exists( aDestFullPath ) )
				StarBASIC::Error( SbERR_FILE_EXISTS );
			else
				xSFI->move( aSourceFullPath, aDestFullPath );
		}
		catch( Exception & )
		{
			StarBASIC::Error( SbERR_FILE_NOT_FOUND );
		}
	}
}

// Implementation of StepRENAME with OSL
void implStepRenameOSL( const String& aSource, const String& aDest )
{
	FileBase::RC nRet = File::move( getFullPathUNC( aSource ), getFullPathUNC( aDest ) );
	if( nRet != FileBase::E_None )
	{
		StarBASIC::Error( SbERR_PATH_NOT_FOUND );
	}
}

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

	rPar.Get(0)->PutEmpty();
	if (rPar.Count() == 3)
	{
		String aSource = rPar.Get(1)->GetString();
		String aDest = rPar.Get(2)->GetString();
		// <-- UCB
		if( hasUno() )
		{
			com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess();
			if( xSFI.is() )
			{
				try
				{
					xSFI->copy( getFullPath( aSource ), getFullPath( aDest ) );
				}
				catch( Exception & )
				{
					StarBASIC::Error( SbERR_PATH_NOT_FOUND );
				}
			}
		}
		else
		// --> UCB
		{
#ifdef _OLD_FILE_IMPL
			DirEntry aSourceDirEntry(aSource);
			if (aSourceDirEntry.Exists())
			{
				if (aSourceDirEntry.CopyTo(DirEntry(aDest),FSYS_ACTION_COPYFILE) != FSYS_ERR_OK)
					StarBASIC::Error( SbERR_PATH_NOT_FOUND );
			}
			else
					StarBASIC::Error( SbERR_PATH_NOT_FOUND );
#else
			FileBase::RC nRet = File::copy( getFullPathUNC( aSource ), getFullPathUNC( aDest ) );
			if( nRet != FileBase::E_None )
			{
				StarBASIC::Error( SbERR_PATH_NOT_FOUND );
			}
#endif
		}
	}
	else
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
}

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

	rPar.Get(0)->PutEmpty();
	if (rPar.Count() == 2)
	{
		String aFileSpec = rPar.Get(1)->GetString();

		// <-- UCB
		if( hasUno() )
		{
			com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess();
			if( xSFI.is() )
			{
			    String aFullPath = getFullPath( aFileSpec );
				if( !xSFI->exists( aFullPath ) || xSFI->isFolder( aFullPath ) )
				{
					StarBASIC::Error( SbERR_FILE_NOT_FOUND );
					return;
				}
				try
				{
					xSFI->kill( aFullPath );
				}
				catch( Exception & )
				{
					StarBASIC::Error( ERRCODE_IO_GENERAL );
				}
			}
		}
		else
		// --> UCB
		{
#ifdef _OLD_FILE_IMPL
			if(DirEntry(aFileSpec).Kill() != FSYS_ERR_OK)
				StarBASIC::Error( SbERR_PATH_NOT_FOUND );
#else
			File::remove( getFullPathUNC( aFileSpec ) );
#endif
		}
	}
	else
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
}

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

	rPar.Get(0)->PutEmpty();
	if (rPar.Count() == 2)
	{
		String aPath = rPar.Get(1)->GetString();

		// <-- UCB
		if( hasUno() )
		{
			com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess();
			if( xSFI.is() )
			{
				try
				{
					xSFI->createFolder( getFullPath( aPath ) );
				}
				catch( Exception & )
				{
					StarBASIC::Error( ERRCODE_IO_GENERAL );
				}
			}
		}
		else
		// --> UCB
		{
#ifdef _OLD_FILE_IMPL
			if (!DirEntry(aPath).MakeDir())
				StarBASIC::Error( SbERR_PATH_NOT_FOUND );
#else
			Directory::create( getFullPathUNC( aPath ) );
#endif
		}
	}
	else
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
}


#ifndef _OLD_FILE_IMPL

// In OSL only empty directories can be deleted
// so we have to delete all files recursively
void implRemoveDirRecursive( const String& aDirPath )
{
	DirectoryItem aItem;
	FileBase::RC nRet = DirectoryItem::get( aDirPath, aItem );
	sal_Bool bExists = (nRet == FileBase::E_None);

	FileStatus aFileStatus( FileStatusMask_Type );
	nRet = aItem.getFileStatus( aFileStatus );
	FileStatus::Type aType = aFileStatus.getFileType();
	sal_Bool bFolder = isFolder( aType );

	if( !bExists || !bFolder )
	{
		StarBASIC::Error( SbERR_PATH_NOT_FOUND );
		return;
	}

	Directory aDir( aDirPath );
	nRet = aDir.open();
	if( nRet != FileBase::E_None )
	{
		StarBASIC::Error( SbERR_PATH_NOT_FOUND );
		return;
	}

	for( ;; )
	{
		DirectoryItem aItem2;
		nRet = aDir.getNextItem( aItem2 );
		if( nRet != FileBase::E_None )
			break;

		// Handle flags
        FileStatus aFileStatus2( FileStatusMask_Type | FileStatusMask_FileURL );
		nRet = aItem2.getFileStatus( aFileStatus2 );
		::rtl::OUString aPath = aFileStatus2.getFileURL();

		// Directory?
		FileStatus::Type aType2 = aFileStatus2.getFileType();
		sal_Bool bFolder2 = isFolder( aType2 );
		if( bFolder2 )
		{
			implRemoveDirRecursive( aPath );
		}
		else
		{
			File::remove( aPath );
		}
	}
	nRet = aDir.close();

	nRet = Directory::remove( aDirPath );
}
#endif


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

	rPar.Get(0)->PutEmpty();
	if (rPar.Count() == 2)
	{
		String aPath = rPar.Get(1)->GetString();
		// <-- UCB
		if( hasUno() )
		{
			com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess();
			if( xSFI.is() )
			{
				try
				{
					if( !xSFI->isFolder( aPath ) )
					{
						StarBASIC::Error( SbERR_PATH_NOT_FOUND );
						return;
					}
					SbiInstance* pInst = pINST;
					bool bCompatibility = ( pInst && pInst->IsCompatibility() );
					if( bCompatibility )
					{
						Sequence< ::rtl::OUString > aContent = xSFI->getFolderContents( aPath, true );
						sal_Int32 nCount = aContent.getLength();
						if( nCount > 0 )
						{
							StarBASIC::Error( SbERR_ACCESS_ERROR );
							return;
						}
					}

					xSFI->kill( getFullPath( aPath ) );
				}
				catch( Exception & )
				{
					StarBASIC::Error( ERRCODE_IO_GENERAL );
				}
			}
		}
		else
		// --> UCB
		{
#ifdef _OLD_FILE_IMPL
			DirEntry aDirEntry(aPath);
			if (aDirEntry.Kill() != FSYS_ERR_OK)
				StarBASIC::Error( SbERR_PATH_NOT_FOUND );
#else
			implRemoveDirRecursive( getFullPathUNC( aPath ) );
#endif
		}
	}
	else
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
}

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

	rPar.Get(0)->PutEmpty();
	StarBASIC::Error(SbERR_NOT_IMPLEMENTED);
}

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

	if( rPar.Count() < 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
		double aDouble = rPar.Get( 1 )->GetDouble();
		aDouble = exp( aDouble );
        checkArithmeticOverflow( aDouble );
		rPar.Get( 0 )->PutDouble( aDouble );
	}
}

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

	if ( rPar.Count() < 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
		SbxVariableRef pArg = rPar.Get( 1 );
		String aStr( pArg->GetString() );
		sal_Int32 nLen = 0;
		// <-- UCB
		if( hasUno() )
		{
			com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess();
			if( xSFI.is() )
			{
				try
				{
					nLen = xSFI->getSize( getFullPath( aStr ) );
				}
				catch( Exception & )
				{
					StarBASIC::Error( ERRCODE_IO_GENERAL );
				}
			}
		}
		else
		// --> UCB
		{
#ifdef _OLD_FILE_IMPL
			FileStat aStat = DirEntry( aStr );
			nLen = aStat.GetSize();
#else
			DirectoryItem aItem;
			FileBase::RC nRet = DirectoryItem::get( getFullPathUNC( aStr ), aItem );
			FileStatus aFileStatus( FileStatusMask_FileSize );
		    nRet = aItem.getFileStatus( aFileStatus );
		    nLen = (sal_Int32)aFileStatus.getFileSize();
#endif
		}
		rPar.Get(0)->PutLong( (long)nLen );
	}
}


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

	if ( rPar.Count() < 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
		char aBuffer[16];
		SbxVariableRef pArg = rPar.Get( 1 );
		if ( pArg->IsInteger() )
            snprintf( aBuffer, sizeof(aBuffer), "%X", pArg->GetInteger() );
		else
            snprintf( aBuffer, sizeof(aBuffer), "%lX", static_cast<long unsigned int>(pArg->GetLong()) );
		rPar.Get(0)->PutString( String::CreateFromAscii( aBuffer ) );
	}
}

// InStr( [start],string,string,[compare] )

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

	sal_uIntPtr nArgCount = rPar.Count()-1;
	if ( nArgCount < 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
		sal_uInt16 nStartPos = 1;

		sal_uInt16 nFirstStringPos = 1;
		if ( nArgCount >= 3 )
		{
			sal_Int32 lStartPos = rPar.Get(1)->GetLong();
			if( lStartPos <= 0 || lStartPos > 0xffff )
			{
				StarBASIC::Error( SbERR_BAD_ARGUMENT );
				lStartPos = 1;
			}
			nStartPos = (sal_uInt16)lStartPos;
			nFirstStringPos++;
		}

		SbiInstance* pInst = pINST;
		int bTextMode;
		bool bCompatibility = ( pInst && pInst->IsCompatibility() );
		if( bCompatibility )
		{
			SbiRuntime* pRT = pInst ? pInst->pRun : NULL;
			bTextMode = pRT ? pRT->GetImageFlag( SBIMG_COMPARETEXT ) : sal_False;
		}
		else
		{
			bTextMode = 1;
		}
		if ( nArgCount == 4 )
			bTextMode = rPar.Get(4)->GetInteger();

		sal_uInt16 nPos;
		const String& rToken = rPar.Get(nFirstStringPos+1)->GetString();

		// #97545 Always find empty string
		if( !rToken.Len() )
		{
			nPos = nStartPos;
		}
		else
		{
			if( !bTextMode )
			{
				const String& rStr1 = rPar.Get(nFirstStringPos)->GetString();

				nPos = rStr1.Search( rToken, nStartPos-1 );
				if ( nPos == STRING_NOTFOUND )
					nPos = 0;
				else
					nPos++;
			}
			else
			{
				String aStr1 = rPar.Get(nFirstStringPos)->GetString();
				String aToken = rToken;

				aStr1.ToUpperAscii();
				aToken.ToUpperAscii();

				nPos = aStr1.Search( aToken, nStartPos-1 );
				if ( nPos == STRING_NOTFOUND )
					nPos = 0;
				else
					nPos++;
			}
		}
		rPar.Get(0)->PutLong( nPos );
	}
}


// InstrRev(string1, string2[, start[, compare]])

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

	sal_uIntPtr nArgCount = rPar.Count()-1;
	if ( nArgCount < 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
		String aStr1 = rPar.Get(1)->GetString();
		String aToken = rPar.Get(2)->GetString();

		sal_Int32 lStartPos = -1;
		if ( nArgCount >= 3 )
		{
			lStartPos = rPar.Get(3)->GetLong();
			if( (lStartPos <= 0 && lStartPos != -1) || lStartPos > 0xffff )
			{
				StarBASIC::Error( SbERR_BAD_ARGUMENT );
				lStartPos = -1;
			}
		}

		SbiInstance* pInst = pINST;
		int bTextMode;
		bool bCompatibility = ( pInst && pInst->IsCompatibility() );
		if( bCompatibility )
		{
			SbiRuntime* pRT = pInst ? pInst->pRun : NULL;
			bTextMode = pRT ? pRT->GetImageFlag( SBIMG_COMPARETEXT ) : sal_False;
		}
		else
		{
			bTextMode = 1;
		}
		if ( nArgCount == 4 )
			bTextMode = rPar.Get(4)->GetInteger();

		sal_uInt16 nStrLen = aStr1.Len();
		sal_uInt16 nStartPos = lStartPos == -1 ? nStrLen : (sal_uInt16)lStartPos;

		sal_uInt16 nPos = 0;
		if( nStartPos <= nStrLen )
		{
			sal_uInt16 nTokenLen = aToken.Len();
			if( !nTokenLen )
			{
				// Always find empty string
				nPos = nStartPos;
			}
			else if( nStrLen > 0 )
			{
				if( !bTextMode )
				{
					::rtl::OUString aOUStr1 ( aStr1 );
					::rtl::OUString aOUToken( aToken );
				    sal_Int32 nRet = aOUStr1.lastIndexOf( aOUToken, nStartPos );
					if( nRet == -1 )
						nPos = 0;
					else
						nPos = (sal_uInt16)nRet + 1;
				}
				else
				{
					aStr1.ToUpperAscii();
					aToken.ToUpperAscii();

					::rtl::OUString aOUStr1 ( aStr1 );
					::rtl::OUString aOUToken( aToken );
				    sal_Int32 nRet = aOUStr1.lastIndexOf( aOUToken, nStartPos );

					if( nRet == -1 )
						nPos = 0;
					else
						nPos = (sal_uInt16)nRet + 1;
				}
			}
		}
		rPar.Get(0)->PutLong( nPos );
	}
}


/*
	Int( 2.8 ) 	=  2.0
	Int( -2.8 ) = -3.0
	Fix( 2.8 ) 	=  2.0
	Fix( -2.8 ) = -2.0    <- !!
*/

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

	if ( rPar.Count() < 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
		SbxVariableRef pArg = rPar.Get( 1 );
		double aDouble= pArg->GetDouble();
		/*
			floor( 2.8 ) =  2.0
			floor( -2.8 ) = -3.0
		*/
		aDouble = floor( aDouble );
		rPar.Get(0)->PutDouble( aDouble );
	}
}



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

	if ( rPar.Count() < 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
		SbxVariableRef pArg = rPar.Get( 1 );
		double aDouble = pArg->GetDouble();
		if ( aDouble >= 0.0 )
			aDouble = floor( aDouble );
		else
			aDouble = ceil( aDouble );
		rPar.Get(0)->PutDouble( aDouble );
	}
}


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

	if ( rPar.Count() < 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
		CharClass& rCharClass = GetCharClass();
		String aStr( rPar.Get(1)->GetString() );
		rCharClass.toLower( aStr );
		rPar.Get(0)->PutString( aStr );
	}
}

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

	if ( rPar.Count() < 3 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
		String aStr( rPar.Get(1)->GetString() );
		sal_Int32 lResultLen = rPar.Get(2)->GetLong();
		if( lResultLen > 0xffff )
		{
			lResultLen = 0xffff;
		}
		else if( lResultLen < 0 )
		{
			lResultLen = 0;
			StarBASIC::Error( SbERR_BAD_ARGUMENT );
		}
		aStr.Erase( (sal_uInt16)lResultLen );
		rPar.Get(0)->PutString( aStr );
	}
}

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

	if ( rPar.Count() < 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
		double aArg = rPar.Get(1)->GetDouble();
		if ( aArg > 0 )
        {
            double d = log( aArg );
            checkArithmeticOverflow( d );
			rPar.Get( 0 )->PutDouble( d );
        }
		else
			StarBASIC::Error( SbERR_BAD_ARGUMENT );
	}
}

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

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


// Mid( String, nStart, nLength )

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

	sal_uIntPtr nArgCount = rPar.Count()-1;
	if ( nArgCount < 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
		// #23178: Funktionalitaet von Mid$ als Anweisung nachbilden, indem
		// als weiterer (4.) Parameter ein Ersetzungsstring aufgenommen wird.
		// Anders als im Original kann in dieser Variante der 3. Parameter
		// nLength nicht weggelassen werden. Ist ueber bWrite schon vorgesehen.
		if( nArgCount == 4 )
			bWrite = sal_True;

		String aArgStr = rPar.Get(1)->GetString();
		sal_uInt16 nStartPos = (sal_uInt16)(rPar.Get(2)->GetLong() );
		if ( nStartPos == 0 )
			StarBASIC::Error( SbERR_BAD_ARGUMENT );
		else
		{
			nStartPos--;
			sal_uInt16 nLen = 0xffff;
			bool bWriteNoLenParam = false;
			if ( nArgCount == 3 || bWrite )
			{
				sal_Int32 n = rPar.Get(3)->GetLong();
				if( bWrite && n == -1 )
					bWriteNoLenParam = true;
				nLen = (sal_uInt16)n;
			}
			String aResultStr;
			if ( bWrite )
			{
				SbiInstance* pInst = pINST;
				bool bCompatibility = ( pInst && pInst->IsCompatibility() );
				if( bCompatibility )
				{
					sal_uInt16 nArgLen = aArgStr.Len();
					if( nStartPos + 1 > nArgLen )
					{
						StarBASIC::Error( SbERR_BAD_ARGUMENT );
						return;
					}

					String aReplaceStr = rPar.Get(4)->GetString();
					sal_uInt16 nReplaceStrLen = aReplaceStr.Len();
					sal_uInt16 nReplaceLen;
					if( bWriteNoLenParam )
					{
						nReplaceLen = nReplaceStrLen;
					}
					else
					{
						nReplaceLen = nLen;
						if( nReplaceLen > nReplaceStrLen )
							nReplaceLen = nReplaceStrLen;
					}

					sal_uInt16 nReplaceEndPos = nStartPos + nReplaceLen;
					if( nReplaceEndPos > nArgLen )
						nReplaceLen -= (nReplaceEndPos - nArgLen);

					aResultStr = aArgStr;
					sal_uInt16 nErase = nReplaceLen;
					aResultStr.Erase( nStartPos, nErase );
					aResultStr.Insert( aReplaceStr, 0, nReplaceLen, nStartPos );
				}
				else
				{
					aResultStr = aArgStr;
					aResultStr.Erase( nStartPos, nLen );
					aResultStr.Insert(rPar.Get(4)->GetString(),0,nLen,nStartPos);
				}

				rPar.Get(1)->PutString( aResultStr );
			}
			else
			{
				aResultStr = aArgStr.Copy( nStartPos, nLen );
				rPar.Get(0)->PutString( aResultStr );
			}
		}
	}
}

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

	if ( rPar.Count() < 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
		char aBuffer[16];
		SbxVariableRef pArg = rPar.Get( 1 );
		if ( pArg->IsInteger() )
            snprintf( aBuffer, sizeof(aBuffer), "%o", pArg->GetInteger() );
		else
            snprintf( aBuffer, sizeof(aBuffer), "%lo", static_cast<long unsigned int>(pArg->GetLong()) );
		rPar.Get(0)->PutString( String::CreateFromAscii( aBuffer ) );
	}
}

// Replace(expression, find, replace[, start[, count[, compare]]])

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

	sal_uIntPtr nArgCount = rPar.Count()-1;
	if ( nArgCount < 3 || nArgCount > 6 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
		String aExpStr = rPar.Get(1)->GetString();
		String aFindStr = rPar.Get(2)->GetString();
		String aReplaceStr = rPar.Get(3)->GetString();

		sal_Int32 lStartPos = 1;
		if ( nArgCount >= 4 )
		{
			if( rPar.Get(4)->GetType() != SbxEMPTY )
				lStartPos = rPar.Get(4)->GetLong();
			if( lStartPos < 1  || lStartPos > 0xffff )
			{
				StarBASIC::Error( SbERR_BAD_ARGUMENT );
				lStartPos = 1;
			}
		}

		sal_Int32 lCount = -1;
		if( nArgCount >=5 )
		{
			if( rPar.Get(5)->GetType() != SbxEMPTY )
				lCount = rPar.Get(5)->GetLong();
			if( lCount < -1 || lCount > 0xffff )
			{
				StarBASIC::Error( SbERR_BAD_ARGUMENT );
				lCount = -1;
			}
		}

		SbiInstance* pInst = pINST;
		int bTextMode;
		bool bCompatibility = ( pInst && pInst->IsCompatibility() );
		if( bCompatibility )
		{
			SbiRuntime* pRT = pInst ? pInst->pRun : NULL;
			bTextMode = pRT ? pRT->GetImageFlag( SBIMG_COMPARETEXT ) : sal_False;
		}
		else
		{
			bTextMode = 1;
		}
		if ( nArgCount == 6 )
			bTextMode = rPar.Get(6)->GetInteger();

		sal_uInt16 nExpStrLen = aExpStr.Len();
		sal_uInt16 nFindStrLen = aFindStr.Len();
		sal_uInt16 nReplaceStrLen = aReplaceStr.Len();

		if( lStartPos <= nExpStrLen )
		{
			sal_uInt16 nPos = static_cast<sal_uInt16>( lStartPos - 1 );
			sal_uInt16 nCounts = 0;
			while( lCount == -1 || lCount > nCounts )
			{
				String aSrcStr( aExpStr );
				if( bTextMode )
				{
					aSrcStr.ToUpperAscii();
					aFindStr.ToUpperAscii();
				}
				nPos = aSrcStr.Search( aFindStr, nPos );
				if( nPos != STRING_NOTFOUND )
				{
					aExpStr.Replace( nPos, nFindStrLen, aReplaceStr );
					nPos = nPos + nReplaceStrLen;
					nCounts++;
				}
				else
				{
					break;
				}
			}
		}
		rPar.Get(0)->PutString( aExpStr.Copy( static_cast<sal_uInt16>(lStartPos - 1) )  );
	}
}

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

	if ( rPar.Count() < 3 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
		const String& rStr = rPar.Get(1)->GetString();
		sal_Int32 lResultLen = rPar.Get(2)->GetLong();
		if( lResultLen > 0xffff )
		{
			lResultLen = 0xffff;
		}
		else if( lResultLen < 0 )
		{
			lResultLen = 0;
			StarBASIC::Error( SbERR_BAD_ARGUMENT );
		}
		sal_uInt16 nResultLen = (sal_uInt16)lResultLen;
		sal_uInt16 nStrLen = rStr.Len();
		if ( nResultLen > nStrLen )
			nResultLen = nStrLen;
		String aResultStr = rStr.Copy( nStrLen-nResultLen );
		rPar.Get(0)->PutString( aResultStr );
	}
}

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

	rPar.Get( 0 )->PutObject( pBasic->getRTL() );
}

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

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

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

	if ( rPar.Count() < 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
		double aDouble = rPar.Get(1)->GetDouble();
		sal_Int16 nResult = 0;
		if ( aDouble > 0 )
			nResult = 1;
		else if ( aDouble < 0 )
			nResult = -1;
		rPar.Get(0)->PutInteger( nResult );
	}
}

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

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

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

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

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

	if ( rPar.Count() < 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
		double aDouble = rPar.Get(1)->GetDouble();
		if ( aDouble >= 0 )
			rPar.Get(0)->PutDouble( sqrt( aDouble ));
		else
			StarBASIC::Error( SbERR_BAD_ARGUMENT );
	}
}

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

	if ( rPar.Count() < 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
		String aStr;
		SbxVariableRef pArg = rPar.Get( 1 );
		pArg->Format( aStr );

		// Numbers start with a space
		if( pArg->IsNumericRTL() )
        {
    		// Kommas durch Punkte ersetzen, damit es symmetrisch zu Val ist!
	    	aStr.SearchAndReplace( ',', '.' );

			SbiInstance* pInst = pINST;
			bool bCompatibility = ( pInst && pInst->IsCompatibility() );
			if( bCompatibility )
			{
				xub_StrLen nLen = aStr.Len();

				const sal_Unicode* pBuf = aStr.GetBuffer();

				bool bNeg = ( pBuf[0] == '-' );
				sal_uInt16 iZeroSearch = 0;
				if( bNeg )
					iZeroSearch++;

				sal_uInt16 iNext = iZeroSearch + 1;
				if( pBuf[iZeroSearch] == '0' && nLen > iNext && pBuf[iNext] == '.' )
				{
					aStr.Erase( iZeroSearch, 1 );
					pBuf = aStr.GetBuffer();
				}
				if( !bNeg )
					aStr.Insert( ' ', 0 );
			}
			else
				aStr.Insert( ' ', 0 );
        }
		rPar.Get(0)->PutString( aStr );
	}
}

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

	if ( rPar.Count() < 3 )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		rPar.Get(0)->PutEmpty();
		return;
	}
	const String& rStr1 = rPar.Get(1)->GetString();
	const String& rStr2 = rPar.Get(2)->GetString();

	SbiInstance* pInst = pINST;
	sal_Int16 nTextCompare;
	bool bCompatibility = ( pInst && pInst->IsCompatibility() );
	if( bCompatibility )
	{
		SbiRuntime* pRT = pInst ? pInst->pRun : NULL;
		nTextCompare = pRT ? pRT->GetImageFlag( SBIMG_COMPARETEXT ) : sal_False;
	}
	else
	{
		nTextCompare = sal_True;
	}
	if ( rPar.Count() == 4 )
		nTextCompare = rPar.Get(3)->GetInteger();

	if( !bCompatibility )
		nTextCompare = !nTextCompare;

	StringCompare aResult;
    sal_Int32 nRetValue = 0;
	if( nTextCompare )
    {
        ::utl::TransliterationWrapper* pTransliterationWrapper = GetSbData()->pTransliterationWrapper;
        if( !pTransliterationWrapper )
        {
		    com::sun::star::uno::Reference< XMultiServiceFactory > xSMgr = getProcessServiceFactory();
            pTransliterationWrapper = GetSbData()->pTransliterationWrapper =
    	        new ::utl::TransliterationWrapper( xSMgr,
                    ::com::sun::star::i18n::TransliterationModules_IGNORE_CASE |
                    ::com::sun::star::i18n::TransliterationModules_IGNORE_KANA |
                    ::com::sun::star::i18n::TransliterationModules_IGNORE_WIDTH );
        }

        LanguageType eLangType = GetpApp()->GetSettings().GetLanguage();
        pTransliterationWrapper->loadModuleIfNeeded( eLangType );
        nRetValue = pTransliterationWrapper->compareString( rStr1, rStr2 );
    }
	else
    {
		aResult = rStr1.CompareTo( rStr2 );
	    if ( aResult == COMPARE_LESS )
		    nRetValue = -1;
	    else if ( aResult == COMPARE_GREATER )
		    nRetValue = 1;
    }

	rPar.Get(0)->PutInteger( sal::static_int_cast< sal_Int16 >( nRetValue ) );
}

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

	if ( rPar.Count() < 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
		String aStr;
		sal_Unicode aFiller;
		sal_Int32 lCount = rPar.Get(1)->GetLong();
		if( lCount < 0 || lCount > 0xffff )
			StarBASIC::Error( SbERR_BAD_ARGUMENT );
		sal_uInt16 nCount = (sal_uInt16)lCount;
		if( rPar.Get(2)->GetType() == SbxINTEGER )
			aFiller = (sal_Unicode)rPar.Get(2)->GetInteger();
		else
		{
			const String& rStr = rPar.Get(2)->GetString();
			aFiller = rStr.GetBuffer()[0];
		}
		aStr.Fill( nCount, aFiller );
		rPar.Get(0)->PutString( aStr );
	}
}

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

	if ( rPar.Count() < 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
		String aStr;
		aStr.Fill( (sal_uInt16)(rPar.Get(1)->GetLong() ), '\t');
		rPar.Get(0)->PutString( aStr );
	}
}

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

	if ( rPar.Count() < 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
		SbxVariableRef pArg = rPar.Get( 1 );
		rPar.Get( 0 )->PutDouble( tan( pArg->GetDouble() ) );
	}
}

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

	if ( rPar.Count() < 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
		CharClass& rCharClass = GetCharClass();
		String aStr( rPar.Get(1)->GetString() );
		rCharClass.toUpper( aStr );
		rPar.Get(0)->PutString( aStr );
	}
}


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

	if ( rPar.Count() < 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
		double nResult = 0.0;
		char* pEndPtr;

		String aStr( rPar.Get(1)->GetString() );
// lt. Mikkysoft bei Kommas abbrechen!
//		for( sal_uInt16 n=0; n < aStr.Len(); n++ )
//			if( aStr[n] == ',' ) aStr[n] = '.';

		FilterWhiteSpace( aStr );
		if ( aStr.GetBuffer()[0] == '&' && aStr.Len() > 1 )
		{
			int nRadix = 10;
			char aChar = (char)aStr.GetBuffer()[1];
			if ( aChar == 'h' || aChar == 'H' )
				nRadix = 16;
			else if ( aChar == 'o' || aChar == 'O' )
				nRadix = 8;
			if ( nRadix != 10 )
			{
				ByteString aByteStr( aStr, gsl_getSystemTextEncoding() );
				sal_Int16 nlResult = (sal_Int16)strtol( aByteStr.GetBuffer()+2, &pEndPtr, nRadix);
				nResult = (double)nlResult;
			}
		}
		else
		{
			// #57844 Lokalisierte Funktion benutzen
			nResult = ::rtl::math::stringToDouble( aStr, '.', ',', NULL, NULL );
            checkArithmeticOverflow( nResult );
			// ATL: nResult = strtod( aStr.GetStr(), &pEndPtr );
		}

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


// Helper functions for date conversion
sal_Int16 implGetDateDay( double aDate )
{
	aDate -= 2.0; // normieren: 1.1.1900 => 0.0
	aDate = floor( aDate );
	Date aRefDate( 1, 1, 1900 );
	aRefDate += (sal_uIntPtr)aDate;

    sal_Int16 nRet = (sal_Int16)( aRefDate.GetDay() );
    return nRet;
}

sal_Int16 implGetDateMonth( double aDate )
{
	Date aRefDate( 1,1,1900 );
	long nDays = (long)aDate;
	nDays -= 2; // normieren: 1.1.1900 => 0.0
	aRefDate += nDays;
	sal_Int16 nRet = (sal_Int16)( aRefDate.GetMonth() );
    return nRet;
}

sal_Int16 implGetDateYear( double aDate )
{
	Date aRefDate( 1,1,1900 );
	long nDays = (long) aDate;
	nDays -= 2; // normieren: 1.1.1900 => 0.0
	aRefDate += nDays;
	sal_Int16 nRet = (sal_Int16)( aRefDate.GetYear() );
    return nRet;
}

sal_Bool implDateSerial( sal_Int16 nYear, sal_Int16 nMonth, sal_Int16 nDay, double& rdRet )
{
	if ( nYear < 30 && SbiRuntime::isVBAEnabled() )
		nYear += 2000;
	else if ( nYear < 100 )
		nYear += 1900;
	Date aCurDate( nDay, nMonth, nYear );
	if ((nYear < 100 || nYear > 9999) )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return sal_False;
	}
	if ( !SbiRuntime::isVBAEnabled() )
	{
		if ( (nMonth < 1 || nMonth > 12 )||
		(nDay < 1 || nDay > 31 ) )
		{
			StarBASIC::Error( SbERR_BAD_ARGUMENT );
			return sal_False;
		}
	}
	else
	{
		// grab the year & month
		aCurDate = Date( 1, (( nMonth % 12 ) > 0 ) ? ( nMonth % 12 ) : 12 + ( nMonth % 12 ), nYear );

		// adjust year based on month value
		// e.g. 2000, 0, xx = 1999, 12, xx ( or December of the previous year )
		//		2000, 13, xx = 2001, 1, xx ( or January of the following year )
		if( ( nMonth < 1 ) || ( nMonth > 12 ) )
		{
			// inacurrate around leap year, don't use days to calculate,
			// just modify the months directory
			sal_Int16 nYearAdj = ( nMonth /12 ); // default to positive months inputed
			if ( nMonth <=0 )
				nYearAdj = ( ( nMonth -12 ) / 12 );
			aCurDate.SetYear( aCurDate.GetYear() + nYearAdj );
		}

		// adjust day value,
		// e.g. 2000, 2, 0 = 2000, 1, 31 or the last day of the previous month
		//		2000, 1, 32 = 2000, 2, 1 or the first day of the following month
		if( ( nDay < 1 ) || ( nDay > aCurDate.GetDaysInMonth() ) )
			aCurDate += nDay - 1;
		else
			aCurDate.SetDay( nDay );
	}

	long nDiffDays = GetDayDiff( aCurDate );
    rdRet = (double)nDiffDays;
    return sal_True;
}

// Function to convert date to ISO 8601 date format
RTLFUNC(CDateToIso)
{
    (void)pBasic;
    (void)bWrite;

	if ( rPar.Count() == 2 )
	{
        double aDate = rPar.Get(1)->GetDate();

        char Buffer[9];
        snprintf( Buffer, sizeof( Buffer ), "%04d%02d%02d",
            implGetDateYear( aDate ),
            implGetDateMonth( aDate ),
            implGetDateDay( aDate ) );
		String aRetStr = String::CreateFromAscii( Buffer );
        rPar.Get(0)->PutString( aRetStr );
	}
	else
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
}

// Function to convert date from ISO 8601 date format
RTLFUNC(CDateFromIso)
{
    (void)pBasic;
    (void)bWrite;

	if ( rPar.Count() == 2 )
	{
		String aStr = rPar.Get(1)->GetString();
        sal_Int16 iMonthStart = aStr.Len() - 4;
        String aYearStr  = aStr.Copy( 0, iMonthStart );
        String aMonthStr = aStr.Copy( iMonthStart, 2 );
        String aDayStr   = aStr.Copy( iMonthStart+2, 2 );

        double dDate;
        if( implDateSerial( (sal_Int16)aYearStr.ToInt32(),
            (sal_Int16)aMonthStr.ToInt32(), (sal_Int16)aDayStr.ToInt32(), dDate ) )
        {
    	    rPar.Get(0)->PutDate( dDate );
        }
	}
	else
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
}

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

	if ( rPar.Count() < 4 )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}
	sal_Int16 nYear = rPar.Get(1)->GetInteger();
	sal_Int16 nMonth = rPar.Get(2)->GetInteger();
	sal_Int16 nDay = rPar.Get(3)->GetInteger();

    double dDate;
    if( implDateSerial( nYear, nMonth, nDay, dDate ) )
    	rPar.Get(0)->PutDate( dDate );
}

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

	if ( rPar.Count() < 4 )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}
	sal_Int16 nHour = rPar.Get(1)->GetInteger();
	if ( nHour == 24 )
		nHour = 0;                      // Wegen UNO DateTimes, die bis 24 Uhr gehen
	sal_Int16 nMinute = rPar.Get(2)->GetInteger();
	sal_Int16 nSecond = rPar.Get(3)->GetInteger();
	if ((nHour < 0 || nHour > 23)   ||
		(nMinute < 0 || nMinute > 59 )	||
		(nSecond < 0 || nSecond > 59 ))
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}

	sal_Int32 nSeconds = nHour;
	nSeconds *= 3600;
	nSeconds += nMinute * 60;
	nSeconds += nSecond;
	double nDays = ((double)nSeconds) / (double)(86400.0);
	rPar.Get(0)->PutDate( nDays ); // JSM
}

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

	if ( rPar.Count() < 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
		// #39629 pINST pruefen, kann aus URL-Zeile gerufen werden
		SvNumberFormatter* pFormatter = NULL;
		if( pINST )
			pFormatter = pINST->GetNumberFormatter();
		else
		{
			sal_uInt32 n;	// Dummy
			SbiInstance::PrepareNumberFormatter( pFormatter, n, n, n );
		}

		sal_uInt32 nIndex = 0;
		double fResult;
		String aStr( rPar.Get(1)->GetString() );
		sal_Bool bSuccess = pFormatter->IsNumberFormat( aStr, nIndex, fResult );
		short nType = pFormatter->GetType( nIndex );

		// DateValue("February 12, 1969") raises error if the system locale is not en_US
		// by using SbiInstance::GetNumberFormatter.
		// It seems that both locale number formatter and English number formatter
		// are supported in Visual Basic.
		LanguageType eLangType = GetpApp()->GetSettings().GetLanguage();
        if( !bSuccess && ( eLangType != LANGUAGE_ENGLISH_US ) )
		{
			// Create a new SvNumberFormatter by using LANGUAGE_ENGLISH to get the date value;
			com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >
				xFactory = comphelper::getProcessServiceFactory();
			SvNumberFormatter aFormatter( xFactory, LANGUAGE_ENGLISH_US );
			bSuccess = aFormatter.IsNumberFormat( aStr, nIndex, fResult );
			nType = aFormatter.GetType( nIndex );
		}

		if(bSuccess && (nType==NUMBERFORMAT_DATE || nType==NUMBERFORMAT_DATETIME))
		{
			if ( nType == NUMBERFORMAT_DATETIME )
			{
				// Zeit abschneiden
				if ( fResult  > 0.0 )
					fResult = floor( fResult );
				else
					fResult = ceil( fResult );
			}
			// fResult += 2.0; // Anpassung  StarCalcFormatter
			rPar.Get(0)->PutDate( fResult ); // JSM
		}
		else
			StarBASIC::Error( SbERR_CONVERSION );

		// #39629 pFormatter kann selbst angefordert sein
		if( !pINST )
			delete pFormatter;
	}
}

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

	if ( rPar.Count() < 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
		// #39629 pINST pruefen, kann aus URL-Zeile gerufen werden
		SvNumberFormatter* pFormatter = NULL;
		if( pINST )
			pFormatter = pINST->GetNumberFormatter();
		else
		{
			sal_uInt32 n;	// Dummy
			SbiInstance::PrepareNumberFormatter( pFormatter, n, n, n );
		}

		sal_uInt32 nIndex = 0;
		double fResult;
		sal_Bool bSuccess = pFormatter->IsNumberFormat( rPar.Get(1)->GetString(),
												   nIndex, fResult );
		short nType = pFormatter->GetType(nIndex);
		if(bSuccess && (nType==NUMBERFORMAT_TIME||nType==NUMBERFORMAT_DATETIME))
		{
			if ( nType == NUMBERFORMAT_DATETIME )
				// Tage abschneiden
				fResult = fmod( fResult, 1 );
			rPar.Get(0)->PutDate( fResult ); // JSM
		}
		else
			StarBASIC::Error( SbERR_CONVERSION );

		// #39629 pFormatter kann selbst angefordert sein
		if( !pINST )
			delete pFormatter;
	}
}

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

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

        sal_Int16 nDay = implGetDateDay( aDate );
		rPar.Get(0)->PutInteger( nDay );
	}
}

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

	if ( rPar.Count() < 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
        sal_Int16 nYear = implGetDateYear( rPar.Get(1)->GetDate() );
		rPar.Get(0)->PutInteger( nYear );
	}
}

sal_Int16 implGetHour( double dDate )
{
	double nFrac = dDate - floor( dDate );
	nFrac *= 86400.0;
	sal_Int32 nSeconds = (sal_Int32)(nFrac + 0.5);
	sal_Int16 nHour = (sal_Int16)(nSeconds / 3600);
    return nHour;
}

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

	if ( rPar.Count() < 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
		double nArg = rPar.Get(1)->GetDate();
		sal_Int16 nHour = implGetHour( nArg );
		rPar.Get(0)->PutInteger( nHour );
	}
}

sal_Int16 implGetMinute( double dDate )
{
	double nFrac = dDate - floor( dDate );
	nFrac *= 86400.0;
	sal_Int32 nSeconds = (sal_Int32)(nFrac + 0.5);
	sal_Int16 nTemp = (sal_Int16)(nSeconds % 3600);
	sal_Int16 nMin = nTemp / 60;
    return nMin;
}

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

	if ( rPar.Count() < 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
		double nArg = rPar.Get(1)->GetDate();
		sal_Int16 nMin = implGetMinute( nArg );
		rPar.Get(0)->PutInteger( nMin );
	}
}

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

	if ( rPar.Count() < 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
        sal_Int16 nMonth = implGetDateMonth( rPar.Get(1)->GetDate() );
		rPar.Get(0)->PutInteger( nMonth );
	}
}

sal_Int16 implGetSecond( double dDate )
{
	double nFrac = dDate - floor( dDate );
	nFrac *= 86400.0;
	sal_Int32 nSeconds = (sal_Int32)(nFrac + 0.5);
	sal_Int16 nTemp = (sal_Int16)(nSeconds / 3600);
	nSeconds -= nTemp * 3600;
	nTemp = (sal_Int16)(nSeconds / 60);
	nSeconds -= nTemp * 60;

	sal_Int16 nRet = (sal_Int16)nSeconds;
    return nRet;
}

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

	if ( rPar.Count() < 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
		double nArg = rPar.Get(1)->GetDate();
		sal_Int16 nSecond = implGetSecond( nArg );
		rPar.Get(0)->PutInteger( nSecond );
	}
}

double Now_Impl()
{
	Date aDate;
	Time aTime;
	double aSerial = (double)GetDayDiff( aDate );
	long nSeconds = aTime.GetHour();
	nSeconds *= 3600;
	nSeconds += aTime.GetMin() * 60;
	nSeconds += aTime.GetSec();
	double nDays = ((double)nSeconds) / (double)(24.0*3600.0);
	aSerial += nDays;
	return aSerial;
}

// Date Now(void)

RTLFUNC(Now)
{
    	(void)pBasic;
    	(void)bWrite;
	rPar.Get(0)->PutDate( Now_Impl() );
}

// Date Time(void)

RTLFUNC(Time)
{
    (void)pBasic;

	if ( !bWrite )
	{
		Time aTime;
		SbxVariable* pMeth = rPar.Get( 0 );
		String aRes;
		if( pMeth->IsFixed() )
		{
			// Time$: hh:mm:ss
			char buf[ 20 ];
            snprintf( buf, sizeof(buf), "%02d:%02d:%02d",
				aTime.GetHour(), aTime.GetMin(), aTime.GetSec() );
			aRes = String::CreateFromAscii( buf );
		}
		else
		{
			// Time: system dependent
			long nSeconds=aTime.GetHour();
			nSeconds *= 3600;
			nSeconds += aTime.GetMin() * 60;
			nSeconds += aTime.GetSec();
			double nDays = (double)nSeconds * ( 1.0 / (24.0*3600.0) );
			Color* pCol;

			// #39629 pINST pruefen, kann aus URL-Zeile gerufen werden
			SvNumberFormatter* pFormatter = NULL;
			sal_uInt32 nIndex;
			if( pINST )
			{
				pFormatter = pINST->GetNumberFormatter();
				nIndex = pINST->GetStdTimeIdx();
			}
			else
			{
				sal_uInt32 n;	// Dummy
				SbiInstance::PrepareNumberFormatter( pFormatter, n, nIndex, n );
			}

			pFormatter->GetOutputString( nDays, nIndex, aRes, &pCol );

			// #39629 pFormatter kann selbst angefordert sein
			if( !pINST )
				delete pFormatter;
		}
		pMeth->PutString( aRes );
	}
	else
	{
		StarBASIC::Error( SbERR_NOT_IMPLEMENTED );
	}
}

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

	Time aTime;
	long nSeconds = aTime.GetHour();
	nSeconds *= 3600;
	nSeconds += aTime.GetMin() * 60;
	nSeconds += aTime.GetSec();
	rPar.Get(0)->PutDate( (double)nSeconds );
}


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

	if ( !bWrite )
	{
		Date aToday;
		double nDays = (double)GetDayDiff( aToday );
		SbxVariable* pMeth = rPar.Get( 0 );
		if( pMeth->IsString() )
		{
			String aRes;
			Color* pCol;

			// #39629 pINST pruefen, kann aus URL-Zeile gerufen werden
			SvNumberFormatter* pFormatter = NULL;
			sal_uInt32 nIndex;
			if( pINST )
			{
				pFormatter = pINST->GetNumberFormatter();
				nIndex = pINST->GetStdDateIdx();
			}
			else
			{
				sal_uInt32 n;	// Dummy
				SbiInstance::PrepareNumberFormatter( pFormatter, nIndex, n, n );
			}

			pFormatter->GetOutputString( nDays, nIndex, aRes, &pCol );
			pMeth->PutString( aRes );

			// #39629 pFormatter kann selbst angefordert sein
			if( !pINST )
				delete pFormatter;
		}
		else
			pMeth->PutDate( nDays );
	}
	else
	{
		StarBASIC::Error( SbERR_NOT_IMPLEMENTED );
	}
}

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

	if ( rPar.Count() < 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
		rPar.Get(0)->PutBool((rPar.Get(1)->GetType() & SbxARRAY) ? sal_True : sal_False );
}

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

	if ( rPar.Count() < 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
    {
    	SbxVariable* pVar = rPar.Get(1);
	    SbxBase* pObj = (SbxBase*)pVar->GetObject();

		// #100385: GetObject can result in an error, so reset it
		SbxBase::ResetError();

        SbUnoClass* pUnoClass;
        sal_Bool bObject;
	    if( pObj &&  NULL != ( pUnoClass=PTR_CAST(SbUnoClass,pObj) ) )
        {
            bObject = pUnoClass->getUnoClass().is();
        }
        else
        {
            bObject = pVar->IsObject();
        }
		rPar.Get( 0 )->PutBool( bObject );
    }
}

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

	if ( rPar.Count() < 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
		// #46134 Nur String wird konvertiert, andere Typen ergeben sal_False
		SbxVariableRef xArg = rPar.Get( 1 );
		SbxDataType eType = xArg->GetType();
		sal_Bool bDate = sal_False;

		if( eType == SbxDATE )
		{
			bDate = sal_True;
		}
		else if( eType == SbxSTRING )
		{
			// Error loeschen
			SbxError nPrevError = SbxBase::GetError();
			SbxBase::ResetError();

			// Konvertierung des Parameters nach SbxDATE erzwingen
			xArg->SbxValue::GetDate();

			// Bei Fehler ist es kein Date
			bDate = !SbxBase::IsError();

			// Error-Situation wiederherstellen
			SbxBase::ResetError();
			SbxBase::SetError( nPrevError );
		}
		rPar.Get( 0 )->PutBool( bDate );
	}
}

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

	if ( rPar.Count() < 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
		rPar.Get( 0 )->PutBool( rPar.Get(1)->IsEmpty() );
}

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

	if ( rPar.Count() < 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
		rPar.Get( 0 )->PutBool( rPar.Get(1)->IsErr() );
}

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

	if ( rPar.Count() < 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
		// #51475 Wegen Uno-Objekten auch true liefern,
		// wenn der pObj-Wert NULL ist
		SbxVariableRef pArg = rPar.Get( 1 );
		sal_Bool bNull = rPar.Get(1)->IsNull();
		if( !bNull && pArg->GetType() == SbxOBJECT )
		{
			SbxBase* pObj = pArg->GetObject();
			if( !pObj )
				bNull = sal_True;
		}
		rPar.Get( 0 )->PutBool( bNull );
	}
}

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

	if ( rPar.Count() < 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
		rPar.Get( 0 )->PutBool( rPar.Get( 1 )->IsNumericRTL() );
}

// Das machen wir auf die billige Tour

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

	if ( rPar.Count() < 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
		// #57915 Missing wird durch Error angezeigt
		rPar.Get( 0 )->PutBool( rPar.Get(1)->IsErr() );
}

// Dir( [Maske] [,Attrs] )
// ToDo: Library-globaler Datenbereich fuer Dir-Objekt und Flags


String getDirectoryPath( String aPathStr )
{
    String aRetStr;

    DirectoryItem aItem;
    FileBase::RC nRet = DirectoryItem::get( aPathStr, aItem );
	if( nRet == FileBase::E_None )
	{
		FileStatus aFileStatus( FileStatusMask_Type );
		nRet = aItem.getFileStatus( aFileStatus );
		if( nRet == FileBase::E_None )
		{
			FileStatus::Type aType = aFileStatus.getFileType();
			if( isFolder( aType ) )
            {
        		aRetStr = aPathStr;
            }
            else if( aType == FileStatus::Link )
            {
        		FileStatus aFileStatus2( FileStatusMask_LinkTargetURL );
        		nRet = aItem.getFileStatus( aFileStatus2 );
		        if( nRet == FileBase::E_None )
                    aRetStr = getDirectoryPath( aFileStatus2.getLinkTargetURL() );
            }
		}
    }
    return aRetStr;
}

// Function looks for wildcards, removes them and always returns the pure path
String implSetupWildcard( const String& rFileParam, SbiRTLData* pRTLData )
{
    static String aAsterisk = String::CreateFromAscii( "*" );
	static sal_Char cDelim1 = (sal_Char)'/';
	static sal_Char cDelim2 = (sal_Char)'\\';
	static sal_Char cWild1 = '*';
	static sal_Char cWild2 = '?';

	delete pRTLData->pWildCard;
	pRTLData->pWildCard = NULL;
	pRTLData->sFullNameToBeChecked = String();

	String aFileParam = rFileParam;
	xub_StrLen nLastWild = aFileParam.SearchBackward( cWild1 );
	if( nLastWild == STRING_NOTFOUND )
		nLastWild = aFileParam.SearchBackward( cWild2 );
	sal_Bool bHasWildcards = ( nLastWild != STRING_NOTFOUND );


	xub_StrLen nLastDelim = aFileParam.SearchBackward( cDelim1 );
	if( nLastDelim == STRING_NOTFOUND )
		nLastDelim = aFileParam.SearchBackward( cDelim2 );

    if( bHasWildcards )
    {
        // Wildcards in path?
        if( nLastDelim != STRING_NOTFOUND && nLastDelim > nLastWild )
            return aFileParam;
    }
    else
    {
	    String aPathStr = getFullPath( aFileParam );
        if( nLastDelim != aFileParam.Len() - 1 )
            pRTLData->sFullNameToBeChecked = aPathStr;
        return aPathStr;
    }

	String aPureFileName;
	if( nLastDelim == STRING_NOTFOUND )
	{
		aPureFileName = aFileParam;
		aFileParam = String();
	}
	else
	{
		aPureFileName = aFileParam.Copy( nLastDelim + 1 );
		aFileParam = aFileParam.Copy( 0, nLastDelim );
	}

	// Try again to get a valid URL/UNC-path with only the path
	String aPathStr = getFullPath( aFileParam );
	xub_StrLen nPureLen = aPureFileName.Len();

	// Is there a pure file name left? Otherwise the path is
	// invalid anyway because it was not accepted by OSL before
	if( nPureLen && aPureFileName != aAsterisk )
	{
		pRTLData->pWildCard = new WildCard( aPureFileName );
	}
	return aPathStr;
}

inline sal_Bool implCheckWildcard( const String& rName, SbiRTLData* pRTLData )
{
	sal_Bool bMatch = sal_True;

	if( pRTLData->pWildCard )
		bMatch = pRTLData->pWildCard->Matches( rName );
	return bMatch;
}


bool isRootDir( String aDirURLStr )
{
	INetURLObject aDirURLObj( aDirURLStr );
	sal_Bool bRoot = sal_False;

	// Check if it's a root directory
	sal_Int32 nCount = aDirURLObj.getSegmentCount();

	// No segment means Unix root directory "file:///"
	if( nCount == 0 )
	{
		bRoot = sal_True;
	}
	// Exactly one segment needs further checking, because it
	// can be Unix "file:///foo/" -> no root
	// or Windows  "file:///c:/"  -> root
	else if( nCount == 1 )
	{
		::rtl::OUString aSeg1 = aDirURLObj.getName( 0, sal_True,
			INetURLObject::DECODE_WITH_CHARSET );
		if( aSeg1.getStr()[1] == (sal_Unicode)':' )
		{
			bRoot = sal_True;
		}
	}
	// More than one segments can never be root
	// so bRoot remains sal_False

    return bRoot;
}

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

	String aPath;

	sal_uInt16 nParCount = rPar.Count();
	if( nParCount > 3 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
		SbiRTLData* pRTLData = pINST->GetRTLData();

		// #34645: Kann auch von der URL-Zeile ueber 'macro: Dir' aufgerufen werden
		// dann existiert kein pRTLData und die Methode muss verlassen werden
		if( !pRTLData )
			return;

		// <-- UCB
		if( hasUno() )
		{
			com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess();
			if( xSFI.is() )
			{
				if ( nParCount >= 2 )
				{
					String aFileParam = rPar.Get(1)->GetString();

					String aFileURLStr = implSetupWildcard( aFileParam, pRTLData );
                    if( pRTLData->sFullNameToBeChecked.Len() > 0 )
                    {
						sal_Bool bExists = sal_False;
						try	{ bExists = xSFI->exists( aFileURLStr ); }
						catch( Exception & ) {}

                        String aNameOnlyStr;
						if( bExists )
                        {
							INetURLObject aFileURL( aFileURLStr );
							aNameOnlyStr = aFileURL.getName( INetURLObject::LAST_SEGMENT,
								true, INetURLObject::DECODE_WITH_CHARSET );
                        }
						rPar.Get(0)->PutString( aNameOnlyStr );
						return;
                    }

					try
					{
						String aDirURLStr;
						sal_Bool bFolder = xSFI->isFolder( aFileURLStr );

						if( bFolder )
						{
							aDirURLStr = aFileURLStr;
						}
						else
						{
                            String aEmptyStr;
							rPar.Get(0)->PutString( aEmptyStr );
						}

						sal_uInt16 nFlags = 0;
						if ( nParCount > 2 )
							pRTLData->nDirFlags = nFlags = rPar.Get(2)->GetInteger();
						else
							pRTLData->nDirFlags = 0;

						// Read directory
						sal_Bool bIncludeFolders = ((nFlags & Sb_ATTR_DIRECTORY) != 0);
						pRTLData->aDirSeq = xSFI->getFolderContents( aDirURLStr, bIncludeFolders );
						pRTLData->nCurDirPos = 0;

						// #78651 Add "." and ".." directories for VB compatibility
						if( bIncludeFolders )
						{
							sal_Bool bRoot = isRootDir( aDirURLStr );

							// If it's no root directory we flag the need for
							// the "." and ".." directories by the value -2
							// for the actual position. Later for -2 will be
							// returned "." and for -1 ".."
							if( !bRoot )
							{
								pRTLData->nCurDirPos = -2;
							}
						}
					}
					catch( Exception & )
					{
						//StarBASIC::Error( ERRCODE_IO_GENERAL );
					}
				}


				if( pRTLData->aDirSeq.getLength() > 0 )
				{
					sal_Bool bFolderFlag = ((pRTLData->nDirFlags & Sb_ATTR_DIRECTORY) != 0);

					SbiInstance* pInst = pINST;
					bool bCompatibility = ( pInst && pInst->IsCompatibility() );
					for( ;; )
					{
						if( pRTLData->nCurDirPos < 0 )
						{
							if( pRTLData->nCurDirPos == -2 )
							{
								aPath = ::rtl::OUString::createFromAscii( "." );
							}
							else if( pRTLData->nCurDirPos == -1 )
							{
								aPath = ::rtl::OUString::createFromAscii( ".." );
							}
							pRTLData->nCurDirPos++;
						}
						else if( pRTLData->nCurDirPos >= pRTLData->aDirSeq.getLength() )
						{
							pRTLData->aDirSeq.realloc( 0 );
							aPath.Erase();
							break;
						}
						else
						{
							::rtl::OUString aFile = pRTLData->aDirSeq.getConstArray()[pRTLData->nCurDirPos++];

							if( bCompatibility )
							{
								if( !bFolderFlag )
								{
									sal_Bool bFolder = xSFI->isFolder( aFile );
									if( bFolder )
										continue;
								}
							}
							else
							{
								// Only directories
								if( bFolderFlag )
								{
									sal_Bool bFolder = xSFI->isFolder( aFile );
									if( !bFolder )
										continue;
								}
							}

							INetURLObject aURL( aFile );
							aPath = aURL.getName( INetURLObject::LAST_SEGMENT, sal_True,
								INetURLObject::DECODE_WITH_CHARSET );
						}

						sal_Bool bMatch = implCheckWildcard( aPath, pRTLData );
						if( !bMatch )
							continue;

						break;
					}
				}
				rPar.Get(0)->PutString( aPath );
			}
		}
		else
		// --> UCB
		{
#ifdef _OLD_FILE_IMPL
			if ( nParCount >= 2 )
			{
				delete pRTLData->pDir;
				pRTLData->pDir = 0; // wg. Sonderbehandlung Sb_ATTR_VOLUME
				DirEntry aEntry( rPar.Get(1)->GetString() );
				FileStat aStat( aEntry );
				if(!aStat.GetError() && (aStat.GetKind() & FSYS_KIND_FILE))
				{
					// ah ja, ist nur ein dateiname
					// Pfad abschneiden (wg. VB4)
					rPar.Get(0)->PutString( aEntry.GetName() );
					return;
				}
				sal_uInt16 nFlags = 0;
				if ( nParCount > 2 )
					pRTLData->nDirFlags = nFlags = rPar.Get(2)->GetInteger();
				else
					pRTLData->nDirFlags = 0;

				// Sb_ATTR_VOLUME wird getrennt gehandelt
				if( pRTLData->nDirFlags & Sb_ATTR_VOLUME )
					aPath = aEntry.GetVolume();
				else
				{
					// Die richtige Auswahl treffen
					sal_uInt16 nMode = FSYS_KIND_FILE;
					if( nFlags & Sb_ATTR_DIRECTORY )
						nMode |= FSYS_KIND_DIR;
					if( nFlags == Sb_ATTR_DIRECTORY )
						nMode = FSYS_KIND_DIR;
					pRTLData->pDir = new Dir( aEntry, (DirEntryKind) nMode );
					pRTLData->nCurDirPos = 0;
				}
			}

			if( pRTLData->pDir )
			{
				for( ;; )
				{
					if( pRTLData->nCurDirPos >= pRTLData->pDir->Count() )
					{
						delete pRTLData->pDir;
						pRTLData->pDir = 0;
						aPath.Erase();
						break;
					}
					DirEntry aNextEntry=(*(pRTLData->pDir))[pRTLData->nCurDirPos++];
					aPath = aNextEntry.GetName(); //Full();
					break;
				}
			}
			rPar.Get(0)->PutString( aPath );
#else
			// TODO: OSL
			if ( nParCount >= 2 )
			{
				String aFileParam = rPar.Get(1)->GetString();

				String aDirURL = implSetupWildcard( aFileParam, pRTLData );

				sal_uInt16 nFlags = 0;
				if ( nParCount > 2 )
					pRTLData->nDirFlags = nFlags = rPar.Get(2)->GetInteger();
				else
					pRTLData->nDirFlags = 0;

				// Read directory
				sal_Bool bIncludeFolders = ((nFlags & Sb_ATTR_DIRECTORY) != 0);
				pRTLData->pDir = new Directory( aDirURL );
				FileBase::RC nRet = pRTLData->pDir->open();
				if( nRet != FileBase::E_None )
				{
					delete pRTLData->pDir;
					pRTLData->pDir = NULL;
					rPar.Get(0)->PutString( String() );
					return;
				}

				// #86950 Add "." and ".." directories for VB compatibility
				pRTLData->nCurDirPos = 0;
				if( bIncludeFolders )
				{
					sal_Bool bRoot = isRootDir( aDirURL );

					// If it's no root directory we flag the need for
					// the "." and ".." directories by the value -2
					// for the actual position. Later for -2 will be
					// returned "." and for -1 ".."
					if( !bRoot )
					{
						pRTLData->nCurDirPos = -2;
					}
				}

			}

			if( pRTLData->pDir )
			{
				sal_Bool bFolderFlag = ((pRTLData->nDirFlags & Sb_ATTR_DIRECTORY) != 0);
				for( ;; )
				{
					if( pRTLData->nCurDirPos < 0 )
					{
						if( pRTLData->nCurDirPos == -2 )
						{
							aPath = ::rtl::OUString::createFromAscii( "." );
						}
						else if( pRTLData->nCurDirPos == -1 )
						{
							aPath = ::rtl::OUString::createFromAscii( ".." );
						}
						pRTLData->nCurDirPos++;
					}
                    else
                    {
					    DirectoryItem aItem;
				        FileBase::RC nRet = pRTLData->pDir->getNextItem( aItem );
					    if( nRet != FileBase::E_None )
					    {
						    delete pRTLData->pDir;
						    pRTLData->pDir = NULL;
						    aPath.Erase();
						    break;
					    }

					    // Handle flags
					    FileStatus aFileStatus( FileStatusMask_Type | FileStatusMask_FileName );
					    nRet = aItem.getFileStatus( aFileStatus );

					    // Only directories?
					    if( bFolderFlag )
					    {
						    FileStatus::Type aType = aFileStatus.getFileType();
						    sal_Bool bFolder = isFolder( aType );
						    if( !bFolder )
							    continue;
					    }

					    aPath = aFileStatus.getFileName();
                    }

					sal_Bool bMatch = implCheckWildcard( aPath, pRTLData );
					if( !bMatch )
						continue;

					break;
				}
			}
			rPar.Get(0)->PutString( aPath );
#endif
		}
	}
}


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

	if ( rPar.Count() == 2 )
	{
		sal_Int16 nFlags = 0;

		// In Windows, We want to use Windows API to get the file attributes
		// for VBA interoperability.
	#if defined( WNT )
		if( SbiRuntime::isVBAEnabled() )
		{
			DirEntry aEntry( rPar.Get(1)->GetString() );
			aEntry.ToAbs();

			// #57064 Bei virtuellen URLs den Real-Path extrahieren
			ByteString aByteStrFullPath( aEntry.GetFull(), gsl_getSystemTextEncoding() );
			DWORD nRealFlags = GetFileAttributes (aByteStrFullPath.GetBuffer());
			if (nRealFlags != 0xffffffff)
			{
				if (nRealFlags == FILE_ATTRIBUTE_NORMAL)
					nRealFlags = 0;
				nFlags = (sal_Int16) (nRealFlags);
			}
			else
				StarBASIC::Error( SbERR_FILE_NOT_FOUND );

			rPar.Get(0)->PutInteger( nFlags );

			return;
		}
	#endif

		// <-- UCB
		if( hasUno() )
		{
			com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess();
			if( xSFI.is() )
			{
				try
				{
					String aPath = getFullPath( rPar.Get(1)->GetString() );
					sal_Bool bExists = sal_False;
					try { bExists = xSFI->exists( aPath ); }
					catch( Exception & ) {}
					if( !bExists )
					{
						StarBASIC::Error( SbERR_FILE_NOT_FOUND );
						return;
					}

					sal_Bool bReadOnly = xSFI->isReadOnly( aPath );
					sal_Bool bHidden = xSFI->isHidden( aPath );
					sal_Bool bDirectory = xSFI->isFolder( aPath );
					if( bReadOnly )
						nFlags |= 0x0001; // ATTR_READONLY
					if( bHidden )
						nFlags |= 0x0002; // ATTR_HIDDEN
					if( bDirectory )
						nFlags |= 0x0010; // ATTR_DIRECTORY
				}
				catch( Exception & )
				{
					StarBASIC::Error( ERRCODE_IO_GENERAL );
				}
			}
		}
		else
		// --> UCB
		{
			DirectoryItem aItem;
			FileBase::RC nRet = DirectoryItem::get( getFullPathUNC( rPar.Get(1)->GetString() ), aItem );
			FileStatus aFileStatus( FileStatusMask_Attributes | FileStatusMask_Type );
			nRet = aItem.getFileStatus( aFileStatus );
			sal_uInt64 nAttributes = aFileStatus.getAttributes();
			sal_Bool bReadOnly = (nAttributes & Attribute_ReadOnly) != 0;

			FileStatus::Type aType = aFileStatus.getFileType();
			sal_Bool bDirectory = isFolder( aType );
			if( bReadOnly )
				nFlags |= 0x0001; // ATTR_READONLY
			if( bDirectory )
				nFlags |= 0x0010; // ATTR_DIRECTORY
		}
		rPar.Get(0)->PutInteger( nFlags );
	}
	else
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
}


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

	if ( rPar.Count() != 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
		// <-- UCB
		String aPath = rPar.Get(1)->GetString();
		Time aTime;
		Date aDate;
		if( hasUno() )
		{
			com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess();
			if( xSFI.is() )
			{
				try
				{
					com::sun::star::util::DateTime aUnoDT = xSFI->getDateTimeModified( aPath );
					aTime = Time( aUnoDT.Hours, aUnoDT.Minutes, aUnoDT.Seconds, aUnoDT.HundredthSeconds );
					aDate = Date( aUnoDT.Day, aUnoDT.Month, aUnoDT.Year );
				}
				catch( Exception & )
				{
					StarBASIC::Error( ERRCODE_IO_GENERAL );
				}
			}
		}
		else
		// --> UCB
		{
#ifdef _OLD_FILE_IMPL
			DirEntry aEntry( aPath );
			FileStat aStat( aEntry );
			aTime = Time( aStat.TimeModified() );
			aDate = Date( aStat.DateModified() );
#else
			DirectoryItem aItem;
			FileBase::RC nRet = DirectoryItem::get( getFullPathUNC( aPath ), aItem );
			FileStatus aFileStatus( FileStatusMask_ModifyTime );
		    nRet = aItem.getFileStatus( aFileStatus );
		    TimeValue aTimeVal = aFileStatus.getModifyTime();
			oslDateTime aDT;
			osl_getDateTimeFromTimeValue( &aTimeVal, &aDT );

			aTime = Time( aDT.Hours, aDT.Minutes, aDT.Seconds, 10000000*aDT.NanoSeconds );
			aDate = Date( aDT.Day, aDT.Month, aDT.Year );
#endif
		}

		double fSerial = (double)GetDayDiff( aDate );
		long nSeconds = aTime.GetHour();
		nSeconds *= 3600;
		nSeconds += aTime.GetMin() * 60;
		nSeconds += aTime.GetSec();
		double nDays = ((double)nSeconds) / (double)(24.0*3600.0);
		fSerial += nDays;

		Color* pCol;

		// #39629 pINST pruefen, kann aus URL-Zeile gerufen werden
		SvNumberFormatter* pFormatter = NULL;
		sal_uInt32 nIndex;
		if( pINST )
		{
			pFormatter = pINST->GetNumberFormatter();
			nIndex = pINST->GetStdDateTimeIdx();
		}
		else
		{
			sal_uInt32 n;	// Dummy
			SbiInstance::PrepareNumberFormatter( pFormatter, n, n, nIndex );
		}

		String aRes;
		pFormatter->GetOutputString( fSerial, nIndex, aRes, &pCol );
		rPar.Get(0)->PutString( aRes );

		// #39629 pFormatter kann selbst angefordert sein
		if( !pINST )
			delete pFormatter;
	}
}


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

	// AB 08/16/2000: No changes for UCB
	if ( rPar.Count() != 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
		sal_Int16 nChannel = rPar.Get(1)->GetInteger();
		// nChannel--;  // macht MD beim Oeffnen auch nicht
		SbiIoSystem* pIO = pINST->GetIoSystem();
		SbiStream* pSbStrm = pIO->GetStream( nChannel );
		if ( !pSbStrm )
		{
			StarBASIC::Error( SbERR_BAD_CHANNEL );
			return;
		}
		sal_Bool bIsEof;
		SvStream* pSvStrm = pSbStrm->GetStrm();
		if ( pSbStrm->IsText() )
		{
			char cBla;
			(*pSvStrm) >> cBla;	// koennen wir noch ein Zeichen lesen
			bIsEof = pSvStrm->IsEof();
			if ( !bIsEof )
				pSvStrm->SeekRel( -1 );
		}
		else
			bIsEof = pSvStrm->IsEof();  // fuer binaerdateien!
		rPar.Get(0)->PutBool( bIsEof );
	}
}

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

	// AB 08/16/2000: No changes for UCB

	// #57064 Obwohl diese Funktion nicht mit DirEntry arbeitet, ist sie von
	// der Anpassung an virtuelle URLs nich betroffen, da sie nur auf bereits
	// geoeffneten Dateien arbeitet und der Name hier keine Rolle spielt.

	if ( rPar.Count() != 3 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
		sal_Int16 nChannel = rPar.Get(1)->GetInteger();
//		nChannel--;
		SbiIoSystem* pIO = pINST->GetIoSystem();
		SbiStream* pSbStrm = pIO->GetStream( nChannel );
		if ( !pSbStrm )
		{
			StarBASIC::Error( SbERR_BAD_CHANNEL );
			return;
		}
		sal_Int16 nRet;
		if ( rPar.Get(2)->GetInteger() == 1 )
			nRet = (sal_Int16)(pSbStrm->GetMode());
		else
			nRet = 0; // System file handle not supported

		rPar.Get(0)->PutInteger( nRet );
	}
}
RTLFUNC(Loc)
{
    (void)pBasic;
    (void)bWrite;

	// AB 08/16/2000: No changes for UCB
	if ( rPar.Count() != 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
		sal_Int16 nChannel = rPar.Get(1)->GetInteger();
		SbiIoSystem* pIO = pINST->GetIoSystem();
		SbiStream* pSbStrm = pIO->GetStream( nChannel );
		if ( !pSbStrm )
		{
			StarBASIC::Error( SbERR_BAD_CHANNEL );
			return;
		}
		SvStream* pSvStrm = pSbStrm->GetStrm();
		sal_uIntPtr nPos;
		if( pSbStrm->IsRandom())
		{
			short nBlockLen = pSbStrm->GetBlockLen();
			nPos = nBlockLen ? (pSvStrm->Tell() / nBlockLen) : 0;
			nPos++; // Blockpositionen beginnen bei 1
		}
		else if ( pSbStrm->IsText() )
			nPos = pSbStrm->GetLine();
		else if( pSbStrm->IsBinary() )
			nPos = pSvStrm->Tell();
		else if ( pSbStrm->IsSeq() )
			nPos = ( pSvStrm->Tell()+1 ) / 128;
		else
			nPos = pSvStrm->Tell();
		rPar.Get(0)->PutLong( (sal_Int32)nPos );
	}
}

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

	// AB 08/16/2000: No changes for UCB
	if ( rPar.Count() != 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
		sal_Int16 nChannel = rPar.Get(1)->GetInteger();
		SbiIoSystem* pIO = pINST->GetIoSystem();
		SbiStream* pSbStrm = pIO->GetStream( nChannel );
		if ( !pSbStrm )
		{
			StarBASIC::Error( SbERR_BAD_CHANNEL );
			return;
		}
		SvStream* pSvStrm = pSbStrm->GetStrm();
		sal_uIntPtr nOldPos = pSvStrm->Tell();
		sal_uIntPtr nLen = pSvStrm->Seek( STREAM_SEEK_TO_END );
		pSvStrm->Seek( nOldPos );
		rPar.Get(0)->PutLong( (sal_Int32)nLen );
	}
}


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

	// AB 08/16/2000: No changes for UCB
	int nArgs = (int)rPar.Count();
	if ( nArgs < 2 || nArgs > 3 )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}
	sal_Int16 nChannel = rPar.Get(1)->GetInteger();
//	nChannel--;
	SbiIoSystem* pIO = pINST->GetIoSystem();
	SbiStream* pSbStrm = pIO->GetStream( nChannel );
	if ( !pSbStrm )
	{
		StarBASIC::Error( SbERR_BAD_CHANNEL );
		return;
	}
	SvStream* pStrm = pSbStrm->GetStrm();

	if ( nArgs == 2 )   // Seek-Function
	{
		sal_uIntPtr nPos = pStrm->Tell();
		if( pSbStrm->IsRandom() )
			nPos = nPos / pSbStrm->GetBlockLen();
		nPos++;	// Basic zaehlt ab 1
		rPar.Get(0)->PutLong( (sal_Int32)nPos );
	}
	else                // Seek-Statement
	{
		sal_Int32 nPos = rPar.Get(2)->GetLong();
		if ( nPos < 1 )
		{
			StarBASIC::Error( SbERR_BAD_ARGUMENT );
			return;
		}
		nPos--; // Basic zaehlt ab 1, SvStreams zaehlen ab 0
		pSbStrm->SetExpandOnWriteTo( 0 );
		if ( pSbStrm->IsRandom() )
			nPos *= pSbStrm->GetBlockLen();
		pStrm->Seek( (sal_uIntPtr)nPos );
		pSbStrm->SetExpandOnWriteTo( nPos );
	}
}

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

	sal_uInt16 nArgCount = (sal_uInt16)rPar.Count();
	if ( nArgCount < 2 || nArgCount > 3 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
		String aResult;
		if( nArgCount == 2 )
			rPar.Get(1)->Format( aResult );
		else
		{
			String aFmt( rPar.Get(2)->GetString() );
		    rPar.Get(1)->Format( aResult, &aFmt );
		}
		rPar.Get(0)->PutString( aResult );
	}
}

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

	if ( rPar.Count() > 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	sal_Int16 nSeed;
	if( rPar.Count() == 2 )
		nSeed = (sal_Int16)rPar.Get(1)->GetInteger();
	else
		nSeed = (sal_Int16)rand();
	srand( nSeed );
}

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

	if ( rPar.Count() > 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
		double nRand = (double)rand();
		nRand = ( nRand / (double)RAND_MAX );
		rPar.Get(0)->PutDouble( nRand );
	}
}


//
//  Syntax: Shell("Path",[ Window-Style,[ "Params", [ bSync = sal_False ]]])
//
//  WindowStyles (VBA-kompatibel):
//      2 == Minimized
//	    3 == Maximized
//     10 == Full-Screen (Textmodus-Anwendungen OS/2, WIN95, WNT)
//
// !!!HACK der WindowStyle wird im Creator an Application::StartApp
//         uebergeben. Format: "xxxx2"
//


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

	// No shell command for "virtual" portal users
	if( needSecurityRestrictions() )
	{
		StarBASIC::Error(SbERR_NOT_IMPLEMENTED);
		return;
	}

	sal_uIntPtr nArgCount = rPar.Count();
	if ( nArgCount < 2 || nArgCount > 5 )
	{
		rPar.Get(0)->PutLong(0);
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	}
	else
	{
		sal_uInt16 nOptions = vos::OProcess::TOption_SearchPath|
						  vos::OProcess::TOption_Detached;
		String aCmdLine = rPar.Get(1)->GetString();
		// Zusaetzliche Parameter anhaengen, es muss eh alles geparsed werden
		if( nArgCount >= 4 )
		{
			aCmdLine.AppendAscii( " " );
			aCmdLine += rPar.Get(3)->GetString();
		}
		else if( !aCmdLine.Len() )
		{
			// Spezial-Behandlung (leere Liste) vermeiden
			aCmdLine.AppendAscii( " " );
		}
		sal_uInt16 nLen = aCmdLine.Len();

		// #55735 Wenn Parameter dabei sind, muessen die abgetrennt werden
		// #72471 Auch die einzelnen Parameter trennen
		std::list<String> aTokenList;
		String aToken;
		sal_uInt16 i = 0;
		sal_Unicode c;
		while( i < nLen )
		{
			// Spaces weg
            for ( ;; ++i )
            {
                c = aCmdLine.GetBuffer()[ i ];
                if ( c != ' ' && c != '\t' )
                    break;
            }

			if( c == '\"' || c == '\'' )
			{
				sal_uInt16 iFoundPos = aCmdLine.Search( c, i + 1 );

				// Wenn nichts gefunden wurde, Rest kopieren
				if( iFoundPos == STRING_NOTFOUND )
				{
					aToken = aCmdLine.Copy( i, STRING_LEN );
					i = nLen;
				}
				else
				{
					aToken = aCmdLine.Copy( i + 1, (iFoundPos - i - 1) );
					i = iFoundPos + 1;
				}
			}
			else
			{
				sal_uInt16 iFoundSpacePos = aCmdLine.Search( ' ', i );
				sal_uInt16 iFoundTabPos = aCmdLine.Search( '\t', i );
				sal_uInt16 iFoundPos = Min( iFoundSpacePos, iFoundTabPos );

				// Wenn nichts gefunden wurde, Rest kopieren
				if( iFoundPos == STRING_NOTFOUND )
				{
					aToken = aCmdLine.Copy( i, STRING_LEN );
					i = nLen;
				}
				else
				{
					aToken = aCmdLine.Copy( i, (iFoundPos - i) );
					i = iFoundPos;
				}
			}

			// In die Liste uebernehmen
			aTokenList.push_back( aToken );
		}
		// #55735 / #72471 Ende

		sal_Int16 nWinStyle = 0;
		if( nArgCount >= 3 )
		{
			nWinStyle = rPar.Get(2)->GetInteger();
			switch( nWinStyle )
			{
				case 2:
					nOptions |= vos::OProcess::TOption_Minimized;
					break;
				case 3:
					nOptions |= vos::OProcess::TOption_Maximized;
					break;
				case 10:
					nOptions |= vos::OProcess::TOption_FullScreen;
					break;
			}

			sal_Bool bSync = sal_False;
			if( nArgCount >= 5 )
				bSync = rPar.Get(4)->GetBool();
			if( bSync )
				nOptions |= vos::OProcess::TOption_Wait;
		}
		vos::OProcess::TProcessOption eOptions =
			(vos::OProcess::TProcessOption)nOptions;


		// #72471 Parameter aufbereiten
		std::list<String>::const_iterator iter = aTokenList.begin();
		const String& rStr = *iter;
		::rtl::OUString aOUStrProg( rStr.GetBuffer(), rStr.Len() );
		String aOUStrProgUNC = getFullPathUNC( aOUStrProg );

		iter++;

		sal_uInt16 nParamCount = sal::static_int_cast< sal_uInt16 >(
            aTokenList.size() - 1 );
		::rtl::OUString* pArgumentList = NULL;
		//const char** pParamList = NULL;
		if( nParamCount )
		{
			pArgumentList = new ::rtl::OUString[ nParamCount ];
			//pParamList = new const char*[ nParamCount ];
			sal_uInt16 iList = 0;
			while( iter != aTokenList.end() )
			{
				const String& rParamStr = (*iter);
				pArgumentList[iList++] = ::rtl::OUString( rParamStr.GetBuffer(), rParamStr.Len() );
				//pParamList[iList++] = (*iter).GetStr();
				iter++;
			}
		}

		//const char* pParams = aParams.Len() ? aParams.GetStr() : 0;
		vos::OProcess* pApp;
		pApp = new vos::OProcess( aOUStrProgUNC );
		sal_Bool bSucc;
		if( nParamCount == 0 )
		{
			bSucc = pApp->execute( eOptions ) == vos::OProcess::E_None;
		}
		else
		{
		    vos::OArgumentList aArgList( pArgumentList, nParamCount );
			bSucc = pApp->execute( eOptions, aArgList ) == vos::OProcess::E_None;
		}

		/*
		if( nParamCount == 0 )
			pApp = new vos::OProcess( pProg );
		else
			pApp = new vos::OProcess( pProg, pParamList, nParamCount );
		sal_Bool bSucc = pApp->execute( eOptions ) == vos::OProcess::E_None;
		*/

		delete pApp;
		delete[] pArgumentList;
		if( !bSucc )
			StarBASIC::Error( SbERR_FILE_NOT_FOUND );
		else
			rPar.Get(0)->PutLong( 0 );
	}
}

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

	if ( rPar.Count() != 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
		SbxDataType eType = rPar.Get(1)->GetType();
		rPar.Get(0)->PutInteger( (sal_Int16)eType );
	}
}

// Exported function
String getBasicTypeName( SbxDataType eType )
{
	static const char* pTypeNames[] =
	{
		"Empty",            // SbxEMPTY
		"Null",             // SbxNULL
		"Integer",          // SbxINTEGER
		"Long",             // SbxLONG
		"Single",           // SbxSINGLE
		"Double",           // SbxDOUBLE
		"Currency",         // SbxCURRENCY
		"Date",             // SbxDATE
		"String",           // SbxSTRING
		"Object",           // SbxOBJECT
		"Error",            // SbxERROR
		"Boolean",          // SbxBOOL
		"Variant",          // SbxVARIANT
		"DataObject",       // SbxDATAOBJECT
		"Unknown Type",     //
		"Unknown Type",     //
		"Char",             // SbxCHAR
		"Byte",             // SbxBYTE
		"UShort",           // SbxUSHORT
		"ULong",            // SbxULONG
		"Long64",           // SbxLONG64
		"ULong64",          // SbxULONG64
		"Int",              // SbxINT
		"UInt",             // SbxUINT
		"Void",             // SbxVOID
		"HResult",          // SbxHRESULT
		"Pointer",          // SbxPOINTER
		"DimArray",         // SbxDIMARRAY
		"CArray",           // SbxCARRAY
		"Userdef",          // SbxUSERDEF
		"Lpstr",            // SbxLPSTR
		"Lpwstr",           // SbxLPWSTR
		"Unknown Type",     // SbxCoreSTRING
		"WString",          // SbxWSTRING
		"WChar",            // SbxWCHAR
		"Int64",            // SbxSALINT64
		"UInt64",           // SbxSALUINT64
		"Decimal",          // SbxDECIMAL
	};

	int nPos = ((int)eType) & 0x0FFF;
	sal_uInt16 nTypeNameCount = sizeof( pTypeNames ) / sizeof( char* );
	if ( nPos < 0 || nPos >= nTypeNameCount )
		nPos = nTypeNameCount - 1;
	String aRetStr = String::CreateFromAscii( pTypeNames[nPos] );
	return aRetStr;
}

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

	if ( rPar.Count() != 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
		SbxDataType eType = rPar.Get(1)->GetType();
		sal_Bool bIsArray = ( ( eType & SbxARRAY ) != 0 );
		String aRetStr = getBasicTypeName( eType );
		if( bIsArray )
			aRetStr.AppendAscii( "()" );
		rPar.Get(0)->PutString( aRetStr );
	}
}

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

	if ( rPar.Count() != 2 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else
	{
		const String& rStr = rPar.Get(1)->GetString();
		rPar.Get(0)->PutLong( (sal_Int32)rStr.Len() );
	}
}

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

	// No DDE for "virtual" portal users
	if( needSecurityRestrictions() )
	{
		StarBASIC::Error(SbERR_NOT_IMPLEMENTED);
		return;
	}

	int nArgs = (int)rPar.Count();
	if ( nArgs != 3 )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}
	const String& rApp = rPar.Get(1)->GetString();
	const String& rTopic = rPar.Get(2)->GetString();

	SbiDdeControl* pDDE = pINST->GetDdeControl();
	sal_Int16 nChannel;
	SbError nDdeErr = pDDE->Initiate( rApp, rTopic, nChannel );
	if( nDdeErr )
		StarBASIC::Error( nDdeErr );
	else
		rPar.Get(0)->PutInteger( nChannel );
}

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

	// No DDE for "virtual" portal users
	if( needSecurityRestrictions() )
	{
		StarBASIC::Error(SbERR_NOT_IMPLEMENTED);
		return;
	}

	rPar.Get(0)->PutEmpty();
	int nArgs = (int)rPar.Count();
	if ( nArgs != 2 )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}
	sal_Int16 nChannel = rPar.Get(1)->GetInteger();
	SbiDdeControl* pDDE = pINST->GetDdeControl();
	SbError nDdeErr = pDDE->Terminate( nChannel );
	if( nDdeErr )
		StarBASIC::Error( nDdeErr );
}

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

	// No DDE for "virtual" portal users
	if( needSecurityRestrictions() )
	{
		StarBASIC::Error(SbERR_NOT_IMPLEMENTED);
		return;
	}

	rPar.Get(0)->PutEmpty();
	int nArgs = (int)rPar.Count();
	if ( nArgs != 1 )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}

	SbiDdeControl* pDDE = pINST->GetDdeControl();
	SbError nDdeErr = pDDE->TerminateAll();
	if( nDdeErr )
		StarBASIC::Error( nDdeErr );

}

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

	// No DDE for "virtual" portal users
	if( needSecurityRestrictions() )
	{
		StarBASIC::Error(SbERR_NOT_IMPLEMENTED);
		return;
	}

	int nArgs = (int)rPar.Count();
	if ( nArgs != 3 )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}
	sal_Int16 nChannel = rPar.Get(1)->GetInteger();
	const String& rItem = rPar.Get(2)->GetString();
	SbiDdeControl* pDDE = pINST->GetDdeControl();
	String aResult;
	SbError nDdeErr = pDDE->Request( nChannel, rItem, aResult );
	if( nDdeErr )
		StarBASIC::Error( nDdeErr );
	else
		rPar.Get(0)->PutString( aResult );
}

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

	// No DDE for "virtual" portal users
	if( needSecurityRestrictions() )
	{
		StarBASIC::Error(SbERR_NOT_IMPLEMENTED);
		return;
	}

	rPar.Get(0)->PutEmpty();
	int nArgs = (int)rPar.Count();
	if ( nArgs != 3 )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}
	sal_Int16 nChannel = rPar.Get(1)->GetInteger();
	const String& rCommand = rPar.Get(2)->GetString();
	SbiDdeControl* pDDE = pINST->GetDdeControl();
	SbError nDdeErr = pDDE->Execute( nChannel, rCommand );
	if( nDdeErr )
		StarBASIC::Error( nDdeErr );
}

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

	// No DDE for "virtual" portal users
	if( needSecurityRestrictions() )
	{
		StarBASIC::Error(SbERR_NOT_IMPLEMENTED);
		return;
	}

	rPar.Get(0)->PutEmpty();
	int nArgs = (int)rPar.Count();
	if ( nArgs != 4 )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}
	sal_Int16 nChannel = rPar.Get(1)->GetInteger();
	const String& rItem = rPar.Get(2)->GetString();
	const String& rData = rPar.Get(3)->GetString();
	SbiDdeControl* pDDE = pINST->GetDdeControl();
	SbError nDdeErr = pDDE->Poke( nChannel, rItem, rData );
	if( nDdeErr )
		StarBASIC::Error( nDdeErr );
}


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

	if ( rPar.Count() != 1 )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}
	SbiIoSystem* pIO = pINST->GetIoSystem();
	short nChannel = 1;
	while( nChannel < CHANNELS )
	{
		SbiStream* pStrm = pIO->GetStream( nChannel );
		if( !pStrm )
		{
			rPar.Get(0)->PutInteger( nChannel );
			return;
		}
		nChannel++;
	}
	StarBASIC::Error( SbERR_TOO_MANY_FILES );
}

RTLFUNC(LBound)
{
    (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 )
	{
		sal_Int32 nLower, nUpper;
		short nDim = (nParCount == 3) ? (short)rPar.Get(2)->GetInteger() : 1;
		if( !pArr->GetDim32( nDim, nLower, nUpper ) )
			StarBASIC::Error( SbERR_OUT_OF_RANGE );
		else
			rPar.Get(0)->PutLong( nLower );
	}
	else
		StarBASIC::Error( SbERR_MUST_HAVE_DIMS );
}

RTLFUNC(UBound)
{
    (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 )
	{
		sal_Int32 nLower, nUpper;
		short nDim = (nParCount == 3) ? (short)rPar.Get(2)->GetInteger() : 1;
		if( !pArr->GetDim32( nDim, nLower, nUpper ) )
			StarBASIC::Error( SbERR_OUT_OF_RANGE );
		else
			rPar.Get(0)->PutLong( nUpper );
	}
	else
		StarBASIC::Error( SbERR_MUST_HAVE_DIMS );
}

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

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

	sal_uIntPtr nRed	 = rPar.Get(1)->GetInteger() & 0xFF;
	sal_uIntPtr nGreen = rPar.Get(2)->GetInteger() & 0xFF;
	sal_uIntPtr nBlue  = rPar.Get(3)->GetInteger() & 0xFF;
	sal_uIntPtr nRGB;

	SbiInstance* pInst = pINST;
	bool bCompatibility = ( pInst && pInst->IsCompatibility() );
	if( bCompatibility )
	{
		nRGB   = (nBlue << 16) | (nGreen << 8) | nRed;
	}
	else
	{
		nRGB   = (nRed << 16) | (nGreen << 8) | nBlue;
	}
	rPar.Get(0)->PutLong( nRGB );
}

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

	static const sal_Int32 pRGB[] =
	{
		0x000000,
		0x800000,
		0x008000,
		0x808000,
		0x000080,
		0x800080,
		0x008080,
		0xC0C0C0,
		0x808080,
		0xFF0000,
		0x00FF00,
		0xFFFF00,
		0x0000FF,
		0xFF00FF,
		0x00FFFF,
		0xFFFFFF,
	};

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

	sal_Int16 nCol = rPar.Get(1)->GetInteger();
	if( nCol < 0 || nCol > 15 )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}
	sal_Int32 nRGB = pRGB[ nCol ];
	rPar.Get(0)->PutLong( nRGB );
}

// StrConv(string, conversion, LCID)
RTLFUNC(StrConv)
{
    (void)pBasic;
    (void)bWrite;

	sal_uIntPtr nArgCount = rPar.Count()-1;
	if( nArgCount < 2 || nArgCount > 3 )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}

	String aOldStr = rPar.Get(1)->GetString();
	sal_Int32 nConversion = rPar.Get(2)->GetLong();

	sal_uInt16 nLanguage = LANGUAGE_SYSTEM;
	if( nArgCount == 3 )
	{
		// LCID not supported now
		//nLanguage = rPar.Get(3)->GetInteger();
	}

	sal_uInt16 nOldLen = aOldStr.Len();
	if( nOldLen == 0 )
	{
		// null string,return
		rPar.Get(0)->PutString(aOldStr);
		return;
	}

	sal_Int32 nType = 0;
	if ( (nConversion & 0x03) == 3 ) //  vbProperCase
	{
		CharClass& rCharClass = GetCharClass();
		aOldStr = rCharClass.toTitle( aOldStr.ToLowerAscii(), 0, nOldLen );
	}
	else if ( (nConversion & 0x01) == 1 ) // vbUpperCase
		nType |= ::com::sun::star::i18n::TransliterationModules_LOWERCASE_UPPERCASE;
	else if ( (nConversion & 0x02) == 2 ) // vbLowerCase
		nType |= ::com::sun::star::i18n::TransliterationModules_UPPERCASE_LOWERCASE;

	if ( (nConversion & 0x04) == 4 ) // vbWide
		nType |= ::com::sun::star::i18n::TransliterationModules_HALFWIDTH_FULLWIDTH;
	else if ( (nConversion & 0x08) == 8 ) // vbNarrow
		nType |= ::com::sun::star::i18n::TransliterationModules_FULLWIDTH_HALFWIDTH;

	if ( (nConversion & 0x10) == 16) // vbKatakana
		nType |= ::com::sun::star::i18n::TransliterationModules_HIRAGANA_KATAKANA;
	else if ( (nConversion & 0x20) == 32 ) // vbHiragana
		nType |= ::com::sun::star::i18n::TransliterationModules_KATAKANA_HIRAGANA;

	String aNewStr( aOldStr );
	if( nType != 0 )
	{
		com::sun::star::uno::Reference< XMultiServiceFactory > xSMgr = getProcessServiceFactory();
    	::utl::TransliterationWrapper aTransliterationWrapper( xSMgr,nType );
		com::sun::star::uno::Sequence<sal_Int32> aOffsets;
		aTransliterationWrapper.loadModuleIfNeeded( nLanguage );
		aNewStr = aTransliterationWrapper.transliterate( aOldStr, nLanguage, 0, nOldLen, &aOffsets );
	}

	if ( (nConversion & 0x40) == 64 ) // vbUnicode
	{
		// convert the string to byte string, preserving unicode (2 bytes per character)
		sal_uInt16 nSize = aNewStr.Len()*2;
		const sal_Unicode* pSrc = aNewStr.GetBuffer();
		sal_Char* pChar = new sal_Char[nSize+1];
		for( sal_uInt16 i=0; i < nSize; i++ )
		{
			pChar[i] = static_cast< sal_Char >( i%2 ? ((*pSrc) >> 8) & 0xff : (*pSrc) & 0xff );
			if( i%2 )
				pSrc++;
		}
		pChar[nSize] = '\0';
		::rtl::OString aOStr(pChar);

		// there is no concept about default codepage in unix. so it is incorrectly in unix
		::rtl::OUString aOUStr = ::rtl::OStringToOUString(aOStr, osl_getThreadTextEncoding());
		aNewStr = String(aOUStr);
		rPar.Get(0)->PutString( aNewStr );
		return;
	}
	else if ( (nConversion & 0x80) == 128 ) // vbFromUnicode
	{
		::rtl::OUString aOUStr(aNewStr);
		// there is no concept about default codepage in unix. so it is incorrectly in unix
		::rtl::OString aOStr = ::rtl::OUStringToOString(aNewStr,osl_getThreadTextEncoding());
		const sal_Char* pChar = aOStr.getStr();
		sal_uInt16 nArraySize = static_cast< sal_uInt16 >( aOStr.getLength() );
		SbxDimArray* pArray = new SbxDimArray(SbxBYTE);
		bool bIncIndex = (IsBaseIndexOne() && SbiRuntime::isVBAEnabled() );
		if(nArraySize)
		{
			if( bIncIndex )
				pArray->AddDim( 1, nArraySize );
			else
				pArray->AddDim( 0, nArraySize-1 );
		}
		else
		{
			pArray->unoAddDim( 0, -1 );
		}

		for( sal_uInt16	i=0; i< nArraySize; i++)
		{
			SbxVariable* pNew = new SbxVariable( SbxBYTE );
			pNew->PutByte(*pChar);
			pChar++;
			pNew->SetFlag( SBX_WRITE );
			short index = i;
			if( bIncIndex )
				++index;
			pArray->Put( pNew, &index );
		}

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

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


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

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

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

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

	// Diesen Call einfach an das Object weiterreichen
	SbxBase* pObj = (SbxObject*)rPar.Get(1)->GetObject();
	if ( pObj )
	{
		if( pObj->IsA( TYPE( SbUserFormModule ) ) )
		{
			((SbUserFormModule*)pObj)->Load();
		}
		else if( pObj->IsA( TYPE( SbxObject ) ) )
		{
			SbxVariable* pVar = ((SbxObject*)pObj)->
				Find( String( RTL_CONSTASCII_USTRINGPARAM("Load") ), SbxCLASS_METHOD );
			if( pVar )
				pVar->GetInteger();
		}
	}
}

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

	rPar.Get(0)->PutEmpty();
	if( rPar.Count() != 2 )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}

	// Diesen Call einfach an das Object weitereichen
	SbxBase* pObj = (SbxObject*)rPar.Get(1)->GetObject();
	if ( pObj )
	{
		if( pObj->IsA( TYPE( SbUserFormModule ) ) )
		{
			SbUserFormModule* pFormModule = ( SbUserFormModule* )pObj;
			pFormModule->Unload();
		}
		else if( pObj->IsA( TYPE( SbxObject ) ) )
		{
			SbxVariable* pVar = ((SbxObject*)pObj)->
				Find( String( RTL_CONSTASCII_USTRINGPARAM("Unload") ), SbxCLASS_METHOD );
			if( pVar )
				pVar->GetInteger();
		}
	}
}

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

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

	String aFileURL = getFullPath( rPar.Get(1)->GetString() );
	SvStream* pStream = utl::UcbStreamHelper::CreateStream( aFileURL, STREAM_READ );
	if( pStream != NULL )
	{
		Bitmap aBmp;
        ReadDIB(aBmp, *pStream, true);
		Graphic aGraphic(aBmp);

		SbxObjectRef xRef = new SbStdPicture;
		((SbStdPicture*)(SbxObject*)xRef)->SetGraphic( aGraphic );
		rPar.Get(0)->PutObject( xRef );
	}
	delete pStream;
}

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

	rPar.Get(0)->PutEmpty();
	if( rPar.Count() != 3 )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}

	SbxBase* pObj = (SbxObject*)rPar.Get(1)->GetObject();
	if( pObj->IsA( TYPE( SbStdPicture ) ) )
	{
		SvFileStream aOStream( rPar.Get(2)->GetString(), STREAM_WRITE | STREAM_TRUNC );
		Graphic aGraphic = ((SbStdPicture*)pObj)->GetGraphic();
		aOStream << aGraphic;
	}
}


//-----------------------------------------------------------------------------------------

RTLFUNC(AboutStarBasic)
{
    (void)pBasic;
    (void)bWrite;
    (void)rPar;
}

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

	static const WinBits nStyleMap[] =
	{
		WB_OK,				// MB_OK
		WB_OK_CANCEL,       // MB_OKCANCEL
		WB_ABORT_RETRY_IGNORE,    // MB_ABORTRETRYIGNORE
		WB_YES_NO_CANCEL,   // MB_YESNOCANCEL
		WB_YES_NO,          // MB_YESNO
		WB_RETRY_CANCEL     // MB_RETRYCANCEL
	};
	static const sal_Int16 nButtonMap[] =
	{
		2, // #define RET_CANCEL sal_False
		1, // #define RET_OK     sal_True
		6, // #define RET_YES    2
		7, // #define RET_NO     3
		4  // #define RET_RETRY  4
	};


	sal_uInt16 nArgCount = (sal_uInt16)rPar.Count();
	if( nArgCount < 2 || nArgCount > 6 )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}
	WinBits nWinBits;
	WinBits nType = 0; // MB_OK
	if( nArgCount >= 3 )
		nType = (WinBits)rPar.Get(2)->GetInteger();
	WinBits nStyle = nType;
	nStyle &= 15; // Bits 4-16 loeschen
	if( nStyle > 5 )
		nStyle = 0;

	nWinBits = nStyleMap[ nStyle ];

	WinBits nWinDefBits;
	nWinDefBits = (WB_DEF_OK | WB_DEF_RETRY | WB_DEF_YES);
	if( nType & 256 )
	{
		if( nStyle == 5 )
			nWinDefBits = WB_DEF_CANCEL;
		else if( nStyle == 2 )
			nWinDefBits = WB_DEF_RETRY;
		else
			nWinDefBits = (WB_DEF_CANCEL | WB_DEF_RETRY | WB_DEF_NO);
	}
	else if( nType & 512 )
	{
		if( nStyle == 2)
			nWinDefBits = WB_DEF_IGNORE;
		else
			nWinDefBits = WB_DEF_CANCEL;
	}
	else if( nStyle == 2)
		nWinDefBits = WB_DEF_CANCEL;
    nWinBits |= nWinDefBits;

	String aMsg = rPar.Get(1)->GetString();
	String aTitle;
	if( nArgCount >= 4 )
		aTitle = rPar.Get(3)->GetString();
	else
		aTitle = GetpApp()->GetDisplayName();

	nType &= (16+32+64);
	MessBox* pBox = 0;
	Window* pParent = GetpApp()->GetDefDialogParent();
	switch( nType )
	{
		case 16:
			pBox = new ErrorBox( pParent, nWinBits, aMsg );
			break;
		case 32:
			pBox = new QueryBox( pParent, nWinBits, aMsg );
			break;
		case 48:
			pBox = new WarningBox( pParent, nWinBits, aMsg );
			break;
		case 64:
			pBox = new InfoBox( pParent, nWinBits, aMsg );
			break;
		default:
			pBox = new MessBox( pParent, nWinBits, aTitle, aMsg );
	}
	pBox->SetText( aTitle );
	sal_uInt16 nRet = (sal_uInt16)pBox->Execute();
	if( nRet == sal_True )
		nRet = 1;

	sal_Int16 nMappedRet;
	if( nStyle == 2 )
	{
		nMappedRet = nRet;
		if( nMappedRet == 0 )
			nMappedRet = 3;	// Abort
	}
	else
		nMappedRet = nButtonMap[ nRet ];

	rPar.Get(0)->PutInteger( nMappedRet );
	delete pBox;
}

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

	rPar.Get(0)->PutEmpty();
	if ( rPar.Count() == 3 )
	{
		String aStr = rPar.Get(1)->GetString();
		sal_Int16 nFlags = rPar.Get(2)->GetInteger();

		// <-- UCB
		if( hasUno() )
		{
			com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess();
			if( xSFI.is() )
			{
				try
				{
					sal_Bool bReadOnly = (nFlags & 0x0001) != 0; // ATTR_READONLY
					xSFI->setReadOnly( aStr, bReadOnly );
					sal_Bool bHidden   = (nFlags & 0x0002) != 0; // ATTR_HIDDEN
					xSFI->setHidden( aStr, bHidden );
				}
				catch( Exception & )
				{
					StarBASIC::Error( ERRCODE_IO_GENERAL );
				}
			}
		}
		else
		// --> UCB
		{
#ifdef _OLD_FILE_IMPL
			// #57064 Bei virtuellen URLs den Real-Path extrahieren
			DirEntry aEntry( aStr );
			String aFile = aEntry.GetFull();
			ByteString aByteFile( aFile, gsl_getSystemTextEncoding() );
	#ifdef WNT
			if (!SetFileAttributes (aByteFile.GetBuffer(),(DWORD)nFlags))
				StarBASIC::Error(SbERR_FILE_NOT_FOUND);
	#endif
	#ifdef OS2
			FILESTATUS3 aFileStatus;
			APIRET rc = DosQueryPathInfo(aByteFile.GetBuffer(),1,
										 &aFileStatus,sizeof(FILESTATUS3));
			if (!rc)
			{
				if (aFileStatus.attrFile != nFlags)
				{
					aFileStatus.attrFile = nFlags;
					rc = DosSetPathInfo(aFile.GetStr(),1,
										&aFileStatus,sizeof(FILESTATUS3),0);
					if (rc)
						StarBASIC::Error( SbERR_FILE_NOT_FOUND );
				}
			}
			else
				StarBASIC::Error( SbERR_FILE_NOT_FOUND );
	#endif
#else
			// Not implemented
#endif
		}
	}
	else
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
}

RTLFUNC(Reset)  // JSM
{
    (void)pBasic;
    (void)bWrite;
    (void)rPar;

	SbiIoSystem* pIO = pINST->GetIoSystem();
	if (pIO)
		pIO->CloseAll();
}

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

	sal_uInt16 nArgCount = (sal_uInt16)rPar.Count();
	if( nArgCount < 2 || nArgCount > 3 )
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
	else if( !pBasic )
		StarBASIC::Error( SbERR_INTERNAL_ERROR );
	else
	{
		SbxObject* p = pBasic;
		while( p->GetParent() )
			p = p->GetParent();
		SvFileStream aStrm( rPar.Get( 1 )->GetString(),
							STREAM_WRITE | STREAM_TRUNC );
		p->Dump( aStrm, rPar.Get( 2 )->GetBool() );
		aStrm.Close();
		if( aStrm.GetError() != SVSTREAM_OK )
			StarBASIC::Error( SbERR_IO_ERROR );
	}
}


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

	if ( rPar.Count() == 2 )
	{
		String aStr = rPar.Get(1)->GetString();
		sal_Bool bExists = sal_False;

		// <-- UCB
		if( hasUno() )
		{
			com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess();
			if( xSFI.is() )
			{
				try
				{
					bExists = xSFI->exists( aStr );
				}
				catch( Exception & )
				{
					StarBASIC::Error( ERRCODE_IO_GENERAL );
				}
			}
		}
		else
		// --> UCB
		{
#ifdef _OLD_FILE_IMPL
			DirEntry aEntry( aStr );
			bExists = aEntry.Exists();
#else
			DirectoryItem aItem;
			FileBase::RC nRet = DirectoryItem::get( getFullPathUNC( aStr ), aItem );
			bExists = (nRet == FileBase::E_None);
#endif
		}
		rPar.Get(0)->PutBool( bExists );
	}
	else
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
}

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

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

	sal_Int32 nNumber = rPar.Get(1)->GetLong();
	sal_Int32 nStart = rPar.Get(2)->GetLong();
	sal_Int32 nStop = rPar.Get(3)->GetLong();
	sal_Int32 nInterval = rPar.Get(4)->GetLong();

	if( nStart < 0 || nStop <= nStart || nInterval < 1 )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}

	// the Partition function inserts leading spaces before lowervalue and uppervalue
    // so that they both have the same number of characters as the string
    // representation of the value (Stop + 1). This ensures that if you use the output
    // of the Partition function with several values of Number, the resulting text
	// will be handled properly during any subsequent sort operation.

	// calculate the  maximun number of characters before lowervalue and uppervalue
	::rtl::OUString aBeforeStart = ::rtl::OUString::valueOf( nStart - 1 );
	::rtl::OUString aAfterStop = ::rtl::OUString::valueOf( nStop + 1 );
	sal_Int32 nLen1 = aBeforeStart.getLength();
	sal_Int32 nLen2 = aAfterStop.getLength();
	sal_Int32 nLen = nLen1 >= nLen2 ? nLen1:nLen2;

	::rtl::OUStringBuffer aRetStr( nLen * 2 + 1);
	::rtl::OUString aLowerValue;
	::rtl::OUString aUpperValue;
	if( nNumber < nStart )
	{
		aUpperValue = aBeforeStart;
	}
	else if( nNumber > nStop )
	{
		aLowerValue = aAfterStop;
	}
	else
	{
		sal_Int32 nLowerValue = nNumber;
		sal_Int32 nUpperValue = nLowerValue;
		if( nInterval > 1 )
		{
			nLowerValue = ((( nNumber - nStart ) / nInterval ) * nInterval ) + nStart;
			nUpperValue = nLowerValue + nInterval - 1;
		}

		aLowerValue = ::rtl::OUString::valueOf( nLowerValue );
		aUpperValue = ::rtl::OUString::valueOf( nUpperValue );
	}

	nLen1 = aLowerValue.getLength();
	nLen2 = aUpperValue.getLength();

	if( nLen > nLen1 )
	{
		// appending the leading spaces for the lowervalue
		for ( sal_Int32 i= (nLen - nLen1) ; i > 0; --i )
			aRetStr.appendAscii(" ");
	}
	aRetStr.append( aLowerValue ).appendAscii(":");
	if( nLen > nLen2 )
	{
		// appending the leading spaces for the uppervalue
		for ( sal_Int32 i= (nLen - nLen2) ; i > 0; --i )
			aRetStr.appendAscii(" ");
	}
	aRetStr.append( aUpperValue );
	rPar.Get(0)->PutString( String(aRetStr.makeStringAndClear()) );
}
