/**************************************************************
 * 
 * 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_basctl.hxx"

// CLOOKS:
//#define _MENUBTN_HXX
#define _SPIN_HXX
#define _PRVWIN_HXX
//#define _FIELD_HXX ***
//#define _TAB_HXX ***
#define _DIALOGS_HXX
#define _SVRTF_HXX
#define _ISETBRW_HXX
#define _VCTRLS_HXX
#define SI_NOCONTROL
#define SI_NOSBXCONTROLS

#define ITEMID_SIZE	0

// Falls ohne PCH's:
#include <ide_pch.hxx>


#define _SOLAR__PRIVATE 1
#include <basic/sbx.hxx>
#include <svl/hint.hxx>
#include <tools/diagnose_ex.h>
#include <basidesh.hrc>
#include <basidesh.hxx>
#include <basdoc.hxx>
#include <basobj.hxx>
#include <bastypes.hxx>
#include <basicbox.hxx>
#include <objdlg.hxx>
#include <sbxitem.hxx>
#include <tbxctl.hxx>
#include <iderdll2.hxx>
#include <basidectrlr.hxx>
#include <localizationmgr.hxx>

#define BasicIDEShell
#define SFX_TYPEMAP
#include <idetemp.hxx>
#include <basslots.hxx>
#include <iderdll.hxx>
#include <svx/pszctrl.hxx>
#include <svx/insctrl.hxx>
#include <svx/srchdlg.hxx>
#include <svx/lboxctrl.hxx>
#include <svx/tbcontrl.hxx>
#include <com/sun/star/script/XLibraryContainer.hpp>
#include <com/sun/star/script/XLibraryContainerPassword.hpp>
#include <com/sun/star/container/XNameContainer.hpp>
#include <com/sun/star/container/XContainer.hpp>
#include <com/sun/star/container/XContainerListener.hpp>
#include <com/sun/star/script/XLibraryContainer.hpp>

#include <svx/xmlsecctrl.hxx>

using namespace ::com::sun::star::uno;
using namespace ::com::sun::star;
using ::rtl::OUString;

static const rtl::OUString sStandardLibName(  rtl::OUString::createFromAscii("Standard") );

typedef ::cppu::WeakImplHelper1< container::XContainerListener > ContainerListenerBASE;

class ContainerListenerImpl : public ContainerListenerBASE
{
    BasicIDEShell* mpShell;
public:

    ContainerListenerImpl( BasicIDEShell* pShell ) : mpShell( pShell ) {}

    ~ContainerListenerImpl() 
    {
    }

    void addContainerListener( const ScriptDocument& rScriptDocument, const String& aLibName )
    {
        try
        {
            uno::Reference< container::XContainer > xContainer( rScriptDocument.getLibrary( E_SCRIPTS, aLibName, sal_False ), uno::UNO_QUERY );
            if ( xContainer.is() )
            {
                uno::Reference< container::XContainerListener > xContainerListener( this );
                xContainer->addContainerListener( xContainerListener );
            }
        }
        catch( uno::Exception& ) {}
    }
    void removeContainerListener( const ScriptDocument& rScriptDocument, const String& aLibName )
    {
        try
        {
            uno::Reference< container::XContainer > xContainer( rScriptDocument.getLibrary( E_SCRIPTS, aLibName, sal_False ), uno::UNO_QUERY );
            if ( xContainer.is() )
            {
                uno::Reference< container::XContainerListener > xContainerListener( this );
                xContainer->removeContainerListener( xContainerListener );
            }
        }
        catch( uno::Exception& ) {}
    }

    // XEventListener
    virtual void SAL_CALL disposing( const lang::EventObject& ) throw( uno::RuntimeException ) {}

    // XContainerListener
    virtual void SAL_CALL elementInserted( const container::ContainerEvent& Event ) throw( uno::RuntimeException )
    {
        rtl::OUString sModuleName;
        if( mpShell && ( Event.Accessor >>= sModuleName ) )
            mpShell->FindBasWin( mpShell->m_aCurDocument, mpShell->m_aCurLibName, sModuleName, sal_True, sal_False );
    }
    virtual void SAL_CALL elementReplaced( const container::ContainerEvent& ) throw( com::sun::star::uno::RuntimeException ) { }
    virtual void SAL_CALL elementRemoved( const container::ContainerEvent& Event ) throw( com::sun::star::uno::RuntimeException )
    {
        rtl::OUString sModuleName;
        if( mpShell  && ( Event.Accessor >>= sModuleName ) )
        {
            IDEBaseWindow* pWin = mpShell->FindWindow( mpShell->m_aCurDocument, mpShell->m_aCurLibName, sModuleName, BASICIDE_TYPE_MODULE, sal_True );
            if( pWin )
                mpShell->RemoveWindow( pWin, sal_True, sal_True );
        }
    }

};

SFX_IMPL_NAMED_VIEWFACTORY( BasicIDEShell, "Default" )
{
	SFX_VIEW_REGISTRATION( BasicDocShell );
}


SFX_IMPL_INTERFACE( BasicIDEShell, SfxViewShell, IDEResId( RID_STR_IDENAME ) )
{
	SFX_CHILDWINDOW_REGISTRATION( SID_SEARCH_DLG );
    SFX_FEATURED_CHILDWINDOW_REGISTRATION(SID_SHOW_PROPERTYBROWSER, BASICIDE_UI_FEATURE_SHOW_BROWSER);
    SFX_POPUPMENU_REGISTRATION( IDEResId( RID_POPUP_DLGED ) );
}



#define IDE_VIEWSHELL_FLAGS		SFX_VIEW_CAN_PRINT|SFX_VIEW_NO_NEWWINDOW


// Hack for #101048
static sal_Int32 GnBasicIDEShellCount;
sal_Int32 getBasicIDEShellCount( void )
    { return GnBasicIDEShellCount; }

BasicIDEShell::BasicIDEShell( SfxViewFrame* pFrame_, SfxViewShell* /* pOldShell */ ) :
		SfxViewShell( pFrame_, IDE_VIEWSHELL_FLAGS ),
        m_aCurDocument( ScriptDocument::getApplicationScriptDocument() ),
		aHScrollBar( &GetViewFrame()->GetWindow(), WinBits( WB_HSCROLL | WB_DRAG ) ),
		aVScrollBar( &GetViewFrame()->GetWindow(), WinBits( WB_VSCROLL | WB_DRAG ) ),
		aScrollBarBox( &GetViewFrame()->GetWindow(), WinBits( WB_SIZEABLE ) ),
        m_bAppBasicModified( sal_False ),
        m_aNotifier( *this )
{
    m_xLibListener = new ContainerListenerImpl( this );
	Init();
    GnBasicIDEShellCount++;
}



