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

#undef SC_DLLIMPLEMENTATION



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

#include <sfx2/app.hxx>
#include <sfx2/docfile.hxx>
#include <sfx2/docfilt.hxx>
#include <sfx2/docinsert.hxx>
#include <sfx2/fcontnr.hxx>
#include <sfx2/filedlghelper.hxx>
#include <svtools/ehdl.hxx>
#include <svtools/sfxecode.hxx>
#include <vcl/waitobj.hxx>

#include "linkarea.hxx"
#include "linkarea.hrc"
#include "scresid.hxx"
#include "sc.hrc"
#include "rangeutl.hxx"
#include "docsh.hxx"
#include "tablink.hxx"

//==================================================================

ScLinkedAreaDlg::ScLinkedAreaDlg( Window* pParent ) :
	ModalDialog ( pParent, ScResId( RID_SCDLG_LINKAREA ) ),
	//
	aFlLocation	( this, ScResId( FL_LOCATION ) ),
	aCbUrl		( this, ScResId( CB_URL ) ),
	aBtnBrowse	( this, ScResId( BTN_BROWSE ) ),
	aTxtHint	( this, ScResId( FT_HINT ) ),
	aFtRanges	( this, ScResId( FT_RANGES ) ),
	aLbRanges	( this, ScResId( LB_RANGES ) ),
	aBtnReload	( this, ScResId( BTN_RELOAD ) ),
	aNfDelay	( this, ScResId( NF_DELAY ) ),
	aFtSeconds	( this, ScResId( FT_SECONDS ) ),
	aBtnOk		( this, ScResId( BTN_OK ) ),
	aBtnCancel	( this, ScResId( BTN_CANCEL ) ),
	aBtnHelp	( this, ScResId( BTN_HELP ) ),
	//
    pSourceShell( NULL ),
    pDocInserter( NULL )

{
	FreeResource();

	aCbUrl.SetHelpId( HID_SCDLG_LINKAREAURL );	// SvtURLBox ctor always sets SID_OPENURL
	aCbUrl.SetSelectHdl( LINK( this, ScLinkedAreaDlg, FileHdl ) );
	aBtnBrowse.SetClickHdl( LINK( this, ScLinkedAreaDlg, BrowseHdl ) );
	aLbRanges.SetSelectHdl( LINK( this, ScLinkedAreaDlg, RangeHdl ) );
	aBtnReload.SetClickHdl( LINK( this, ScLinkedAreaDlg, ReloadHdl ) );
	UpdateEnable();

	aNfDelay.SetAccessibleName(aBtnReload.GetText());
	aNfDelay.SetAccessibleRelationLabeledBy(&aBtnReload);
}

ScLinkedAreaDlg::~ScLinkedAreaDlg()
{
	// pSourceShell is deleted by aSourceRef
}

short ScLinkedAreaDlg::Execute()
{
	// set parent for file dialog or filter options

	Window*	pOldDefParent = Application::GetDefDialogParent();
	Application::SetDefDialogParent( this );

	short nRet = ModalDialog::Execute();

	Application::SetDefDialogParent( pOldDefParent );

	return nRet;
}

#define FILTERNAME_HTML  "HTML (StarCalc)"
#define FILTERNAME_QUERY "calc_HTML_WebQuery"

IMPL_LINK( ScLinkedAreaDlg, BrowseHdl, PushButton*, EMPTYARG )
{
    if ( !pDocInserter )
        pDocInserter = new sfx2::DocumentInserter(
            0, String::CreateFromAscii( ScDocShell::Factory().GetShortName() ) );
    pDocInserter->StartExecuteModal( LINK( this, ScLinkedAreaDlg, DialogClosedHdl ) );
    return 0;
}

