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

#include "dbaccess_helpid.hrc"
#include "dbmm_module.hxx"
#include "dbmm_global.hrc"
#include "macromigration.hrc"
#include "macromigrationpages.hxx"
#include "macromigrationdialog.hxx"

/** === begin UNO includes === **/
#include <com/sun/star/frame/XModel.hpp>
/** === end UNO includes === **/

#include <tools/urlobj.hxx>
#include <tools/diagnose_ex.h>
#include <vcl/metric.hxx>

//........................................................................
namespace dbmm
{
//........................................................................

	/** === begin UNO using === **/
	using ::com::sun::star::uno::Reference;
	using ::com::sun::star::uno::XInterface;
	using ::com::sun::star::uno::UNO_QUERY;
	using ::com::sun::star::uno::UNO_QUERY_THROW;
	using ::com::sun::star::uno::UNO_SET_THROW;
	using ::com::sun::star::uno::Exception;
	using ::com::sun::star::uno::RuntimeException;
	using ::com::sun::star::uno::Any;
	using ::com::sun::star::uno::makeAny;
    using ::com::sun::star::uno::Sequence;
    using ::com::sun::star::frame::XModel;
	/** === end UNO using === **/

	//====================================================================
	//= MacroMigrationPage
	//====================================================================
	//--------------------------------------------------------------------
    MacroMigrationPage::MacroMigrationPage( MacroMigrationDialog& _rParentDialog, const ResId& _rRes )
        :MacroMigrationPage_Base( &_rParentDialog, _rRes )
        ,m_aHeader( this, MacroMigrationResId( FT_HEADER ) )
    {
        Font aFont( m_aHeader.GetFont() );
        aFont.SetWeight( WEIGHT_BOLD );
        m_aHeader.SetFont( aFont );
    }

    //--------------------------------------------------------------------
    MacroMigrationPage::~MacroMigrationPage()
    {
    }

    //--------------------------------------------------------------------
    const MacroMigrationDialog& MacroMigrationPage::getDialog() const
    {
        return *dynamic_cast< const MacroMigrationDialog* >( GetParent() );
    }

    //--------------------------------------------------------------------
    MacroMigrationDialog& MacroMigrationPage::getDialog()
    {
        return *dynamic_cast< MacroMigrationDialog* >( GetParent() );
    }

	//====================================================================
	//= PreparationPage
	//====================================================================
	//--------------------------------------------------------------------
    PreparationPage::PreparationPage( MacroMigrationDialog& _rParentDialog )
        :MacroMigrationPage( _rParentDialog, MacroMigrationResId( TP_PREPARE ) )
        ,m_aIntroduction ( this, MacroMigrationResId( FT_INTRODUCTION    ) )
        ,m_aCloseDocError( this, MacroMigrationResId( FT_CLOSE_DOC_ERROR ) )
    {
        FreeResource();
    }

	//--------------------------------------------------------------------
    void PreparationPage::showCloseDocsError( bool _bShow )
    {
        m_aCloseDocError.Show( _bShow );
    }

    //--------------------------------------------------------------------
    TabPage* PreparationPage::Create( ::svt::RoadmapWizard& _rParentDialog )
    {
        return new PreparationPage( dynamic_cast< MacroMigrationDialog& >( _rParentDialog ) );
    }

	//====================================================================
	//= SaveDBDocPage
	//====================================================================
	//--------------------------------------------------------------------
    SaveDBDocPage::SaveDBDocPage( MacroMigrationDialog& _rParentDialog )
        :MacroMigrationPage( _rParentDialog, MacroMigrationResId( TP_SAVE_DBDOC_AS ) )
        ,m_aExplanation         ( this, MacroMigrationResId( FT_EXPLANATION             ) )
        ,m_aSaveAsLabel         ( this, MacroMigrationResId( FT_SAVE_AS_LABEL           ) )
        ,m_aSaveAsLocation      ( this, MacroMigrationResId( ED_SAVE_AS_LOCATION        ) )
        ,m_aBrowseSaveAsLocation( this, MacroMigrationResId( PB_BROWSE_SAVE_AS_LOCATION ) )
        ,m_aStartMigration      ( this, MacroMigrationResId( FT_START_MIGRATION         ) )
        ,m_aLocationController( _rParentDialog.getComponentContext(), m_aSaveAsLocation, m_aBrowseSaveAsLocation )
    {
        FreeResource();

        m_aSaveAsLocation.SetModifyHdl( LINK( this, SaveDBDocPage, OnLocationModified ) );
        m_aSaveAsLocation.SetDropDownLineCount( 20 );

        m_aSaveAsLocation.SetHelpId( HID_MACRO_MIGRATION_BACKUP_LOCATION );

        impl_updateLocationDependentItems();
    }