void BasicIDEShell::Init()
{
	TbxControls::RegisterControl( SID_CHOOSE_CONTROLS );
	SvxPosSizeStatusBarControl::RegisterControl();
	SvxInsertStatusBarControl::RegisterControl();
	XmlSecStatusBarControl::RegisterControl( SID_SIGNATURE );
    SvxSimpleUndoRedoController::RegisterControl( SID_UNDO );
    SvxSimpleUndoRedoController::RegisterControl( SID_REDO );

	SvxSearchDialogWrapper::RegisterChildWindow( sal_False );

	IDE_DLL()->GetExtraData()->ShellInCriticalSection() = sal_True;

	SetName( String( RTL_CONSTASCII_USTRINGPARAM( "BasicIDE" ) ) );
	SetHelpId( SVX_INTERFACE_BASIDE_VIEWSH );

	LibBoxControl::RegisterControl( SID_BASICIDE_LIBSELECTOR );
	LanguageBoxControl::RegisterControl( SID_BASICIDE_CURRENT_LANG );

	CreateModulWindowLayout();

    GetViewFrame()->GetWindow().SetBackground();

	pCurWin = 0;
    m_aCurDocument = ScriptDocument::getApplicationScriptDocument();
	pObjectCatalog = 0;
	bCreatingWindow = sal_False;

	m_pCurLocalizationMgr = NULL;

	pTabBar = new BasicIDETabBar( &GetViewFrame()->GetWindow() );
	pTabBar->SetSplitHdl( LINK( this, BasicIDEShell, TabBarSplitHdl ) );
	bTabBarSplitted = sal_False;

	nCurKey = 100;
	InitScrollBars();
	InitTabBar();

    SetCurLib( ScriptDocument::getApplicationScriptDocument(), String::CreateFromAscii( "Standard" ), false, false );

    if ( IDE_DLL() && IDE_DLL()->pShell == NULL )
        IDE_DLL()->pShell = this;

    IDE_DLL()->GetExtraData()->ShellInCriticalSection() = sal_False;

    // It's enough to create the controller ...
    // It will be public by using magic :-)
    new BasicIDEController( this );

    // Force updating the title ! Because it must be set to the controller
    // it has to be called directly after creating those controller.
    SetMDITitle ();

	UpdateWindows();
}

__EXPORT BasicIDEShell::~BasicIDEShell()
{
    m_aNotifier.dispose();

    if ( IDE_DLL() && IDE_DLL()->pShell == this )
        IDE_DLL()->pShell = NULL;

	// Damit bei einem Basic-Fehler beim Speichern die Shell nicht sofort
	// wieder hoch kommt:
	IDE_DLL()->GetExtraData()->ShellInCriticalSection() = sal_True;

	SetWindow( 0 );
	SetCurWindow( 0 );

	// Alle Fenster zerstoeren:
	IDEBaseWindow* pWin = aIDEWindowTable.First();
	while ( pWin )
	{
		// Kein Store, passiert bereits, wenn die BasicManager zerstoert werden.
		delete pWin;
		pWin = aIDEWindowTable.Next();
	}

	aIDEWindowTable.Clear();
	delete pTabBar;
	delete pObjectCatalog;
	DestroyModulWindowLayout();

        ContainerListenerImpl* pListener = static_cast< ContainerListenerImpl* >( m_xLibListener.get() );
        // Destroy all ContainerListeners for Basic Container.
        if ( pListener )
            pListener->removeContainerListener( m_aCurDocument, m_aCurLibName );
    
	// MI: Das gab einen GPF im SDT beim Schliessen da dann der ViewFrame die
	// ObjSh loslaesst. Es wusste auch keiner mehr wozu das gut war.
	// GetViewFrame()->GetObjectShell()->Broadcast( SfxSimpleHint( SFX_HINT_DYING ) );

	IDE_DLL()->GetExtraData()->ShellInCriticalSection() = sal_False;

    GnBasicIDEShellCount--;
}

