/**************************************************************
 *
 * 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 <vcl/svapp.hxx>
#include <vcl/wrkwin.hxx>
#include <vcl/toolbox.hxx>
#include <vcl/msgbox.hxx>
#include <vcl/sound.hxx>
#include <basic/basmgr.hxx>
#include <basic/sbx.hxx>
#include <basic/sbmod.hxx>
#include <basic/basrdll.hxx>

//#include <sv.hxx>
//#include <basic.hxx>
//#include <sostor.hxx>

// Defines for ToolBox-Id's
#define TB_NEW				1
#define TB_OPENSTORAGE		2
#define TB_SAVESTORAGE		3
#define TB_ORG				4
#define TB_CREATELIB1		10
#define TB_CREATELIB2		11
#define TB_CREATELIB3		12
#define TB_LOADLIB1			20
#define TB_LOADLIB2			21
#define TB_LOADLIB3			22
#define TB_STORELIBX		30
#define TB_UNLOADX			31
#define TB_LOADX			32
#define TB_EXECX			33
#define TB_REMOVEX			34
#define TB_REMOVEDELX		35

#define TB_LIB0				40
#define TB_LIB1				41
#define TB_LIB2				42
#define TB_LIB3				43

const char* pLib1Str = "Lib1";
const char* pLib2Str = "Lib2";
const char* pLib3Str = "Lib3";

// Test-Application
class TestApp : public Application
{
public:
	virtual void Main( void );
	virtual void Main( int, char*[] );
};

// Test-Window with a ToolBox to choose a test from
// and the typically used virtual methods
class TestWindow : public WorkWindow
{
private:
	ToolBox 		aToolBox;
	BasicManager*	pBasMgr;

	void			CheckError();
	sal_uInt16			nLibX;
	DECL_LINK( BasicErrorHdl, StarBASIC * );


public:
					TestWindow();
					~TestWindow();

	virtual void	Paint( const Rectangle& );
	virtual void	Resize();
	virtual void	KeyInput( const KeyEvent& rKeyEvt );
	virtual void	MouseMove( const MouseEvent& rMEvt );
	virtual void	MouseButtonDown( const MouseEvent& rMEvt );
	virtual void	MouseButtonUp( const MouseEvent& rMEvt );

	DECL_LINK( TBSelect, ToolBox * );
	void			UpdateToolBox();
	void			ShowInfo();
};

TestWindow::~TestWindow()
{
}

TestWindow::TestWindow() :
	WorkWindow( NULL, WB_APP | WB_STDWORK | WB_3DLOOK | WB_CLIPCHILDREN ) ,
	aToolBox( this, WinBits( WB_BORDER | WB_3DLOOK | WB_SCROLL | WB_LINESPACING ) )
{
	nLibX = 0;

	aToolBox.SetButtonType( BUTTON_TEXT );
	aToolBox.SetLineCount( 2 );
	aToolBox.SetPosPixel( Point( 0, 0 ) );
	aToolBox.SetSelectHdl( LINK( this, TestWindow, TBSelect ) );

	Font aFont;
	aFont.SetName( "Helv" );
	aFont.SetSize( Size( 0, 6 ) );
	aFont.SetPitch( PITCH_VARIABLE );
	aFont.SetFamily( FAMILY_SWISS );
	aFont.SetTransparent( sal_True );
	aFont.SetAlign( ALIGN_TOP );
	aToolBox.SetFont( aFont );
	SetFont( aFont );

	aToolBox.InsertItem( TB_NEW, "New" );
	aToolBox.SetHelpText( TB_NEW, "New BasicManager" );
	aToolBox.InsertItem( TB_OPENSTORAGE, "Load" );
	aToolBox.SetHelpText( TB_OPENSTORAGE, "Load Storage D:\\MYSTORE.SVS" );
	aToolBox.InsertItem( TB_SAVESTORAGE, "Save" );
	aToolBox.SetHelpText( TB_SAVESTORAGE, "Save Storage D:\\MYSTORE.SVS" );

	aToolBox.InsertSeparator();

	aToolBox.InsertItem( TB_ORG, "Verwalten" );
	aToolBox.SetHelpText( TB_ORG, "Libaries verwalten" );

	aToolBox.InsertSeparator();

	aToolBox.InsertItem( TB_LIB0, "0" );
	aToolBox.SetHelpText( TB_LIB0, "Aktuelle Lib: STANDARD" );
	aToolBox.InsertItem( TB_LIB1, "1" );
	aToolBox.SetHelpText( TB_LIB1, "Aktuelle Lib: 1" );
	aToolBox.InsertItem( TB_LIB2, "2" );
	aToolBox.SetHelpText( TB_LIB2, "Aktuelle Lib: 2" );
	aToolBox.InsertItem( TB_LIB3, "3" );
	aToolBox.SetHelpText( TB_LIB3, "Aktuelle Lib: 3" );

	aToolBox.InsertBreak();
	aToolBox.InsertItem( TB_CREATELIB1, "CreateLib1" );
	aToolBox.SetHelpText( TB_CREATELIB1, "Create Library LIB1" );
	aToolBox.InsertItem( TB_CREATELIB2, "CreateLib2" );
	aToolBox.SetHelpText( TB_CREATELIB2, "Create Library LIB2" );
	aToolBox.InsertItem( TB_CREATELIB3, "CreateLib3" );
	aToolBox.SetHelpText( TB_CREATELIB3, "Create Library LIB3" );

	aToolBox.InsertSeparator();
	aToolBox.InsertItem( TB_LOADLIB1, "LoadLib1" );
	aToolBox.SetHelpText( TB_LOADLIB1, "Load Library LIB1" );
	aToolBox.InsertItem( TB_LOADLIB2, "LoadLib2" );
	aToolBox.SetHelpText( TB_LOADLIB2, "Load Library LIB2" );
	aToolBox.InsertItem( TB_LOADLIB3, "LoadLib3" );
	aToolBox.SetHelpText( TB_LOADLIB3, "Load Library LIB3" );

	aToolBox.InsertSeparator();
	aToolBox.InsertItem( TB_STORELIBX, "StoreLibX" );
	aToolBox.SetHelpText( TB_STORELIBX, "Store Library LIBX" );
	aToolBox.InsertItem( TB_UNLOADX, "UnloadX" );
	aToolBox.SetHelpText( TB_UNLOADX, "Unload Library LIBX" );
	aToolBox.InsertItem( TB_LOADX, "LoadX" );
	aToolBox.SetHelpText( TB_LOADX, "Load Library LIBX" );
	aToolBox.InsertItem( TB_EXECX, "ExecX" );
	aToolBox.SetHelpText( TB_EXECX, "Execute 'Libary' LIBX" );
	aToolBox.InsertItem( TB_REMOVEX, "RemoveX" );
	aToolBox.SetHelpText( TB_REMOVEX, "Remove Library LIBX" );
	aToolBox.InsertItem( TB_REMOVEDELX, "RemDelX" );
	aToolBox.SetHelpText( TB_REMOVEDELX, "Remove and delete Library LIBX" );

	pBasMgr = 0;

	Show();
	UpdateToolBox();
	aToolBox.Show();
}
void TestWindow::ShowInfo()
{
	Invalidate();
	Update();
	long nH = GetTextSize( "X" ).Height();
	if ( pBasMgr )
	{
		Point aPos( 10, aToolBox.GetSizePixel().Height()+5 );
		for ( sal_uInt16 nLib = 0; nLib < pBasMgr->GetLibCount(); nLib++ )
		{
			String aOutStr( nLib );
			aOutStr +=": ";
			StarBASIC* pL = pBasMgr->GetLib( nLib );
			aOutStr += '[';
			aOutStr += pBasMgr->GetLibName( nLib );
			aOutStr += "]<";
			if ( pL )
				aOutStr += pL->GetName();
			else
				aOutStr += "NoLoaded";
			aOutStr += ">, Storage='";
			aOutStr += pBasMgr->GetLibStorageName( nLib );
			aOutStr += "', bLoaded=";
			aOutStr += (sal_uInt16)pBasMgr->IsLibLoaded( nLib );
			DrawText( aPos, aOutStr );
			aPos.Y() += nH;
		}
	}
}

void TestWindow::UpdateToolBox()
{
    // View of some buttons as checked or disabled if
    // wished by tests
    aToolBox.EnableItem( TB_ORG, (sal_Bool)(sal_uIntPtr)pBasMgr );

    aToolBox.EnableItem( TB_CREATELIB1, (sal_Bool)(sal_uIntPtr)pBasMgr );
    aToolBox.EnableItem( TB_CREATELIB2, (sal_Bool)(sal_uIntPtr)pBasMgr );
    aToolBox.EnableItem( TB_CREATELIB3, (sal_Bool)(sal_uIntPtr)pBasMgr );

    aToolBox.EnableItem( TB_LOADLIB1, (sal_Bool)(sal_uIntPtr)pBasMgr );
    aToolBox.EnableItem( TB_LOADLIB2, (sal_Bool)(sal_uIntPtr)pBasMgr );
    aToolBox.EnableItem( TB_LOADLIB3, (sal_Bool)(sal_uIntPtr)pBasMgr );

    aToolBox.EnableItem( TB_STORELIBX, (sal_Bool)(sal_uIntPtr)pBasMgr );
    aToolBox.EnableItem( TB_EXECX, (sal_Bool)(sal_uIntPtr)pBasMgr );
    aToolBox.EnableItem( TB_UNLOADX, (sal_Bool)(sal_uIntPtr)pBasMgr );
    aToolBox.EnableItem( TB_LOADX, (sal_Bool)(sal_uIntPtr)pBasMgr );
    aToolBox.EnableItem( TB_REMOVEX, (sal_Bool)(sal_uIntPtr)pBasMgr );
    aToolBox.EnableItem( TB_REMOVEDELX, (sal_Bool)(sal_uIntPtr)pBasMgr );

    aToolBox.CheckItem( TB_LIB0, nLibX == 0 );
    aToolBox.CheckItem( TB_LIB1, nLibX == 1 );
    aToolBox.CheckItem( TB_LIB2, nLibX == 2 );
    aToolBox.CheckItem( TB_LIB3, nLibX == 3 );
}

IMPL_LINK( TestWindow, TBSelect, ToolBox *, p )
{
	sal_uInt16 nId = aToolBox.GetCurItemId();
	sal_Bool bChecked = aToolBox.IsItemChecked( nId );
	switch ( nId )
	{
		case TB_NEW:
		{
			delete pBasMgr;
			pBasMgr = new BasicManager( new StarBASIC );
			pBasMgr->SetStorageName( "d:\\mystore.svs" );
		}
		break;
		case TB_OPENSTORAGE:
		{
			delete pBasMgr;
			SvStorageRef xStorage = new SvStorage( "d:\\mystore.svs", STREAM_READ | STREAM_SHARE_DENYWRITE );
			DBG_ASSERT( xStorage.Is(), "Kein Storage!" );
			pBasMgr = new BasicManager( *xStorage );
		}
		break;
		case TB_SAVESTORAGE:
		{
			if ( pBasMgr)
			{
				SvStorageRef xStorage = new SvStorage( "d:\\mystore.svs" );
				DBG_ASSERT( xStorage.Is(), "Kein Storage!" );
				pBasMgr->Store( *xStorage );
			}
		}
		break;
		case TB_ORG:
		{
			if ( pBasMgr)
			{
				InfoBox( 0, "Organisieren..." ).Execute();
			}
		}
		break;
		case TB_CREATELIB1:
		{
			if ( pBasMgr )
			{
				sal_uInt16 nLib = pBasMgr->GetLibId( pBasMgr->CreateLib( pLib1Str ) );
				if ( nLib != LIB_NOTFOUND )
				{
					pBasMgr->SetLibStorageName( nLib, "d:\\mystore.svs" );
					StarBASIC* pLib = pBasMgr->GetLib( pLib1Str );
					DBG_ASSERT( pLib, "Lib?!" );
					String aSource( "Sub SubInLib1Mod1\nprint\"XXX\"\nEnd Sub");
					SbModule* pM = pLib->MakeModule( "ModLib1", aSource  );
					DBG_ASSERT( pM, "Modul?" );
					pLib->Compile( pM );
				}
				else
					InfoBox( 0, "CreateLibary fehlgeschlagen..." ).Execute();
			}
		}
		break;
		case TB_CREATELIB2:
		{
			if ( pBasMgr )
			{
				sal_uInt16 nLib = pBasMgr->GetLibId( pBasMgr->CreateLib( pLib2Str ) );
				if ( nLib != LIB_NOTFOUND )
				{
					pBasMgr->SetLibStorageName( nLib, "d:\\mystore.svs" );
					StarBASIC* pLib = pBasMgr->GetLib( pLib2Str );
					DBG_ASSERT( pLib, "Lib?!" );
					SbModule* pM = pLib->MakeModule( "ModuleLib2", "Sub SubInLib2\n print \"Tralala\" \nEnd Sub\n" );
					pLib->Compile( pM );
				}
				else
					InfoBox( 0, "CreateLibary fehlgeschlagen..." ).Execute();
			}
		}
		break;
		case TB_CREATELIB3:
		{
			if ( pBasMgr )
			{
				// liegt in einem anderen Storage !!!
				sal_uInt16 nLib = pBasMgr->GetLibId( pBasMgr->CreateLib( pLib3Str ) );
				if ( nLib != LIB_NOTFOUND )
				{
					pBasMgr->SetLibStorageName( nLib, "d:\\mystore2.svs" );
					StarBASIC* pLib = pBasMgr->GetLib( pLib3Str );
					DBG_ASSERT( pLib, "Lib?!" );
					SbModule* pM = pLib->MakeModule( "ModuleLib2", "Sub XYZInLib3\n print \"?!\" \nEnd Sub\n" );
					pLib->Compile( pM );
				}
				else
					InfoBox( 0, "CreateLibary fehlgeschlagen..." ).Execute();
			}
		}
		break;
		case TB_LOADLIB1:
		{
			if ( pBasMgr )
			{
				SvStorageRef xStorage = new SvStorage( "d:\\mystore.svs" );
				if ( !pBasMgr->AddLib( *xStorage, pLib1Str, sal_False ) )
					Sound::Beep();
			}
		}
		break;
		case TB_LOADLIB2:
		{
			if ( pBasMgr )
			{
				SvStorageRef xStorage = new SvStorage( "d:\\mystore.svs" );
				if ( !pBasMgr->AddLib( *xStorage, pLib2Str, sal_False ) )
					Sound::Beep();
			}
		}
		break;
		case TB_LOADLIB3:
		{
			if ( pBasMgr )
			{
				// liegt in einem anderen Storage !!!
				SvStorageRef xStorage = new SvStorage( "d:\\mystore2.svs" );
				if ( !pBasMgr->AddLib( *xStorage, pLib3Str, sal_False ) )
					Sound::Beep();
			}
		}
		break;
		case TB_STORELIBX:
		{
			if ( pBasMgr )
				pBasMgr->StoreLib( nLibX );
		}
		break;
		case TB_UNLOADX:
		{
			if ( pBasMgr )
				pBasMgr->UnloadLib( nLibX );
		}
		break;
		case TB_LOADX:
		{
			if ( pBasMgr )
				pBasMgr->LoadLib( nLibX );
		}
		break;
		case TB_REMOVEX:
		{
			if ( pBasMgr )
				pBasMgr->RemoveLib( nLibX, sal_False );
		}
		break;
		case TB_REMOVEDELX:
		{
			if ( pBasMgr )
				pBasMgr->RemoveLib( nLibX, sal_True );
		}
		break;
		case TB_EXECX:
		{
			if ( pBasMgr )
			{
				StarBASIC* pBasic = pBasMgr->GetLib( nLibX );
				if ( pBasic && pBasic->GetModules()->Count() )
				{
					pBasic->SetErrorHdl( LINK( this, TestWindow, BasicErrorHdl ) );

					SbModule* pMod = (SbModule*)pBasic->GetModules()->Get( 0 );
					if ( pMod && pMod->GetMethods()->Count() )
						pMod->GetMethods()->Get(0)->GetInteger();
				}
			}
		}
		break;

		case TB_LIB0:	nLibX = 0;
		break;
		case TB_LIB1:	nLibX = 1;
		break;
		case TB_LIB2:	nLibX = 2;
		break;
		case TB_LIB3:	nLibX = 3;
		break;
	}

	UpdateToolBox();
	CheckError();
	ShowInfo();
	return 0;
}

void TestWindow::CheckError()
{
	 if ( pBasMgr )
	 {
		BasicError* pError = pBasMgr->GetFirstError();
		while ( pError )
		{
			String aErrorStr;
			String aReasonStr;
			switch ( pError->GetErrorId() )
			{
				case BASERR_ID_STDLIBOPEN:
					aErrorStr = "Standard-Lib konnte nicht geoffnet werden.";
				break;
				case BASERR_ID_STDLIBSAVE:
					aErrorStr = "Standard-Lib konnte nicht gespeichert werden.";
				break;
				case BASERR_ID_LIBLOAD:
					aErrorStr = "Lib konnte nicht geoffnet werden.";
				break;
				case BASERR_ID_LIBCREATE:
					aErrorStr = "Lib konnte nicht erzeugt werden.";
				break;
				case BASERR_ID_LIBSAVE:
					aErrorStr = "Lib konnte nicht gespeichert werden.";
				break;
				case BASERR_ID_MGROPEN:
					aErrorStr = "Manager konnte nicht geladen werden.";
				break;
				case BASERR_ID_MGRSAVE:
					aErrorStr = "Manager konnte nicht gespeichert werden.";
				break;
				case BASERR_ID_UNLOADLIB:
					aErrorStr = "Libary konnte nicht entladen werden.";
				break;
				case BASERR_ID_REMOVELIB:
					aErrorStr = "Libary konnte nicht entfernt werden.";
				break;
				default:
					aErrorStr = "Unbekannter Fehler!";
			}

			switch ( pError->GetReason() )
			{
				case BASERR_REASON_OPENSTORAGE:
					aReasonStr = "Der Storage konnte nicht geoeffnet werden";
				break;
				case BASERR_REASON_OPENLIBSTORAGE:
					aReasonStr = "Der Lib-Storage konnte nicht geoeffnet werden";
				break;
				case BASERR_REASON_OPENMGRSTREAM:
					aReasonStr = "Der Manager-Stream konnte nicht geoeffnet werden";
				break;
				case BASERR_REASON_OPENLIBSTREAM:
					aReasonStr = "Der Basic-Stream konnte nicht geoeffnet werden";
				break;
				case BASERR_REASON_STDLIB:
					aReasonStr = "STANDARD-Lib";
				break;
				case BASERR_REASON_BASICLOADERROR:
					aReasonStr = "Fehler beim Laden des Basics";
				default:
					aReasonStr = " - ";
			}

			String aErr( aErrorStr );
			aErr += "\nGrund: ";
			aErr += aReasonStr;
			InfoBox( 0, aErr ).Execute();

			pError = pBasMgr->GetNextError();
		}
		pBasMgr->ClearErrors();
	 }
}

void __EXPORT TestWindow::Paint( const Rectangle& rRec )
{
}

void __EXPORT TestWindow::Resize()
{
	Size aTBSz = aToolBox.CalcWindowSizePixel();
	aToolBox.SetSizePixel( Size( GetOutputSizePixel().Width(), aTBSz.Height()) );
	Invalidate();
	ShowInfo();
}

void __EXPORT TestWindow::KeyInput( const KeyEvent& rKEvt )
{
	char nCharCode = rKEvt.GetCharCode();
	sal_uInt16 nCode = rKEvt.GetKeyCode().GetCode();

	// Nur bei Alt-Return
	if ( ( nCode == KEY_RETURN ) && rKEvt.GetKeyCode().IsMod2() )
		;
	else
		WorkWindow::KeyInput( rKEvt );

	UpdateToolBox();
}

void __EXPORT TestWindow::MouseMove( const MouseEvent& rMEvt )
{
}

void __EXPORT TestWindow::MouseButtonDown( const MouseEvent& rMEvt )
{
	ShowInfo();
}

void __EXPORT TestWindow::MouseButtonUp( const MouseEvent& rMEvt )
{
	UpdateToolBox();
}

IMPL_LINK( TestWindow, BasicErrorHdl, StarBASIC *, pBasic )
{
	String aErrorText( pBasic->GetErrorText() );

	String aErrorTextPrefix;
	if( pBasic->IsCompilerError() )
	{
		aErrorTextPrefix = "Compilererror: ";
	}
	else
	{
		aErrorTextPrefix = "Runtimeerror: ";
		aErrorTextPrefix += pBasic->GetErrorCode();
		aErrorTextPrefix += " ";
	}

	InfoBox( 0, String( aErrorTextPrefix + aErrorText ) ).Execute();
	return 0;
}

void __EXPORT TestApp::Main( void )
{
	Main( 0, NULL );
}

void __EXPORT TestApp::Main( int, char*[] )
{
	BasicDLL aBasiDLL;
	SvFactory::Init();
	EnableSVLook();
	TestWindow aWindow;
	Execute();
	SvFactory::DeInit();
}


TestApp aTestApp;
