/**************************************************************
 *
 * 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"

#include <ide_pch.hxx>

#include <vector>
#include <algorithm>
#include <basic/sbx.hxx>
#include <unotools/moduleoptions.hxx>

#include <iderdll.hxx>
#include <iderdll2.hxx>
#include <basobj.hxx>
#include <basidesh.hxx>
#include <objdlg.hxx>
#include <bastypes.hxx>
#include <basdoc.hxx>
#include <basidesh.hrc>

#include <baside2.hxx>
#include <baside3.hxx>
#include <basicmod.hxx>
#include <localizationmgr.hxx>
#include "dlged.hxx"
#include <dlgeddef.hxx>
#include <comphelper/processfactory.hxx>
#ifndef _COM_SUN_STAR_SCRIPT_XLIBRYARYCONTAINER_HPP_
#include <com/sun/star/script/XLibraryContainer.hpp>
#endif
#include <com/sun/star/script/XLibraryContainerPassword.hpp>
#include <com/sun/star/container/XNameContainer.hpp>
#include <xmlscript/xmldlg_imexp.hxx>
#include <rtl/uri.hxx>
#include <osl/process.h>
#include <osl/file.hxx>

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


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

extern "C" {
    SAL_DLLPUBLIC_EXPORT long basicide_handle_basic_error( void* pPtr )
	{
        return BasicIDE::HandleBasicError( (StarBASIC*)pPtr );
    }
}

namespace BasicIDE
{
//----------------------------------------------------------------------------

SbMethod* CreateMacro( SbModule* pModule, const String& rMacroName )
{
    BasicIDEShell* pIDEShell = IDE_DLL()->GetShell();
    SfxViewFrame* pViewFrame = pIDEShell ? pIDEShell->GetViewFrame() : NULL;
	SfxDispatcher* pDispatcher = pViewFrame ? pViewFrame->GetDispatcher() : NULL;

    if( pDispatcher )
	{
		pDispatcher->Execute( SID_BASICIDE_STOREALLMODULESOURCES );
	}

	if ( pModule->GetMethods()->Find( rMacroName, SbxCLASS_METHOD ) )
		return 0;

	String aMacroName( rMacroName );
	if ( aMacroName.Len() == 0 )
	{
		if ( !pModule->GetMethods()->Count() )
			aMacroName = String( RTL_CONSTASCII_USTRINGPARAM( "Main" ) );
		else
		{
			sal_Bool bValid = sal_False;
			String aStdMacroText( RTL_CONSTASCII_USTRINGPARAM( "Macro" ) );
			//String aStdMacroText( IDEResId( RID_STR_STDMACRONAME ) );
			sal_uInt16 nMacro = 1;
			while ( !bValid )
			{
				aMacroName = aStdMacroText;
				aMacroName += String::CreateFromInt32( nMacro );
				// Pruefen, ob vorhanden...
				bValid = pModule->GetMethods()->Find( aMacroName, SbxCLASS_METHOD ) ? sal_False : sal_True;
				nMacro++;
			}
		}
	}

    ::rtl::OUString aOUSource( pModule->GetSource32() );

	// Nicht zu viele Leerzeilen erzeugen...
    sal_Int32 nSourceLen = aOUSource.getLength();
	if ( nSourceLen > 2 )
	{
        const sal_Unicode* pStr = aOUSource.getStr();
		if ( pStr[ nSourceLen - 1 ]  != LINE_SEP )
			aOUSource += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "\n\n" ) );
		else if ( pStr[ nSourceLen - 2 ] != LINE_SEP )
			aOUSource += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "\n" ) );
		else if ( pStr[ nSourceLen - 3 ] == LINE_SEP )
			aOUSource = aOUSource.copy( 0, nSourceLen-1 );
	}

	::rtl::OUString aSubStr;
	aSubStr = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Sub " ) );
	aSubStr += aMacroName;
	aSubStr += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "\n\nEnd Sub" ) );

	aOUSource += aSubStr;

    // update module in library
    ScriptDocument aDocument( ScriptDocument::NoDocument );
    SbxObject* pParent = pModule->GetParent();
	StarBASIC* pBasic = PTR_CAST(StarBASIC,pParent);
    DBG_ASSERT(pBasic, "BasicIDE::CreateMacro: No Basic found!");
    if ( pBasic )
	{
		BasicManager* pBasMgr = BasicIDE::FindBasicManager( pBasic );
		DBG_ASSERT(pBasMgr, "BasicIDE::CreateMacro: No BasicManager found!");
		if ( pBasMgr )
		{
            aDocument = ScriptDocument::getDocumentForBasicManager( pBasMgr );
            OSL_ENSURE( aDocument.isValid(), "BasicIDE::CreateMacro: no document for the given BasicManager!" );
            if ( aDocument.isValid() )
            {
        	    String aLibName = pBasic->GetName();
	            String aModName = pModule->GetName();
                OSL_VERIFY( aDocument.updateModule( aLibName, aModName, aOUSource ) );
            }
        }
    }

    SbMethod* pMethod = (SbMethod*)pModule->GetMethods()->Find( aMacroName, SbxCLASS_METHOD );

    if( pDispatcher )
	{
		pDispatcher->Execute( SID_BASICIDE_UPDATEALLMODULESOURCES );
	}

    if ( aDocument.isAlive() )
        BasicIDE::MarkDocumentModified( aDocument );

    return pMethod;
}

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

bool RenameDialog( Window* pErrorParent, const ScriptDocument& rDocument, const String& rLibName, const String& rOldName, const String& rNewName )
	throw(ElementExistException, NoSuchElementException)
{
    if ( !rDocument.hasDialog( rLibName, rOldName ) )
    {
        OSL_ENSURE( false, "BasicIDE::RenameDialog: old module name is invalid!" );
        return false;
    }

    if ( rDocument.hasDialog( rLibName, rNewName ) )
    {
        ErrorBox aError( pErrorParent, WB_OK | WB_DEF_OK, String( IDEResId( RID_STR_SBXNAMEALLREADYUSED2 ) ) );
        aError.Execute();
        return false;
    }

	// #i74440
	if ( rNewName.Len() == 0 )
    {
        ErrorBox aError( pErrorParent, WB_OK | WB_DEF_OK, String( IDEResId( RID_STR_BADSBXNAME ) ) );
        aError.Execute();
		return false;
    }

    BasicIDEShell* pIDEShell = IDE_DLL()->GetShell();
    IDEBaseWindow* pWin = pIDEShell ? pIDEShell->FindWindow( rDocument, rLibName, rOldName, BASICIDE_TYPE_DIALOG, sal_False ) : NULL;
    Reference< XNameContainer > xExistingDialog;
    if ( pWin )
        xExistingDialog = ((DialogWindow*)pWin)->GetEditor()->GetDialog();

    if ( xExistingDialog.is() )
        LocalizationMgr::renameStringResourceIDs( rDocument, rLibName, rNewName, xExistingDialog );

    if ( !rDocument.renameDialog( rLibName, rOldName, rNewName, xExistingDialog ) )
        return false;

	if ( pWin )
	{
		// set new name in window
		pWin->SetName( rNewName );

		// update property browser
		((DialogWindow*)pWin)->UpdateBrowser();

		// update tabwriter
		sal_uInt16 nId = (sal_uInt16)(pIDEShell->GetIDEWindowTable()).GetKey( pWin );
		DBG_ASSERT( nId, "No entry in Tabbar!" );
		if ( nId )
		{
			BasicIDETabBar*	pTabBar = (BasicIDETabBar*)pIDEShell->GetTabBar();
			pTabBar->SetPageText( nId, rNewName );
			pTabBar->Sort();
			pTabBar->MakeVisible( pTabBar->GetCurPageId() );
		}
	}
    return true;
}

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

bool RemoveDialog( const ScriptDocument& rDocument, const String& rLibName, const String& rDlgName )
{
    BasicIDEShell* pIDEShell = IDE_DLL()->GetShell();
    if ( pIDEShell )
	{
		DialogWindow* pDlgWin = pIDEShell->FindDlgWin( rDocument, rLibName, rDlgName, sal_False );
		if( pDlgWin )
		{
			Reference< container::XNameContainer > xDialogModel = pDlgWin->GetDialog();
			LocalizationMgr::removeResourceForDialog( rDocument, rLibName, rDlgName, xDialogModel );
		}
	}

    return rDocument.removeDialog( rLibName, rDlgName );
}

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

StarBASIC* FindBasic( const SbxVariable* pVar )
{
	const SbxVariable* pSbx = pVar;
	while ( pSbx && !pSbx->ISA( StarBASIC ) )
		pSbx = pSbx->GetParent();

	DBG_ASSERT( !pSbx || pSbx->ISA( StarBASIC ), "Find Basic: Kein Basic!" );
	return (StarBASIC*)pSbx;
}

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

BasicManager* FindBasicManager( StarBASIC* pLib )
{
    ScriptDocuments aDocuments( ScriptDocument::getAllScriptDocuments( ScriptDocument::AllWithApplication ) );
    for (   ScriptDocuments::const_iterator doc = aDocuments.begin();
            doc != aDocuments.end();
            ++doc
        )
    {
        BasicManager* pBasicMgr = doc->getBasicManager();
        OSL_ENSURE( pBasicMgr, "BasicIDE::FindBasicManager: no basic manager for the document!" );
        if ( !pBasicMgr )
            continue;

        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++ )
	    {
            StarBASIC* pL = pBasicMgr->GetLib( pLibNames[ i ] );
			if ( pL == pLib )
				return pBasicMgr;
        }
	}
	return NULL;
}

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

void MarkDocumentModified( const ScriptDocument& rDocument )
{
	// Muss ja nicht aus einem Document kommen...
    if ( rDocument.isApplication() )
    {
        BasicIDEShell* pIDEShell = IDE_DLL()->GetShell();
        if ( pIDEShell )
            pIDEShell->SetAppBasicModified();
    }
    else
    {
        rDocument.setDocumentModified();
    }

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

	// Objectcatalog updaten...
	BasicIDEShell* pIDEShell = IDE_DLL()->GetShell();
	ObjectCatalog* pObjCatalog = pIDEShell ? pIDEShell->GetObjectCatalog() : 0;
	if ( pObjCatalog )
		pObjCatalog->UpdateEntries();
}

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

void RunMethod( SbMethod* pMethod )
{
	SbxValues aRes;
	aRes.eType = SbxVOID;
	pMethod->Get( aRes );
}

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

void StopBasic()
{
	StarBASIC::Stop();
	BasicIDEShell* pShell = IDE_DLL()->GetShell();
	if ( pShell )
	{
		IDEWindowTable& rWindows = pShell->GetIDEWindowTable();
		IDEBaseWindow* pWin = rWindows.First();
		while ( pWin )
		{
			// BasicStopped von Hand rufen, da das Stop-Notify ggf. sonst nicht
			// durchkommen kann.
			pWin->BasicStopped();
			pWin = rWindows.Next();
		}
	}
	BasicIDE::BasicStopped();
}

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

void BasicStopped( sal_Bool* pbAppWindowDisabled,
		sal_Bool* pbDispatcherLocked, sal_uInt16* pnWaitCount,
		SfxUInt16Item** ppSWActionCount, SfxUInt16Item** ppSWLockViewCount )
{
	// Nach einem Error oder dem expliziten abbrechen des Basics muessen
	// ggf. einige Locks entfernt werden...

	if ( pbAppWindowDisabled )
		*pbAppWindowDisabled = sal_False;
	if ( pbDispatcherLocked )
		*pbDispatcherLocked = sal_False;
	if ( pnWaitCount )
		*pnWaitCount = 0;
	if ( ppSWActionCount )
		*ppSWActionCount = 0;
	if ( ppSWLockViewCount )
		*ppSWLockViewCount = 0;

	// AppWait ?
	sal_uInt16 nWait = 0;
	BasicIDEShell* pIDEShell = IDE_DLL()->GetShell();
	if( pIDEShell )
	{
		while ( pIDEShell->GetViewFrame()->GetWindow().IsWait() )
		{
			pIDEShell->GetViewFrame()->GetWindow().LeaveWait();
			nWait++;
		}
		if ( pnWaitCount )
			*pnWaitCount = nWait;
	}

    /*
    // Interactive = sal_False ?
	if ( SFX_APP()->IsDispatcherLocked() )
	{
		SFX_APP()->LockDispatcher( sal_False );
		if ( pbDispatcherLocked )
			*pbDispatcherLocked = sal_True;
    } */

	Window* pDefParent = Application::GetDefDialogParent();
	if ( pDefParent && !pDefParent->IsEnabled() )
	{
		pDefParent->Enable( sal_True );
		if ( pbAppWindowDisabled )
			*pbAppWindowDisabled = sal_True;
	}

}

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