void BasicIDEShell::onDocumentCreated( const ScriptDocument& /*_rDocument*/ )
{
    UpdateWindows();
}

void BasicIDEShell::onDocumentOpened( const ScriptDocument& /*_rDocument*/ )
{
    UpdateWindows();
}

void BasicIDEShell::onDocumentSave( const ScriptDocument& /*_rDocument*/ )
{
    StoreAllWindowData();
}

void BasicIDEShell::onDocumentSaveDone( const ScriptDocument& /*_rDocument*/ )
{
    // #i115671: Update SID_SAVEDOC after saving is completed
    SfxBindings* pBindings = BasicIDE::GetBindingsPtr();
    if ( pBindings )
        pBindings->Invalidate( SID_SAVEDOC );
}

void BasicIDEShell::onDocumentSaveAs( const ScriptDocument& /*_rDocument*/ )
{
    StoreAllWindowData();
}

void BasicIDEShell::onDocumentSaveAsDone( const ScriptDocument& /*_rDocument*/ )
{
    // not interested in
}

void BasicIDEShell::onDocumentClosed( const ScriptDocument& _rDocument )
{
    if ( !_rDocument.isValid() )
        return;

    bool bSetCurWindow = false;
    bool bSetCurLib = ( _rDocument == m_aCurDocument );

    // remove all windows which belong to this document
    for ( sal_uLong nWin = aIDEWindowTable.Count(); nWin; )
    {
        IDEBaseWindow* pWin = aIDEWindowTable.GetObject( --nWin );
        if ( pWin->IsDocument( _rDocument ) )
        {
            if ( pWin->GetStatus() & (BASWIN_RUNNINGBASIC|BASWIN_INRESCHEDULE) )
            {
                pWin->AddStatus( BASWIN_TOBEKILLED );
                pWin->Hide();
                StarBASIC::Stop();
                // there's no notify
                pWin->BasicStopped();
            }
            else
            {
                pWin->StoreData();
                if ( pWin == pCurWin )
                    bSetCurWindow = true;
                RemoveWindow( pWin, sal_True, sal_False );
            }
        }
    }

    // remove lib info
    BasicIDEData* pData = IDE_DLL()->GetExtraData();
    if ( pData )
        pData->GetLibInfos().RemoveInfoFor( _rDocument );

    if ( bSetCurLib )
        SetCurLib( ScriptDocument::getApplicationScriptDocument(), String::CreateFromAscii( "Standard" ), true, false );
    else if ( bSetCurWindow )
        SetCurWindow( FindApplicationWindow(), sal_True );
}

void BasicIDEShell::onDocumentTitleChanged( const ScriptDocument& /*_rDocument*/ )
{
    SfxBindings* pBindings = BasicIDE::GetBindingsPtr();
    if ( pBindings )
        pBindings->Invalidate( SID_BASICIDE_LIBSELECTOR, sal_True, sal_False );
    SetMDITitle();
}

void BasicIDEShell::onDocumentModeChanged( const ScriptDocument& _rDocument )
{
    for ( sal_uLong nWin = aIDEWindowTable.Count(); nWin; )
    {
        IDEBaseWindow* pWin = aIDEWindowTable.GetObject( --nWin );
        if ( pWin->IsDocument( _rDocument ) && _rDocument.isDocument() )
            pWin->SetReadOnly( _rDocument.isReadOnly() );
    }
}

void BasicIDEShell::StoreAllWindowData( sal_Bool bPersistent )
{
	for ( sal_uLong nWin = 0; nWin < aIDEWindowTable.Count(); nWin++ )
	{
		IDEBaseWindow* pWin = aIDEWindowTable.GetObject( nWin );
		DBG_ASSERT( pWin, "PrepareClose: NULL-Pointer in Table?" );
		if ( !pWin->IsSuspended() )
			pWin->StoreData();
	}

	if ( bPersistent  )
	{
		SFX_APP()->SaveBasicAndDialogContainer();
        SetAppBasicModified( sal_False );

        SfxBindings* pBindings = BasicIDE::GetBindingsPtr();
        if ( pBindings )
        {
            pBindings->Invalidate( SID_SAVEDOC );
            pBindings->Update( SID_SAVEDOC );
        }
	}
}


