/**************************************************************
 *
 * 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_sc.hxx"
#ifdef _MSC_VER
#pragma optimize("",off)
#endif

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



// INCLUDE ---------------------------------------------------------

#include <sfx2/sfxsids.hrc>
#include <sfx2/app.hxx>
#include <svl/itemset.hxx>
#include <svl/stritem.hxx>
#include <sfx2/docfile.hxx>
#include <sfx2/docfilt.hxx>
#include <sfx2/fcontnr.hxx>
#include <sfx2/linkmgr.hxx>
#include <tools/urlobj.hxx>
#include <unotools/transliterationwrapper.hxx>

#include "tablink.hxx"

#include "scextopt.hxx"
#include "table.hxx"
#include "document.hxx"
#include "docsh.hxx"
#include "globstr.hrc"
#include "undoblk.hxx"
#include "undotab.hxx"
#include "global.hxx"
#include "hints.hxx"
#include "cell.hxx"
#include "dociter.hxx"
#include "formula/opcode.hxx"

struct TableLink_Impl
{
    ScDocShell* m_pDocSh;
    Window*     m_pOldParent;
    Link        m_aEndEditLink;

    TableLink_Impl() : m_pDocSh( NULL ), m_pOldParent( NULL ) {}
};

TYPEINIT1(ScTableLink, ::sfx2::SvBaseLink);

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

ScTableLink::ScTableLink(ScDocShell* pDocSh, const String& rFile,
							const String& rFilter, const String& rOpt,
							sal_uLong nRefresh ):
    ::sfx2::SvBaseLink(sfx2::LINKUPDATE_ONCALL,FORMAT_FILE),
	ScRefreshTimer( nRefresh ),
    pImpl( new TableLink_Impl ),
	aFileName(rFile),
	aFilterName(rFilter),
	aOptions(rOpt),
	bInCreate( sal_False ),
	bInEdit( sal_False ),
	bAddUndo( sal_True ),
	bDoPaint( sal_True )
{
    pImpl->m_pDocSh = pDocSh;
}

ScTableLink::ScTableLink(SfxObjectShell* pShell, const String& rFile,
							const String& rFilter, const String& rOpt,
							sal_uLong nRefresh ):
    ::sfx2::SvBaseLink(sfx2::LINKUPDATE_ONCALL,FORMAT_FILE),
	ScRefreshTimer( nRefresh ),
    pImpl( new TableLink_Impl ),
	aFileName(rFile),
	aFilterName(rFilter),
	aOptions(rOpt),
	bInCreate( sal_False ),
	bInEdit( sal_False ),
	bAddUndo( sal_True ),
	bDoPaint( sal_True )
{
    pImpl->m_pDocSh = static_cast< ScDocShell* >( pShell );
	SetRefreshHandler( LINK( this, ScTableLink, RefreshHdl ) );
    SetRefreshControl( pImpl->m_pDocSh->GetDocument()->GetRefreshTimerControlAddress() );
}

__EXPORT ScTableLink::~ScTableLink()
{
	// Verbindung aufheben

	StopRefreshTimer();
	String aEmpty;
    ScDocument* pDoc = pImpl->m_pDocSh->GetDocument();
	SCTAB nCount = pDoc->GetTableCount();
	for (SCTAB nTab=0; nTab<nCount; nTab++)
		if (pDoc->IsLinked(nTab) && pDoc->GetLinkDoc(nTab)==aFileName)
			pDoc->SetLink( nTab, SC_LINK_NONE, aEmpty, aEmpty, aEmpty, aEmpty, 0 );
    delete pImpl;
}

void __EXPORT ScTableLink::Edit( Window* pParent, const Link& rEndEditHdl )
{
	//	DefModalDialogParent setzen, weil evtl. aus der DocShell beim ConvertFrom
	//	ein Optionen-Dialog kommt...

    pImpl->m_aEndEditLink = rEndEditHdl;
    pImpl->m_pOldParent = Application::GetDefDialogParent();
	if (pParent)
		Application::SetDefDialogParent(pParent);

	bInEdit = sal_True;
    SvBaseLink::Edit( pParent, LINK( this, ScTableLink, TableEndEditHdl ) );
}

void __EXPORT ScTableLink::DataChanged( const String&,
										const ::com::sun::star::uno::Any& )
{
    sfx2::LinkManager* pLinkManager=pImpl->m_pDocSh->GetDocument()->GetLinkManager();
	if (pLinkManager!=NULL)
	{
		String aFile;
		String aFilter;
		pLinkManager->GetDisplayNames( this,0,&aFile,NULL,&aFilter);

		//	the file dialog returns the filter name with the application prefix
		//	-> remove prefix
		ScDocumentLoader::RemoveAppPrefix( aFilter );

		if (!bInCreate)
			Refresh( aFile, aFilter, NULL, GetRefreshDelay() );	// don't load twice
	}
}

void __EXPORT ScTableLink::Closed()
{
	// Verknuepfung loeschen: Undo
    ScDocument* pDoc = pImpl->m_pDocSh->GetDocument();
	sal_Bool bUndo (pDoc->IsUndoEnabled());

	if (bAddUndo && bUndo)
	{
        pImpl->m_pDocSh->GetUndoManager()->AddUndoAction(
                new ScUndoRemoveLink( pImpl->m_pDocSh, aFileName ) );

		bAddUndo = sal_False;	// nur einmal
	}

	// Verbindung wird im dtor aufgehoben

	SvBaseLink::Closed();
}

sal_Bool ScTableLink::IsUsed() const
{
    return pImpl->m_pDocSh->GetDocument()->HasLink( aFileName, aFilterName, aOptions );
}

sal_Bool ScTableLink::Refresh(const String& rNewFile, const String& rNewFilter,
							const String* pNewOptions, sal_uLong nNewRefresh )
{
	//	Dokument laden

	if (!rNewFile.Len() || !rNewFilter.Len())
		return sal_False;

    String aNewUrl( ScGlobal::GetAbsDocName( rNewFile, pImpl->m_pDocSh ) );
	sal_Bool bNewUrlName = (aNewUrl != aFileName);

    const SfxFilter* pFilter = pImpl->m_pDocSh->GetFactory().GetFilterContainer()->GetFilter4FilterName(rNewFilter);
	if (!pFilter)
		return sal_False;

    ScDocument* pDoc = pImpl->m_pDocSh->GetDocument();
	pDoc->SetInLinkUpdate( sal_True );

	sal_Bool bUndo(pDoc->IsUndoEnabled());

	//	wenn neuer Filter ausgewaehlt wurde, Optionen vergessen
	if ( rNewFilter != aFilterName )
		aOptions.Erase();
	if ( pNewOptions )					// Optionen hart angegeben?
		aOptions = *pNewOptions;

	//	ItemSet immer anlegen, damit die DocShell die Optionen setzen kann
	SfxItemSet* pSet = new SfxAllItemSet( SFX_APP()->GetPool() );
	if ( aOptions.Len() )
		pSet->Put( SfxStringItem( SID_FILE_FILTEROPTIONS, aOptions ) );

	SfxMedium* pMed = new SfxMedium(aNewUrl, STREAM_STD_READ, sal_False, pFilter, pSet);

	if ( bInEdit )								// only if using the edit dialog,
		pMed->UseInteractionHandler( sal_True );	// enable the filter options dialog

    // aRef->DoClose() will be called explicitly, but it is still more safe to use SfxObjectShellLock here
	ScDocShell* pSrcShell = new ScDocShell(SFX_CREATE_MODE_INTERNAL);
    SfxObjectShellLock aRef = pSrcShell;
	pSrcShell->DoLoad(pMed);

	// Optionen koennten gesetzt worden sein
	String aNewOpt = ScDocumentLoader::GetOptions(*pMed);
	if (!aNewOpt.Len())
		aNewOpt = aOptions;

	//	Undo...

	ScDocument* pUndoDoc = NULL;
	sal_Bool bFirst = sal_True;
	if (bAddUndo && bUndo)
		pUndoDoc = new ScDocument( SCDOCMODE_UNDO );

	//	Tabellen kopieren

    ScDocShellModificator aModificator( *pImpl->m_pDocSh );

	sal_Bool bNotFound = sal_False;
	ScDocument* pSrcDoc = pSrcShell->GetDocument();

	//	#74835# from text filters that don't set the table name,
	//	use the one table regardless of link table name
	sal_Bool bAutoTab = (pSrcDoc->GetTableCount() == 1) &&
					ScDocShell::HasAutomaticTableName( rNewFilter );

	SCTAB nCount = pDoc->GetTableCount();
	for (SCTAB nTab=0; nTab<nCount; nTab++)
	{
		sal_uInt8 nMode = pDoc->GetLinkMode(nTab);
		if (nMode && pDoc->GetLinkDoc(nTab)==aFileName)
		{
			String aTabName = pDoc->GetLinkTab(nTab);

			//	Undo

			if (bAddUndo && bUndo)
			{
				if (bFirst)
					pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_True, sal_True );
				else
					pUndoDoc->AddUndoTab( nTab, nTab, sal_True, sal_True );
				bFirst = sal_False;
				ScRange aRange(0,0,nTab,MAXCOL,MAXROW,nTab);
				pDoc->CopyToDocument(aRange, IDF_ALL, sal_False, pUndoDoc);
				pUndoDoc->TransferDrawPage( pDoc, nTab, nTab );
				pUndoDoc->SetLink( nTab, nMode, aFileName, aFilterName,
					aOptions, aTabName, GetRefreshDelay() );
				pUndoDoc->SetTabBgColor( nTab, pDoc->GetTabBgColor(nTab) );
			}

			//	Tabellenname einer ExtDocRef anpassen

			if ( bNewUrlName && nMode == SC_LINK_VALUE )
			{
				String aName;
				pDoc->GetName( nTab, aName );
                if ( ScGlobal::GetpTransliteration()->isEqual(
                        ScGlobal::GetDocTabName( aFileName, aTabName ), aName ) )
				{
					pDoc->RenameTab( nTab,
						ScGlobal::GetDocTabName( aNewUrl, aTabName ),
						sal_False, sal_True );	// kein RefUpdate, kein ValidTabName
				}
			}

			//	kopieren

			SCTAB nSrcTab = 0;
            bool bFound = false;
            /*  #i71497# check if external document is loaded successfully,
                otherwise we may find the empty default sheet "Sheet1" in
                pSrcDoc, even if the document does not exist. */
            if( pMed->GetError() == 0 )
            {
                // no sheet name -> use first sheet
                if ( aTabName.Len() && !bAutoTab )
                    bFound = pSrcDoc->GetTable( aTabName, nSrcTab );
                else
                    bFound = true;
            }

			if (bFound)
				pDoc->TransferTab( pSrcDoc, nSrcTab, nTab, sal_False,		// nicht neu einfuegen
										(nMode == SC_LINK_VALUE) );		// nur Werte?
			else
			{
				pDoc->DeleteAreaTab( 0,0,MAXCOL,MAXROW, nTab, IDF_ALL );

                bool bShowError = true;
                if ( nMode == SC_LINK_VALUE )
                {
                    //  #139464# Value link (used with external references in formulas):
                    //  Look for formulas that reference the sheet, and put errors in the referenced cells.

                    ScRangeList aErrorCells;        // cells on the linked sheets that need error values

                    ScCellIterator aCellIter( pDoc, 0,0,0, MAXCOL,MAXROW,MAXTAB );			// all sheets
                    ScBaseCell* pCell = aCellIter.GetFirst();
                    while (pCell)
                    {
                        if (pCell->GetCellType() == CELLTYPE_FORMULA)
                        {
                            ScFormulaCell* pFCell = static_cast<ScFormulaCell*>(pCell);

                            ScDetectiveRefIter aRefIter( pFCell );
                            ScRange aRefRange;
                            while ( aRefIter.GetNextRef( aRefRange ) )
                            {
                                if ( aRefRange.aStart.Tab() <= nTab && aRefRange.aEnd.Tab() >= nTab )
                                {
                                    // use first cell of range references (don't fill potentially large ranges)

                                    aErrorCells.Join( ScRange( aRefRange.aStart ) );
                                }
                            }
                        }
                        pCell = aCellIter.GetNext();
                    }

                    sal_uLong nRanges = aErrorCells.Count();
                    if ( nRanges )                          // found any?
                    {
                        ScTokenArray aTokenArr;
                        aTokenArr.AddOpCode( ocNotAvail );
                        aTokenArr.AddOpCode( ocOpen );
                        aTokenArr.AddOpCode( ocClose );
                        aTokenArr.AddOpCode( ocStop );

                        for (sal_uLong nPos=0; nPos<nRanges; nPos++)
                        {
                            const ScRange* pRange = aErrorCells.GetObject(nPos);
                            SCCOL nStartCol = pRange->aStart.Col();
                            SCROW nStartRow = pRange->aStart.Row();
                            SCCOL nEndCol = pRange->aEnd.Col();
                            SCROW nEndRow = pRange->aEnd.Row();
                            for (SCROW nRow=nStartRow; nRow<=nEndRow; nRow++)
                                for (SCCOL nCol=nStartCol; nCol<=nEndCol; nCol++)
                                {
                                    ScAddress aDestPos( nCol, nRow, nTab );
                                    ScFormulaCell* pNewCell = new ScFormulaCell( pDoc, aDestPos, &aTokenArr );
                                    pDoc->PutCell( aDestPos, pNewCell );
                                }
                        }

                        bShowError = false;
                    }
                    // if no references were found, insert error message (don't leave the sheet empty)
                }

                if ( bShowError )
                {
                    //  Normal link or no references: put error message on sheet.

                    pDoc->SetString( 0,0,nTab, ScGlobal::GetRscString(STR_LINKERROR) );
                    pDoc->SetString( 0,1,nTab, ScGlobal::GetRscString(STR_LINKERRORFILE) );
                    pDoc->SetString( 1,1,nTab, aNewUrl );
                    pDoc->SetString( 0,2,nTab, ScGlobal::GetRscString(STR_LINKERRORTAB) );
                    pDoc->SetString( 1,2,nTab, aTabName );
                }

				bNotFound = sal_True;
			}

			if ( bNewUrlName || rNewFilter != aFilterName ||
					aNewOpt != aOptions || pNewOptions ||
					nNewRefresh != GetRefreshDelay() )
				pDoc->SetLink( nTab, nMode, aNewUrl, rNewFilter, aNewOpt,
					aTabName, nNewRefresh );
		}
	}

	//	neue Einstellungen merken

	if ( bNewUrlName )
		aFileName = aNewUrl;
	if ( rNewFilter != aFilterName )
		aFilterName = rNewFilter;
	if ( aNewOpt != aOptions )
		aOptions = aNewOpt;

	//	aufraeumen