void InvalidateDebuggerSlots()
{
    SfxBindings* pBindings = BasicIDE::GetBindingsPtr();
    if ( pBindings )
    {
        pBindings->Invalidate( SID_BASICSTOP );
        pBindings->Update( SID_BASICSTOP );
        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_BASICIDE_TOGGLEBRKPNT );
        pBindings->Update( SID_BASICIDE_TOGGLEBRKPNT );
        pBindings->Invalidate( SID_BASICIDE_STAT_POS );
        pBindings->Update( SID_BASICIDE_STAT_POS );
    }
}

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

long HandleBasicError( StarBASIC* pBasic )
{
	BasicIDEDLL::Init();
    BasicIDE::BasicStopped();

    // no error output during macro choosing
    if ( IDE_DLL()->GetExtraData()->ChoosingMacro() )
		return 1;
	if ( IDE_DLL()->GetExtraData()->ShellInCriticalSection() )
		return 2;

	long nRet = 0;
	BasicIDEShell* pIDEShell = 0;
	if ( SvtModuleOptions().IsBasicIDE() )
	{
		BasicManager* pBasMgr = BasicIDE::FindBasicManager( pBasic );
		if ( pBasMgr )
		{
            sal_Bool bProtected = sal_False;
            ScriptDocument aDocument( ScriptDocument::getDocumentForBasicManager( pBasMgr ) );
            OSL_ENSURE( aDocument.isValid(), "BasicIDE::HandleBasicError: no document for the given BasicManager!" );
            if ( aDocument.isValid() )
            {
                ::rtl::OUString aOULibName( pBasic->GetName() );
                Reference< script::XLibraryContainer > xModLibContainer( aDocument.getLibraryContainer( E_SCRIPTS ) );
                if ( xModLibContainer.is() && xModLibContainer->hasByName( aOULibName ) )
                {
                    Reference< script::XLibraryContainerPassword > xPasswd( xModLibContainer, UNO_QUERY );
                    if ( xPasswd.is() && xPasswd->isLibraryPasswordProtected( aOULibName ) && !xPasswd->isLibraryPasswordVerified( aOULibName ) )
                    {
                        bProtected = sal_True;
                    }
                }
            }

            if ( !bProtected )
            {
				pIDEShell = IDE_DLL()->GetShell();
				if ( !pIDEShell )
				{
                    SfxAllItemSet aArgs( SFX_APP()->GetPool() );
                    SfxRequest aRequest( SID_BASICIDE_APPEAR, SFX_CALLMODE_SYNCHRON, aArgs );
                    SFX_APP()->ExecuteSlot( aRequest );
					pIDEShell = IDE_DLL()->GetShell();
				}
            }
        }
	}

	if ( pIDEShell )
		nRet = pIDEShell->CallBasicErrorHdl( pBasic );
	else
        ErrorHandler::HandleError( StarBASIC::GetErrorCode() );

	return nRet;
}

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

SfxBindings* GetBindingsPtr()
{
    SfxBindings* pBindings = NULL;

    SfxViewFrame* pFrame = NULL;
    BasicIDEDLL* pIDEDLL = IDE_DLL();
    if ( pIDEDLL && pIDEDLL->GetShell() )
    {
        pFrame = pIDEDLL->GetShell()->GetViewFrame();
    }
    else
    {
        SfxViewFrame* pView = SfxViewFrame::GetFirst();
        while ( pView )
        {
            SfxObjectShell* pObjShell = pView->GetObjectShell();
            if ( pObjShell && pObjShell->ISA( BasicDocShell ) )
            {
                pFrame = pView;
                break;
            }
            pView = SfxViewFrame::GetNext( *pView );
        }
    }
    if ( pFrame != NULL )
        pBindings = &pFrame->GetBindings();

    return pBindings;
}

} //namespace BasicIDE

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