sal_uInt16 __EXPORT BasicIDEShell::PrepareClose( sal_Bool bUI, sal_Bool bForBrowsing )
{
	(void)bForBrowsing;

	// da es nach Drucken etc. (DocInfo) modifiziert ist, hier resetten
	GetViewFrame()->GetObjectShell()->SetModified(sal_False);

	if ( StarBASIC::IsRunning() )
	{
        if( bUI )
        {
		    String aErrorStr( IDEResId( RID_STR_CANNOTCLOSE ) );
		    Window *pParent = &GetViewFrame()->GetWindow();
		    InfoBox( pParent, aErrorStr ).Execute();
        }
		return sal_False;
	}
	else
	{
		// Hier unguenstig, wird zweimal gerufen...
//		StoreAllWindowData();

		sal_Bool bCanClose = sal_True;
		for ( sal_uLong nWin = 0; bCanClose && ( nWin < aIDEWindowTable.Count() ); nWin++ )
		{
			IDEBaseWindow* pWin = aIDEWindowTable.GetObject( nWin );
			if ( /* !pWin->IsSuspended() && */ !pWin->CanClose() )
			{
                if ( m_aCurLibName.Len() && ( pWin->IsDocument( m_aCurDocument ) || pWin->GetLibName() != m_aCurLibName ) )
                    SetCurLib( ScriptDocument::getApplicationScriptDocument(), String(), false );
				SetCurWindow( pWin, sal_True );
				bCanClose = sal_False;
			}
		}

		if ( bCanClose )
			StoreAllWindowData( sal_False );	// Nicht auf Platte schreiben, das passiert am Ende automatisch

		return bCanClose;
	}
}

void BasicIDEShell::InitScrollBars()
{
	aVScrollBar.SetLineSize( 300 );
	aVScrollBar.SetPageSize( 2000 );
	aHScrollBar.SetLineSize( 300 );
	aHScrollBar.SetPageSize( 2000 );
	aHScrollBar.Enable();
	aVScrollBar.Enable();
	aVScrollBar.Show();
	aHScrollBar.Show();
	aScrollBarBox.Show();
}



void BasicIDEShell::InitTabBar()
{
	pTabBar->Enable();
	pTabBar->Show();
	pTabBar->SetSelectHdl( LINK( this, BasicIDEShell, TabBarHdl ) );
}


Size __EXPORT BasicIDEShell::GetOptimalSizePixel() const
{
	return Size( 400, 300 );
}



void __EXPORT BasicIDEShell::OuterResizePixel( const Point &rPos, const Size &rSize )
{
	// Adjust fliegt irgendwann raus...
	AdjustPosSizePixel( rPos, rSize );
}


IMPL_LINK_INLINE_START( BasicIDEShell, TabBarSplitHdl, TabBar *, pTBar )
{
	(void)pTBar;
	bTabBarSplitted = sal_True;
	ArrangeTabBar();

	return 0;
}
IMPL_LINK_INLINE_END( BasicIDEShell, TabBarSplitHdl, TabBar *, pTBar )



IMPL_LINK( BasicIDEShell, TabBarHdl, TabBar *, pCurTabBar )
{
	sal_uInt16 nCurId = pCurTabBar->GetCurPageId();
	IDEBaseWindow* pWin = aIDEWindowTable.Get( nCurId );
	DBG_ASSERT( pWin, "Eintrag in TabBar passt zu keinem Fenster!" );
	SetCurWindow( pWin );

	return 0;
}



sal_Bool BasicIDEShell::NextPage( sal_Bool bPrev )
{
	sal_Bool bRet = sal_False;
	sal_uInt16 nPos = pTabBar->GetPagePos( pTabBar->GetCurPageId() );

	if ( bPrev )
		--nPos;
	else
		++nPos;

	if ( nPos < pTabBar->GetPageCount() )
	{
		IDEBaseWindow* pWin = aIDEWindowTable.Get( pTabBar->GetPageId( nPos ) );
		SetCurWindow( pWin, sal_True );
		bRet = sal_True;
	}

	return bRet;
}



void BasicIDEShell::ArrangeTabBar()
{
	Size aSz( GetViewFrame()->GetWindow().GetOutputSizePixel() );
	long nBoxPos = aScrollBarBox.GetPosPixel().X() - 1;
	long nPos = pTabBar->GetSplitSize();
	if ( nPos <= nBoxPos )
	{
		Point aPnt( pTabBar->GetPosPixel() );
		long nH = aHScrollBar.GetSizePixel().Height();
		pTabBar->SetPosSizePixel( aPnt, Size( nPos, nH ) );
		long nScrlStart = aPnt.X() + nPos;
		aHScrollBar.SetPosSizePixel( Point( nScrlStart, aPnt.Y() ), Size( nBoxPos - nScrlStart + 2, nH ) );
		aHScrollBar.Update();
	}
}



::svl::IUndoManager* BasicIDEShell::GetUndoManager()
{
	::svl::IUndoManager* pMgr = NULL;
	if( pCurWin )
		pMgr = pCurWin->GetUndoManager();

	return pMgr;
}



