/**************************************************************
 * 
 * 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.getLength() )
	{
		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().getLength() )
				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 - nFindStrLen + nReplaceStrLen + 1;
					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(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
	Date aRefDate( 1, 1, 1900 );
	if ( aDate >= 0.0 )
	{
		aDate = floor( aDate );
		aRefDate += (sal_uIntPtr)aDate;
	}
	else
	{
		aDate = ceil( aDate );
		aRefDate -= (sal_uIntPtr)(-1.0 * 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;
		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;
		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 )
{
	if( dDate < 0.0 )
		dDate *= -1.0;
	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 )
{
	if( dDate < 0.0 )
		dDate *= -1.0;
	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 )
{
	if( dDate < 0.0 )
		dDate *= -1.0;
	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()->GetAppName();

	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, 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()) );
}