//	pSrcShell->DoClose();
	aRef->DoClose();

	//	Undo

	if (bAddUndo && bUndo)
        pImpl->m_pDocSh->GetUndoManager()->AddUndoAction(
                    new ScUndoRefreshLink( pImpl->m_pDocSh, pUndoDoc ) );

	//	Paint (koennen mehrere Tabellen sein)

	if (bDoPaint)
	{
        pImpl->m_pDocSh->PostPaint( ScRange(0,0,0,MAXCOL,MAXROW,MAXTAB),
								PAINT_GRID | PAINT_TOP | PAINT_LEFT | PAINT_EXTRAS );
		aModificator.SetDocumentModified();
	}

	if (bNotFound)
	{
		//!	Fehler ausgeben ?
	}

	pDoc->SetInLinkUpdate( sal_False );

	//	notify Uno objects (for XRefreshListener)
	//!	also notify Uno objects if file name was changed!
	ScLinkRefreshedHint aHint;
	aHint.SetSheetLink( aFileName );
	pDoc->BroadcastUno( aHint );

	return sal_True;
}

IMPL_LINK( ScTableLink, RefreshHdl, ScTableLink*, EMPTYARG )
{
    long nRes = Refresh( aFileName, aFilterName, NULL, GetRefreshDelay() ) != 0;
    return nRes;
}