void BasicIDEShell::ShowObjectDialog( sal_Bool bShow, sal_Bool bCreateOrDestroy )
{
	if ( bShow )
	{
		if ( !pObjectCatalog && bCreateOrDestroy )
		{
			pObjectCatalog = new ObjectCatalog( &GetViewFrame()->GetWindow() );
			// Position wird in BasicIDEData gemerkt und vom Dlg eingestellt
            if ( pObjectCatalog )
            {
                pObjectCatalog->SetCancelHdl( LINK( this, BasicIDEShell, ObjectDialogCancelHdl ) );
                BasicEntryDescriptor aDesc;
                IDEBaseWindow* pCurWin_ = GetCurWindow();
                if ( pCurWin_ )
                    aDesc = pCurWin_->CreateEntryDescriptor();
                pObjectCatalog->SetCurrentEntry( aDesc );
            }
		}

		// Die allerletzten Aenderungen...
		if ( pCurWin )
			pCurWin->StoreData();

		if ( pObjectCatalog )
		{
			pObjectCatalog->UpdateEntries();
			pObjectCatalog->Show();
		}
	}
	else if ( pObjectCatalog )
	{
		pObjectCatalog->Hide();
		if ( bCreateOrDestroy )
		{
			// Wegen OS/2-Focus-Problem pObjectCatalog vorm delete auf NULL
			ObjectCatalog* pTemp = pObjectCatalog;
			pObjectCatalog = 0;
			delete pTemp;
		}
	}
}



void __EXPORT BasicIDEShell::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId&,
										const SfxHint& rHint, const TypeId& )
{
    if ( IDE_DLL()->GetShell() )
    {
		const SfxSimpleHint* pSfxSimpleHint = dynamic_cast< const SfxSimpleHint* >(&rHint);

		if ( pSfxSimpleHint )
        {
            switch ( pSfxSimpleHint->GetId() )
            {
                case SFX_HINT_DYING:
                {
                    EndListening( rBC, sal_True /* Alle abmelden */ );
                    if ( pObjectCatalog )
                        pObjectCatalog->UpdateEntries();
                }
                break;
            }

			const SbxHint* pSbxHint = dynamic_cast< const SbxHint* >(&rHint);

			if ( pSbxHint )
            {
                sal_uLong nHintId = pSbxHint->GetId();
                if (	( nHintId == SBX_HINT_BASICSTART ) ||
                        ( nHintId == SBX_HINT_BASICSTOP ) )
                {
                    SfxBindings* pBindings = BasicIDE::GetBindingsPtr();
                    if ( pBindings )
                    {
                        pBindings->Invalidate( SID_BASICRUN );
                        pBindings->Update( SID_BASICRUN );
                        pBindings->Invalidate( SID_BASICCOMPILE );
                        pBindings->Update( SID_BASICCOMPILE );
                        pBindings->Invalidate( SID_BASICSTEPOVER );
                        pBindings->Update( SID_BASICSTEPOVER );
                        pBindings->Invalidate( SID_BASICSTEPINTO );
                        pBindings->Update( SID_BASICSTEPINTO );
                        pBindings->Invalidate( SID_BASICSTEPOUT );
                        pBindings->Update( SID_BASICSTEPOUT );
                        pBindings->Invalidate( SID_BASICSTOP );
                        pBindings->Update( SID_BASICSTOP );
                        pBindings->Invalidate( SID_BASICIDE_TOGGLEBRKPNT );
                        pBindings->Update( SID_BASICIDE_TOGGLEBRKPNT );
                        pBindings->Invalidate( SID_BASICIDE_MANAGEBRKPNTS );
                        pBindings->Update( SID_BASICIDE_MANAGEBRKPNTS );
                        pBindings->Invalidate( SID_BASICIDE_MODULEDLG );
                        pBindings->Update( SID_BASICIDE_MODULEDLG );
                        pBindings->Invalidate( SID_BASICLOAD );
                        pBindings->Update( SID_BASICLOAD );
                    }

                    if ( nHintId == SBX_HINT_BASICSTOP )
                    {
                        // Nicht nur bei Error/Break oder explizitem anhalten,
                        // falls durch einen Programmierfehler das Update abgeschaltet ist.
                        BasicIDE::BasicStopped();
                        UpdateModulWindowLayout( true );    // Leer machen...
						if( m_pCurLocalizationMgr )
							m_pCurLocalizationMgr->handleBasicStopped();
                    }
					else if( m_pCurLocalizationMgr )
                    {
						m_pCurLocalizationMgr->handleBasicStarted();
                    }

                    IDEBaseWindow* pWin = aIDEWindowTable.First();
                    while ( pWin )
                    {
                        if ( nHintId == SBX_HINT_BASICSTART )
                            pWin->BasicStarted();
                        else
                            pWin->BasicStopped();
                        pWin = aIDEWindowTable.Next();
                    }
                }
            }
        }
    }
}