	//--------------------------------------------------------------------
    void SaveDBDocPage::impl_updateLocationDependentItems()
    {
        updateDialogTravelUI();
        m_aStartMigration.Show( m_aSaveAsLocation.GetText().Len() > 0 );
    }

	//--------------------------------------------------------------------
    IMPL_LINK( SaveDBDocPage, OnLocationModified, Edit*, /**/ )
    {
        impl_updateLocationDependentItems();
        return 0L;
    }

	//--------------------------------------------------------------------
    void SaveDBDocPage::initializePage()
    {
        OWizardPage::initializePage();

        try
        {
            // get the document's current URL
            Reference< XModel > xDocument( getDialog().getDocument(), UNO_QUERY_THROW );
            INetURLObject aURLParser( xDocument->getURL() );
            OSL_ENSURE( aURLParser.GetProtocol() != INET_PROT_NOT_VALID, "SaveDBDocPage::initializePage: illegal document URL!" );

            ::rtl::OUStringBuffer aBaseName( aURLParser.getBase() );
            aBaseName.appendAscii( ".backup" );
            aURLParser.setBase( aBaseName.makeStringAndClear() );

            m_aLocationController.setURL( aURLParser.GetMainURL( INetURLObject::NO_DECODE ) );
            impl_updateLocationDependentItems();
        }
        catch( const Exception& )
        {
        	DBG_UNHANDLED_EXCEPTION();
        }
    }

	//--------------------------------------------------------------------
    bool SaveDBDocPage::canAdvance() const
    {
        if ( !MacroMigrationPage::canAdvance() )
            return false;

        return m_aSaveAsLocation.GetText().Len() > 0;
    }

	//--------------------------------------------------------------------
    sal_Bool SaveDBDocPage::commitPage( ::svt::WizardTypes::CommitPageReason _eReason )
    {
        if ( !MacroMigrationPage::commitPage( _eReason ) )
            return sal_False;

        if ( ::svt::WizardTypes::eTravelBackward == _eReason )
            return sal_True;

        if ( !m_aLocationController.prepareCommit() )
            return sal_False;

        return sal_True;
    }

	//--------------------------------------------------------------------
    TabPage* SaveDBDocPage::Create( ::svt::RoadmapWizard& _rParentDialog )
    {
        return new SaveDBDocPage( dynamic_cast< MacroMigrationDialog& >( _rParentDialog ) );
    }

	//====================================================================
	//= ProgressPage
	//====================================================================
	//--------------------------------------------------------------------
    ProgressPage::ProgressPage( MacroMigrationDialog& _rParentDialog )
        :MacroMigrationPage( _rParentDialog, MacroMigrationResId( TP_MIGRATE ) )
        ,m_aObjectCount             ( this, MacroMigrationResId( FT_OBJECT_COUNT            ) )
        ,m_aCurrentObjectLabel      ( this, MacroMigrationResId( FT_CURRENT_OBJECT_LABEL    ) )
        ,m_aCurrentObject           ( this, MacroMigrationResId( FT_CURRENT_OBJECT          ) )
        ,m_aCurrentActionLabel      ( this, MacroMigrationResId( FT_CURRENT_PROGRESS_LABEL  ) )
        ,m_aCurrentAction           ( this, MacroMigrationResId( FT_CURRENT_PROGRESS        ) )
        ,m_aCurrentProgress         ( this, MacroMigrationResId( WND_CURRENT_PROGRESS       ) )
        ,m_aAllProgressLabel        ( this, MacroMigrationResId( FT_ALL_PROGRESS_LABEL      ) )
        ,m_aAllProgressText         ( this, MacroMigrationResId( FT_OBJECT_COUNT_PROGRESS   ) )
        ,m_aAllProgress             ( this, MacroMigrationResId( WND_ALL_PROGRESS           ) )
        ,m_aMigrationDone           ( this, MacroMigrationResId( FT_MIGRATION_DONE          ) )
    {
        FreeResource();
    }

	//--------------------------------------------------------------------
    TabPage* ProgressPage::Create( ::svt::RoadmapWizard& _rParentDialog )
    {
        return new ProgressPage( dynamic_cast< MacroMigrationDialog& >( _rParentDialog ) );
    }

	//--------------------------------------------------------------------
    void ProgressPage::setDocumentCounts( const sal_Int32 _nForms, const sal_Int32 _nReports )
    {
        String sText( m_aObjectCount.GetText() );
        sText.SearchAndReplaceAscii( "$forms$", String::CreateFromInt32( _nForms ) );
        sText.SearchAndReplaceAscii( "$reports$", String::CreateFromInt32( _nReports ) );
        m_aObjectCount.SetText( sText );
    }

	//--------------------------------------------------------------------
    void ProgressPage::onFinishedSuccessfully()
    {
        m_aMigrationDone.Show();
    }