IMPL_LINK( ScLinkedAreaDlg, FileHdl, ComboBox*, EMPTYARG )
{
	String aEntered = aCbUrl.GetURL();
	if (pSourceShell)
	{
		SfxMedium* pMed = pSourceShell->GetMedium();
		if ( pMed->GetName() == aEntered )
		{
			//	already loaded - nothing to do
			return 0;
		}
	}

	String aFilter;
	String aOptions;
	//	get filter name by looking at the file content (bWithContent = sal_True)
    // Break operation if any error occurred inside.
    if (!ScDocumentLoader::GetFilterName( aEntered, aFilter, aOptions, sal_True, sal_True ))
        return 0;

    // #i53241# replace HTML filter with DataQuery filter
    if( aFilter.EqualsAscii( FILTERNAME_HTML ) )
        aFilter.AssignAscii( FILTERNAME_QUERY );

	LoadDocument( aEntered, aFilter, aOptions );

	UpdateSourceRanges();
	UpdateEnable();
	return 0;
}

void ScLinkedAreaDlg::LoadDocument( const String& rFile, const String& rFilter, const String& rOptions )
{
	if ( pSourceShell )
	{
		//	unload old document
		pSourceShell->DoClose();
		pSourceShell = NULL;
		aSourceRef.Clear();
	}

	if ( rFile.Len() )
	{
		WaitObject aWait( this );

		String aNewFilter = rFilter;
		String aNewOptions = rOptions;

		SfxErrorContext aEc( ERRCTX_SFX_OPENDOC, rFile );

		ScDocumentLoader aLoader( rFile, aNewFilter, aNewOptions, 0, sal_True );	// with interaction
		pSourceShell = aLoader.GetDocShell();
		if ( pSourceShell )
		{
			sal_uLong nErr = pSourceShell->GetErrorCode();
			if (nErr)
				ErrorHandler::HandleError( nErr );		// including warnings

			aSourceRef = pSourceShell;
			aLoader.ReleaseDocRef();	// don't call DoClose in DocLoader dtor
		}
	}
}

void ScLinkedAreaDlg::InitFromOldLink( const String& rFile, const String& rFilter,
										const String& rOptions, const String& rSource,
										sal_uLong nRefresh )
{
	LoadDocument( rFile, rFilter, rOptions );
	if (pSourceShell)
	{
		SfxMedium* pMed = pSourceShell->GetMedium();
		aCbUrl.SetText( pMed->GetName() );
	}
	else
		aCbUrl.SetText( EMPTY_STRING );

	UpdateSourceRanges();

	xub_StrLen nRangeCount = rSource.GetTokenCount();
	for ( xub_StrLen i=0; i<nRangeCount; i++ )
	{
		String aRange = rSource.GetToken(i);
		aLbRanges.SelectEntry( aRange );
	}

	sal_Bool bDoRefresh = ( nRefresh != 0 );
	aBtnReload.Check( bDoRefresh );
	if (bDoRefresh)
		aNfDelay.SetValue( nRefresh );

	UpdateEnable();
}

IMPL_LINK( ScLinkedAreaDlg, RangeHdl, MultiListBox*, EMPTYARG )
{
	UpdateEnable();
	return 0;
}

IMPL_LINK( ScLinkedAreaDlg, ReloadHdl, CheckBox*, EMPTYARG )
{
    UpdateEnable();
    return 0;
}