void BasicIDEShell::CheckWindows()
{
	sal_Bool bSetCurWindow = sal_False;
	for ( sal_uLong nWin = 0; nWin < aIDEWindowTable.Count(); nWin++ )
	{
		IDEBaseWindow* pWin = aIDEWindowTable.GetObject( nWin );
		if ( pWin->GetStatus() & BASWIN_TOBEKILLED )
		{
			pWin->StoreData();
			if ( pWin == pCurWin )
				bSetCurWindow = sal_True;
			RemoveWindow( pWin, sal_True, sal_False );
			nWin--;
		}
	}
	if ( bSetCurWindow )
		SetCurWindow( FindApplicationWindow(), sal_True );
}



void BasicIDEShell::RemoveWindows( const ScriptDocument& rDocument, const String& rLibName, sal_Bool bDestroy )
{
	sal_Bool bChangeCurWindow = pCurWin ? sal_False : sal_True;
	for ( sal_uLong nWin = 0; nWin < aIDEWindowTable.Count(); nWin++ )
	{
		IDEBaseWindow* pWin = aIDEWindowTable.GetObject( nWin );
        if ( pWin->IsDocument( rDocument ) && pWin->GetLibName() == rLibName )
		{
			if ( pWin == pCurWin )
				bChangeCurWindow = sal_True;
			pWin->StoreData();
			RemoveWindow( pWin, bDestroy, sal_False );
			nWin--;
		}
	}
	if ( bChangeCurWindow )
		SetCurWindow( FindApplicationWindow(), sal_True );
}



void BasicIDEShell::UpdateWindows()
{
	// Alle Fenster, die nicht angezeigt werden duerfen, entfernen
	sal_Bool bChangeCurWindow = pCurWin ? sal_False : sal_True;
    if ( m_aCurLibName.Len() )
	{
		for ( sal_uLong nWin = 0; nWin < aIDEWindowTable.Count(); nWin++ )
		{
			IDEBaseWindow* pWin = aIDEWindowTable.GetObject( nWin );
            if ( !pWin->IsDocument( m_aCurDocument ) || pWin->GetLibName() != m_aCurLibName )
			{
				if ( pWin == pCurWin )
					bChangeCurWindow = sal_True;
				pWin->StoreData();
				// Die Abfrage auf RUNNING verhindert den Absturz, wenn in Reschedule.
				// Fenster bleibt erstmal stehen, spaeter sowieso mal umstellen,
				// dass Fenster nur als Hidden markiert werden und nicht
				// geloescht.
				if ( !(pWin->GetStatus() & ( BASWIN_TOBEKILLED | BASWIN_RUNNINGBASIC | BASWIN_SUSPENDED ) ) )
				{
					RemoveWindow( pWin, sal_False, sal_False );
					nWin--;
				}
			}
		}
	}

	if ( bCreatingWindow )
		return;

    IDEBaseWindow* pNextActiveWindow = 0;

	// Alle anzuzeigenden Fenster anzeigen
    ScriptDocuments aDocuments( ScriptDocument::getAllScriptDocuments( ScriptDocument::AllWithApplication ) );
    for (   ScriptDocuments::const_iterator doc = aDocuments.begin();
            doc != aDocuments.end();
            ++doc
        )
	{
		StartListening( *doc->getBasicManager(), sal_True /* Nur einmal anmelden */ );

        // libraries
        Sequence< ::rtl::OUString > aLibNames( doc->getLibraryNames() );
        sal_Int32 nLibCount = aLibNames.getLength();
	    const ::rtl::OUString* pLibNames = aLibNames.getConstArray();

        for ( sal_Int32 i = 0 ; i < nLibCount ; i++ )
	    {
            String aLibName = pLibNames[ i ];

            if ( !m_aCurLibName.Len() || ( *doc == m_aCurDocument && aLibName == m_aCurLibName ) )
            {
                // check, if library is password protected and not verified
                sal_Bool bProtected = sal_False;
                Reference< script::XLibraryContainer > xModLibContainer( doc->getLibraryContainer( E_SCRIPTS ) );
                if ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) )
                {
                    Reference< script::XLibraryContainerPassword > xPasswd( xModLibContainer, UNO_QUERY );
                    if ( xPasswd.is() && xPasswd->isLibraryPasswordProtected( aLibName ) && !xPasswd->isLibraryPasswordVerified( aLibName ) )
                    {
                        bProtected = sal_True;
                    }
                }

                if ( !bProtected )
                {
                    LibInfoItem* pLibInfoItem = 0;
                    BasicIDEData* pData = IDE_DLL()->GetExtraData();
                    if ( pData )
                        pLibInfoItem = pData->GetLibInfos().GetInfo( LibInfoKey( *doc, aLibName ) );

                    // modules
                    if ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) )
                    {
                        StarBASIC* pLib = doc->getBasicManager()->GetLib( aLibName );
                        if ( pLib )
                            ImplStartListening( pLib );

                        try
					    {
                            Sequence< ::rtl::OUString > aModNames( doc->getObjectNames( E_SCRIPTS, aLibName ) );
                            sal_Int32 nModCount = aModNames.getLength();
	                        const ::rtl::OUString* pModNames = aModNames.getConstArray();

                            for ( sal_Int32 j = 0 ; j < nModCount ; j++ )
				            {
					            String aModName = pModNames[ j ];
						        ModulWindow* pWin = FindBasWin( *doc, aLibName, aModName, sal_False );
                                if ( !pWin )
							        pWin = CreateBasWin( *doc, aLibName, aModName );
                                if ( !pNextActiveWindow && pLibInfoItem && pLibInfoItem->GetCurrentName() == aModName &&
                                        pLibInfoItem->GetCurrentType() == BASICIDE_TYPE_MODULE )
                                {
                                    pNextActiveWindow = (IDEBaseWindow*)pWin;
                                }
                            }
                        }
					    catch ( container::NoSuchElementException& )
					    {
                            DBG_UNHANDLED_EXCEPTION();
					    }
                    }

                    // dialogs
                    Reference< script::XLibraryContainer > xDlgLibContainer( doc->getLibraryContainer( E_DIALOGS ) );
                    if ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) )
                    {
                        try
                        {
                            Sequence< ::rtl::OUString > aDlgNames = doc->getObjectNames( E_DIALOGS, aLibName );
                            sal_Int32 nDlgCount = aDlgNames.getLength();
	                        const ::rtl::OUString* pDlgNames = aDlgNames.getConstArray();

                            for ( sal_Int32 j = 0 ; j < nDlgCount ; j++ )
				            {
					            String aDlgName = pDlgNames[ j ];
                                // this find only looks for non-suspended windows;
                                // suspended windows are handled in CreateDlgWin
                                DialogWindow* pWin = FindDlgWin( *doc, aLibName, aDlgName, sal_False );
                                if ( !pWin )
								    pWin = CreateDlgWin( *doc, aLibName, aDlgName );
                                if ( !pNextActiveWindow && pLibInfoItem && pLibInfoItem->GetCurrentName() == aDlgName &&
                                        pLibInfoItem->GetCurrentType() == BASICIDE_TYPE_DIALOG )
                                {
                                    pNextActiveWindow = (IDEBaseWindow*)pWin;
                                }
                            }
                        }
					    catch ( container::NoSuchElementException& )
					    {
						    DBG_UNHANDLED_EXCEPTION();
					    }
                    }
				}
            }
        }
	}

	if ( bChangeCurWindow )
    {
        if ( !pNextActiveWindow )
            pNextActiveWindow = FindApplicationWindow();
        SetCurWindow( pNextActiveWindow, sal_True );
    }
}