	//--------------------------------------------------------------------
    void ProgressPage::startObject( const ::rtl::OUString& _rObjectName, const ::rtl::OUString& _rCurrentAction, const sal_uInt32 _nRange )
    {
        m_aCurrentObject.SetText( _rObjectName );
        m_aCurrentAction.SetText( _rCurrentAction );
        m_aCurrentProgress.SetRange( _nRange );
        m_aCurrentProgress.SetValue( (sal_uInt32)0 );

        // since this is currently called from the main thread, which does not have the chance
        // to re-schedule, we need to explicitly update the display
        m_aCurrentObject.Update();
        m_aCurrentAction.Update();
        Update();
    }

	//--------------------------------------------------------------------
    void ProgressPage::setObjectProgressText( const ::rtl::OUString& _rText )
    {
        m_aCurrentAction.SetText( _rText );
        m_aCurrentAction.Update();
        Update();
    }

	//--------------------------------------------------------------------
    void ProgressPage::setObjectProgressValue( const sal_uInt32 _nValue )
    {
        m_aCurrentProgress.SetValue( _nValue );
        Update();
    }

	//--------------------------------------------------------------------
    void ProgressPage::endObject()
    {
        m_aCurrentAction.SetText( String() );
        m_aCurrentProgress.SetValue( m_aCurrentProgress.GetRange() );
        m_aCurrentAction.Update();
        Update();
    }

	//--------------------------------------------------------------------
    void ProgressPage::start( const sal_uInt32 _nOverallRange )
    {
        m_aAllProgress.SetRange( _nOverallRange );
        Update();
    }

	//--------------------------------------------------------------------
    void ProgressPage::setOverallProgressText( const ::rtl::OUString& _rText )
    {
        m_aAllProgressText.SetText( _rText );
        Update();
    }

	//--------------------------------------------------------------------
    void ProgressPage::setOverallProgressValue( const sal_uInt32 _nValue )
    {
        m_aAllProgress.SetValue( _nValue );
        Update();
    }

	//====================================================================
	//= ResultPage
	//====================================================================
	//--------------------------------------------------------------------
    ResultPage::ResultPage( MacroMigrationDialog& _rParentDialog )
        :MacroMigrationPage( _rParentDialog, MacroMigrationResId( TP_SUMMARY ) )
        ,m_aChangesLabel( this, MacroMigrationResId( FT_CHANGES_LABEL ) )
        ,m_aChanges     ( this, MacroMigrationResId( ED_CHANGES       ) )
        ,m_aSuccessful  (       MacroMigrationResId( STR_SUCCESSFUL   ) )
        ,m_aUnsuccessful(       MacroMigrationResId( STR_UNSUCCESSFUL ) )
    {
        FreeResource();
    }

	//--------------------------------------------------------------------
    TabPage* ResultPage::Create( ::svt::RoadmapWizard& _rParentDialog )
    {
        return new ResultPage( dynamic_cast< MacroMigrationDialog& >( _rParentDialog ) );
    }

	//--------------------------------------------------------------------
    void ResultPage::displayMigrationLog( const bool _bSuccessful, const String& _rSummary )
    {
        m_aChangesLabel.SetText( _bSuccessful ? m_aSuccessful : m_aUnsuccessful );
        m_aChanges.SetText( _rSummary );

        // resize m_aChangesLabel and m_aChances as needed for the label text to fit 
        Rectangle aOriginalLabelSize( m_aChangesLabel.GetPosPixel(), m_aChangesLabel.GetSizePixel() );
        // assume 3 lines, at most
        Rectangle aNewLabelSize( aOriginalLabelSize );
        aNewLabelSize.Bottom() = aNewLabelSize.Top() + m_aChangesLabel.LogicToPixel( Size( 0, 3*8 ), MAP_APPFONT ).Height();
        TextRectInfo aInfo;
        aNewLabelSize = m_aChangesLabel.GetTextRect( aNewLabelSize, m_aChangesLabel.GetText(), TEXT_DRAW_MULTILINE | TEXT_DRAW_WORDBREAK, &aInfo );
        aNewLabelSize.Bottom() = aNewLabelSize.Top() + m_aChangesLabel.LogicToPixel( Size( 0, aInfo.GetLineCount() * 8 ), MAP_APPFONT ).Height();

        m_aChangesLabel.SetSizePixel( aNewLabelSize.GetSize() );

        long nChangesDiff = aNewLabelSize.GetHeight() - aOriginalLabelSize.GetHeight();
        Size aChangesSize( m_aChanges.GetSizePixel() );
        aChangesSize.Height() -= nChangesDiff;
        m_aChanges.SetSizePixel( aChangesSize );

        Point aChangesPos( m_aChanges.GetPosPixel() );
        aChangesPos.Y() += nChangesDiff;
        m_aChanges.SetPosPixel( aChangesPos );
    }

//........................................................................
} // namespace dbmm
//........................................................................