IMPL_LINK( ScTableLink, TableEndEditHdl, ::sfx2::SvBaseLink*, pLink )
{
    if ( pImpl->m_aEndEditLink.IsSet() )
        pImpl->m_aEndEditLink.Call( pLink );
    bInEdit = sal_False;
    Application::SetDefDialogParent( pImpl->m_pOldParent );
    return 0;
}

// === ScDocumentLoader ==================================================

String ScDocumentLoader::GetOptions( SfxMedium& rMedium )		// static
{
	SfxItemSet* pSet = rMedium.GetItemSet();
	const SfxPoolItem* pItem;
	if ( pSet && SFX_ITEM_SET == pSet->GetItemState( SID_FILE_FILTEROPTIONS, sal_True, &pItem ) )
		return ((const SfxStringItem*)pItem)->GetValue();

	return EMPTY_STRING;
}

sal_Bool ScDocumentLoader::GetFilterName( const String& rFileName,
                                    String& rFilter, String& rOptions,
                                    sal_Bool bWithContent, sal_Bool bWithInteraction )  // static
{
	TypeId aScType = TYPE(ScDocShell);
	SfxObjectShell* pDocSh = SfxObjectShell::GetFirst( &aScType );
	while ( pDocSh )
	{
		if ( pDocSh->HasName() )
		{
			SfxMedium* pMed = pDocSh->GetMedium();
			if ( rFileName == pMed->GetName() )
			{
				rFilter = pMed->GetFilter()->GetFilterName();
				rOptions = GetOptions(*pMed);
				return sal_True;
			}
		}
		pDocSh = SfxObjectShell::GetNext( *pDocSh, &aScType );
	}

    INetURLObject aUrl( rFileName );
    INetProtocol eProt = aUrl.GetProtocol();
    if ( eProt == INET_PROT_NOT_VALID )         // invalid URL?
        return sal_False;                           // abort without creating a medium

	//	Filter-Detection

	const SfxFilter* pSfxFilter = NULL;
	SfxMedium* pMedium = new SfxMedium( rFileName, STREAM_STD_READ, sal_False );
	if ( pMedium->GetError() == ERRCODE_NONE )
	{
        if ( bWithInteraction )
            pMedium->UseInteractionHandler(sal_True);   // #i73992# no longer called from GuessFilter

		SfxFilterMatcher aMatcher( String::CreateFromAscii("scalc") );
        if( bWithContent )
            aMatcher.GuessFilter( *pMedium, &pSfxFilter );
        else
            aMatcher.GuessFilterIgnoringContent( *pMedium, &pSfxFilter );
	}

    sal_Bool bOK = sal_False;
	if ( pMedium->GetError() == ERRCODE_NONE )
    {
        if ( pSfxFilter )
            rFilter = pSfxFilter->GetFilterName();
        else
            rFilter = ScDocShell::GetOwnFilterName();		//	sonst Calc-Datei
        bOK = (rFilter.Len()>0);
    }

	delete pMedium;
    return bOK;
}