void BasicIDEShell::RemoveWindow( IDEBaseWindow* pWindow_, sal_Bool bDestroy, sal_Bool bAllowChangeCurWindow )
{
	DBG_ASSERT( pWindow_, "Kann keinen NULL-Pointer loeschen!" );
	sal_uLong nKey = aIDEWindowTable.GetKey( pWindow_ );
	pTabBar->RemovePage( (sal_uInt16)nKey );
	aIDEWindowTable.Remove( nKey );
	if ( pWindow_ == pCurWin )
	{
		if ( bAllowChangeCurWindow )
			SetCurWindow( FindApplicationWindow(), sal_True );
		else
			SetCurWindow( NULL, sal_False );
	}
	if ( bDestroy )
	{
		if ( !( pWindow_->GetStatus() & BASWIN_INRESCHEDULE ) )
		{
			delete pWindow_;
		}
		else
		{
			pWindow_->AddStatus( BASWIN_TOBEKILLED );
			pWindow_->Hide();
            // In normal mode stop basic in windows to be deleted
            // In VBA stop basic only if the running script is trying to delete
            // its parent module
            bool bStop = true;
            if ( pWindow_->GetDocument().isInVBAMode() )
            {
                SbModule* pMod = StarBASIC::GetActiveModule();
                if ( !pMod || ( pMod && ( pMod->GetName() != pWindow_->GetName() ) ) )
                    bStop = false;
            }
            if ( bStop )
            {
                StarBASIC::Stop();
                // Es kommt kein Notify...
                pWindow_->BasicStopped();
            }
			aIDEWindowTable.Insert( nKey, pWindow_ );	// wieder einhaegen
		}
	}
	else
	{
		pWindow_->Hide();
		pWindow_->AddStatus( BASWIN_SUSPENDED );
		pWindow_->Deactivating();
		aIDEWindowTable.Insert( nKey, pWindow_ );	// wieder einhaegen
	}

}



sal_uInt16 BasicIDEShell::InsertWindowInTable( IDEBaseWindow* pNewWin )
{
	// Eigentlich prueffen,
	nCurKey++;
	aIDEWindowTable.Insert( nCurKey, pNewWin );
	return nCurKey;
}