IMPL_LINK( ScLinkedAreaDlg, DialogClosedHdl, sfx2::FileDialogHelper*, _pFileDlg )
{
    if ( _pFileDlg->GetError() != ERRCODE_NONE )
        return 0;

    SfxMedium* pMed = pDocInserter->CreateMedium();
    if ( pMed )
    {
        WaitObject aWait( this );

        // #92296# replace HTML filter with DataQuery filter
        const String aHTMLFilterName( RTL_CONSTASCII_USTRINGPARAM( FILTERNAME_HTML ) );
        const String aWebQFilterName( RTL_CONSTASCII_USTRINGPARAM( FILTERNAME_QUERY ) );

        const SfxFilter* pFilter = pMed->GetFilter();
        if( pFilter && (pFilter->GetFilterName() == aHTMLFilterName) )
        {
            const SfxFilter* pNewFilter =
                ScDocShell::Factory().GetFilterContainer()->GetFilter4FilterName( aWebQFilterName );
            if( pNewFilter )
                pMed->SetFilter( pNewFilter );
        }

        //  ERRCTX_SFX_OPENDOC -> "Fehler beim Laden des Dokumentes"
        SfxErrorContext aEc( ERRCTX_SFX_OPENDOC, pMed->GetName() );

        if (pSourceShell)
            pSourceShell->DoClose();        // deleted when assigning aSourceRef

        pMed->UseInteractionHandler( sal_True );    // to enable the filter options dialog

        pSourceShell = new ScDocShell;
        aSourceRef = pSourceShell;
        pSourceShell->DoLoad( pMed );

        sal_uLong nErr = pSourceShell->GetErrorCode();
        if (nErr)
            ErrorHandler::HandleError( nErr );              // including warnings

        if ( !pSourceShell->GetError() )                    // only errors
        {
            //aCbUrl.SetText( pSourceShell->GetTitle( SFX_TITLE_FULLNAME ) );
            aCbUrl.SetText( pMed->GetName() );
        }
        else
        {
            pSourceShell->DoClose();
            pSourceShell = NULL;
            aSourceRef.Clear();

            aCbUrl.SetText( EMPTY_STRING );
        }
    }

    UpdateSourceRanges();
    UpdateEnable();
    return 0;
}

#undef FILTERNAME_HTML
#undef FILTERNAME_QUERY

void ScLinkedAreaDlg::UpdateSourceRanges()
{
	aLbRanges.SetUpdateMode( sal_False );

	aLbRanges.Clear();
	if ( pSourceShell )
	{
		ScAreaNameIterator aIter( pSourceShell->GetDocument() );
		ScRange aDummy;
		String aName;
		while ( aIter.Next( aName, aDummy ) )
			aLbRanges.InsertEntry( aName );
	}

	aLbRanges.SetUpdateMode( sal_True );

	if ( aLbRanges.GetEntryCount() == 1 )
		aLbRanges.SelectEntryPos(0);
}

void ScLinkedAreaDlg::UpdateEnable()
{
	sal_Bool bEnable = ( pSourceShell && aLbRanges.GetSelectEntryCount() );
	aBtnOk.Enable( bEnable );

	sal_Bool bReload = aBtnReload.IsChecked();
	aNfDelay.Enable( bReload );
	aFtSeconds.Enable( bReload );
}

String ScLinkedAreaDlg::GetURL()
{
	if (pSourceShell)
	{
		SfxMedium* pMed = pSourceShell->GetMedium();
		return pMed->GetName();
	}
	return EMPTY_STRING;
}

String ScLinkedAreaDlg::GetFilter()
{
	if (pSourceShell)
	{
		SfxMedium* pMed = pSourceShell->GetMedium();
		return pMed->GetFilter()->GetFilterName();
	}
	return EMPTY_STRING;
}

String ScLinkedAreaDlg::GetOptions()
{
	if (pSourceShell)
	{
		SfxMedium* pMed = pSourceShell->GetMedium();
		return ScDocumentLoader::GetOptions( *pMed );
	}
	return EMPTY_STRING;
}

String ScLinkedAreaDlg::GetSource()
{
	String aSource;
	sal_uInt16 nCount = aLbRanges.GetSelectEntryCount();
	for (sal_uInt16 i=0; i<nCount; i++)
	{
		if (i > 0)
			aSource.Append( (sal_Unicode) ';' );
		aSource.Append( aLbRanges.GetSelectEntry( i ) );
	}
	return aSource;
}

sal_uLong ScLinkedAreaDlg::GetRefresh()
{
	if ( aBtnReload.IsChecked() )
        return sal::static_int_cast<sal_uLong>( aNfDelay.GetValue() );
	else
		return 0;	// disabled
}