void ScDocumentLoader::RemoveAppPrefix( String& rFilterName )		// static
{
	String aAppPrefix = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM( STRING_SCAPP ));
	aAppPrefix.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ": " ));
	xub_StrLen nPreLen = aAppPrefix.Len();
	if ( rFilterName.Copy(0,nPreLen) == aAppPrefix )
		rFilterName.Erase(0,nPreLen);
}

ScDocumentLoader::ScDocumentLoader( const String& rFileName,
									String& rFilterName, String& rOptions,
									sal_uInt32 nRekCnt, sal_Bool bWithInteraction ) :
        pDocShell(0),
		pMedium(0)
{
	if ( !rFilterName.Len() )
        GetFilterName( rFileName, rFilterName, rOptions, sal_True, bWithInteraction );

	const SfxFilter* pFilter = ScDocShell::Factory().GetFilterContainer()->GetFilter4FilterName( rFilterName );

	//	ItemSet immer anlegen, damit die DocShell die Optionen setzen kann
	SfxItemSet* pSet = new SfxAllItemSet( SFX_APP()->GetPool() );
	if ( rOptions.Len() )
		pSet->Put( SfxStringItem( SID_FILE_FILTEROPTIONS, rOptions ) );

	pMedium = new SfxMedium( rFileName, STREAM_STD_READ, sal_False, pFilter, pSet );
	if ( pMedium->GetError() != ERRCODE_NONE )
		return ;

	if ( bWithInteraction )
		pMedium->UseInteractionHandler( sal_True );	// to enable the filter options dialog

    pDocShell = new ScDocShell( SFX_CREATE_MODE_INTERNAL );
    aRef = pDocShell;

    ScDocument* pDoc = pDocShell->GetDocument();
	if( pDoc )
	{
		ScExtDocOptions*	pExtDocOpt = pDoc->GetExtDocOptions();
		if( !pExtDocOpt )
		{
			pExtDocOpt = new ScExtDocOptions;
			pDoc->SetExtDocOptions( pExtDocOpt );
		}
        pExtDocOpt->GetDocSettings().mnLinkCnt = nRekCnt;
	}

    pDocShell->DoLoad( pMedium );

	String aNew = GetOptions(*pMedium);			// Optionen werden beim Laden per Dialog gesetzt
	if (aNew.Len() && aNew != rOptions)
		rOptions = aNew;
}

ScDocumentLoader::~ScDocumentLoader()
{
/*  if ( pDocShell )
        pDocShell->DoClose();
*/
	if ( aRef.Is() )
		aRef->DoClose();
	else if ( pMedium )
		delete pMedium;
}

void ScDocumentLoader::ReleaseDocRef()
{
	if ( aRef.Is() )
	{
		//	release reference without calling DoClose - caller must
		//	have another reference to the doc and call DoClose later

        pDocShell = NULL;
		pMedium = NULL;
		aRef.Clear();
	}
}

ScDocument* ScDocumentLoader::GetDocument()
{
    return pDocShell ? pDocShell->GetDocument() : 0;
}

sal_Bool ScDocumentLoader::IsError() const
{
    if ( pDocShell && pMedium )
		return pMedium->GetError() != ERRCODE_NONE;
	else
		return sal_True;
}

String ScDocumentLoader::GetTitle() const
{
    if ( pDocShell )
        return pDocShell->GetTitle();
	else
		return EMPTY_STRING;
}