void BasicIDEShell::InvalidateBasicIDESlots()
{
	// Nur die, die eine optische Auswirkung haben...

	if ( IDE_DLL()->GetShell() )
	{
        SfxBindings* pBindings = BasicIDE::GetBindingsPtr();
        if ( pBindings )
        {
            pBindings->Invalidate( SID_COPY );
            pBindings->Invalidate( SID_CUT );
            pBindings->Invalidate( SID_PASTE );
            pBindings->Invalidate( SID_UNDO );
            pBindings->Invalidate( SID_REDO );
            pBindings->Invalidate( SID_SAVEDOC );
            pBindings->Invalidate( SID_SIGNATURE );
            pBindings->Invalidate( SID_BASICIDE_CHOOSEMACRO );
            pBindings->Invalidate( SID_BASICIDE_MODULEDLG );
            pBindings->Invalidate( SID_BASICIDE_OBJCAT );
            pBindings->Invalidate( SID_BASICSTOP );
            pBindings->Invalidate( SID_BASICRUN );
            pBindings->Invalidate( SID_BASICCOMPILE );
            pBindings->Invalidate( SID_BASICLOAD );
            pBindings->Invalidate( SID_BASICSAVEAS );
            pBindings->Invalidate( SID_BASICIDE_MATCHGROUP );
            pBindings->Invalidate( SID_BASICSTEPINTO );
            pBindings->Invalidate( SID_BASICSTEPOVER );
            pBindings->Invalidate( SID_BASICSTEPOUT );
            pBindings->Invalidate( SID_BASICIDE_TOGGLEBRKPNT );
            pBindings->Invalidate( SID_BASICIDE_MANAGEBRKPNTS );
            pBindings->Invalidate( SID_BASICIDE_ADDWATCH );
            pBindings->Invalidate( SID_BASICIDE_REMOVEWATCH );
            pBindings->Invalidate( SID_CHOOSE_CONTROLS );
            pBindings->Invalidate( SID_PRINTDOC );
            pBindings->Invalidate( SID_PRINTDOCDIRECT );
            pBindings->Invalidate( SID_SETUPPRINTER );
            pBindings->Invalidate( SID_DIALOG_TESTMODE );

            pBindings->Invalidate( SID_DOC_MODIFIED );
            pBindings->Invalidate( SID_BASICIDE_STAT_TITLE );
            pBindings->Invalidate( SID_BASICIDE_STAT_POS );
            pBindings->Invalidate( SID_ATTR_INSERT );
            pBindings->Invalidate( SID_ATTR_SIZE );
        }
	}
}

void BasicIDEShell::EnableScrollbars( sal_Bool bEnable )
{
	if ( bEnable )
	{
		aHScrollBar.Enable();
		aVScrollBar.Enable();
	}
	else
	{
		aHScrollBar.Disable();
		aVScrollBar.Disable();
	}
}

void BasicIDEShell::SetCurLib( const ScriptDocument& rDocument, String aLibName, bool bUpdateWindows, bool bCheck )
{
    if ( !bCheck || ( rDocument != m_aCurDocument || aLibName != m_aCurLibName ) )
    {
        ContainerListenerImpl* pListener = static_cast< ContainerListenerImpl* >( m_xLibListener.get() );

        if ( pListener )
        	pListener->removeContainerListener( m_aCurDocument, m_aCurLibName );

        m_aCurDocument = rDocument;
    
        pListener->addContainerListener( m_aCurDocument, aLibName );

        m_aCurLibName = aLibName;

        if ( bUpdateWindows )
            UpdateWindows();

		SetMDITitle();

		SetCurLibForLocalization( rDocument, aLibName );

        SfxBindings* pBindings = BasicIDE::GetBindingsPtr();
        if ( pBindings )
		{
            pBindings->Invalidate( SID_BASICIDE_LIBSELECTOR );
			pBindings->Invalidate( SID_BASICIDE_CURRENT_LANG );
			pBindings->Invalidate( SID_BASICIDE_MANAGE_LANG );
		}
    }
}

void BasicIDEShell::SetCurLibForLocalization( const ScriptDocument& rDocument, String aLibName )
{
    // Create LocalizationMgr
	delete m_pCurLocalizationMgr;
	Reference< resource::XStringResourceManager > xStringResourceManager;
	try
	{
		if( aLibName.Len() )
		{
			Reference< container::XNameContainer > xDialogLib( rDocument.getLibrary( E_DIALOGS, aLibName, sal_True ) );
			xStringResourceManager = LocalizationMgr::getStringResourceFromDialogLibrary( xDialogLib );
	    }
	}
    catch ( container::NoSuchElementException& )
	{}
	m_pCurLocalizationMgr = new LocalizationMgr
		( this, rDocument, aLibName, xStringResourceManager );

	m_pCurLocalizationMgr->handleTranslationbar();
}

void BasicIDEShell::ImplStartListening( StarBASIC* pBasic )
{
	StartListening( pBasic->GetBroadcaster(), sal_True /* Nur einmal anmelden */ );
}


