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

#include "svx/databaselocationinput.hxx"
#include "svx/dialmgr.hxx"

#include "svx/fmresids.hrc"

/** === begin UNO includes === **/
#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
/** === end UNO includes === **/

#include <comphelper/componentcontext.hxx>
#include <comphelper/namedvaluecollection.hxx>
#include <rtl/ustrbuf.hxx>
#include <sfx2/filedlghelper.hxx>
#include <svtools/urlcontrol.hxx>
#include <svl/filenotation.hxx>
#include <tools/diagnose_ex.h>
#include <unotools/confignode.hxx>
#include <unotools/ucbhelper.hxx>
#include <vcl/button.hxx>
#include <vcl/msgbox.hxx>

//........................................................................
namespace svx
{
//........................................................................

	/** === begin UNO using === **/
    using ::com::sun::star::uno::Sequence;
    using ::com::sun::star::uno::Reference;
    using ::com::sun::star::container::XNameAccess;
    using ::com::sun::star::uno::UNO_QUERY_THROW;
    using ::com::sun::star::uno::Exception;
	/** === end UNO using === **/
    namespace TemplateDescription = ::com::sun::star::ui::dialogs::TemplateDescription;

	//====================================================================
	//= DatabaseLocationInputController_Impl
	//====================================================================
    class DatabaseLocationInputController_Impl
    {
    public:
        DatabaseLocationInputController_Impl(
            const ::comphelper::ComponentContext&   _rContext,
            ::svt::OFileURLControl&                 _rLocationInput,
            PushButton&                             _rBrowseButton
        );
        ~DatabaseLocationInputController_Impl();

        bool    prepareCommit();
        void    setURL( const String& _rURL );
        String  getURL() const;

    private:
        void    impl_initFilterProperties_nothrow();
        void    impl_onBrowseButtonClicked();
        void    impl_onLocationModified();
        String  impl_getCurrentURL() const;

        DECL_LINK( OnControlAction, VclWindowEvent* );

    private:
        const ::comphelper::ComponentContext    m_aContext;
        ::svt::OFileURLControl&                 m_rLocationInput;
        PushButton&                             m_rBrowseButton;
        Sequence< ::rtl::OUString >             m_aFilterExtensions;
        ::rtl::OUString                         m_sFilterUIName;
        bool                                    m_bNeedExistenceCheck;
    };

	//--------------------------------------------------------------------
    DatabaseLocationInputController_Impl::DatabaseLocationInputController_Impl( const ::comphelper::ComponentContext& _rContext,
            ::svt::OFileURLControl& _rLocationInput, PushButton& _rBrowseButton )
        :m_aContext( _rContext )
        ,m_rLocationInput( _rLocationInput )
        ,m_rBrowseButton( _rBrowseButton )
        ,m_aFilterExtensions()
        ,m_sFilterUIName()
        ,m_bNeedExistenceCheck( true )
    {
        impl_initFilterProperties_nothrow();

        // forward the allowed extensions to the input control
        ::rtl::OUStringBuffer aExtensionList;
        for (   const ::rtl::OUString* pExtension = m_aFilterExtensions.getConstArray();
                pExtension != m_aFilterExtensions.getConstArray() + m_aFilterExtensions.getLength();
                ++pExtension
            )
        {
            aExtensionList.append( *pExtension );
            aExtensionList.append( (sal_Unicode)';' );
        }
        m_rLocationInput.SetFilter( aExtensionList.makeStringAndClear() );

        m_rBrowseButton.AddEventListener( LINK( this, DatabaseLocationInputController_Impl, OnControlAction ) );
        m_rLocationInput.AddEventListener( LINK( this, DatabaseLocationInputController_Impl, OnControlAction ) );
    }

    //--------------------------------------------------------------------
    DatabaseLocationInputController_Impl::~DatabaseLocationInputController_Impl()
    {
        m_rBrowseButton.RemoveEventListener( LINK( this, DatabaseLocationInputController_Impl, OnControlAction ) );
        m_rLocationInput.RemoveEventListener( LINK( this, DatabaseLocationInputController_Impl, OnControlAction ) );
    }

	//--------------------------------------------------------------------
    bool DatabaseLocationInputController_Impl::prepareCommit()
    {
		::rtl::OUString sURL( impl_getCurrentURL() );
        if ( !sURL.getLength() )
            return false;

        // check if the name exists
		if ( m_bNeedExistenceCheck )
		{
			if ( ::utl::UCBContentHelper::Exists( sURL ) )
			{
				QueryBox aBox( m_rLocationInput.GetSystemWindow(), WB_YES_NO, SVX_RES( RID_STR_ALREADYEXISTOVERWRITE ) );
				if ( aBox.Execute() != RET_YES )
					return false;
			}
		}

        return true;
    }

	//--------------------------------------------------------------------
    void DatabaseLocationInputController_Impl::setURL( const String& _rURL )
    {
        ::svt::OFileNotation aTransformer( _rURL );
        m_rLocationInput.SetText( aTransformer.get( ::svt::OFileNotation::N_SYSTEM ) );
    }

	//--------------------------------------------------------------------
    String DatabaseLocationInputController_Impl::getURL() const
    {
        return impl_getCurrentURL();
    }

	//--------------------------------------------------------------------
    void DatabaseLocationInputController_Impl::impl_initFilterProperties_nothrow()
    {
        try
        {
            // get the name of the default filter for database documents
            ::utl::OConfigurationTreeRoot aConfig(
                ::utl::OConfigurationTreeRoot::createWithServiceFactory(
                    m_aContext.getLegacyServiceFactory(),
                    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Setup/Office/Factories/com.sun.star.sdb.OfficeDatabaseDocument" ) )
            ) );
            ::rtl::OUString sDatabaseFilter;
            OSL_VERIFY( aConfig.getNodeValue( "ooSetupFactoryActualFilter" ) >>= sDatabaseFilter );

            // get the type this filter is responsible for
            Reference< XNameAccess > xFilterFactory(
                m_aContext.createComponent( "com.sun.star.document.FilterFactory" ),
                UNO_QUERY_THROW );
            ::comphelper::NamedValueCollection aFilterProperties( xFilterFactory->getByName( sDatabaseFilter ) );
            ::rtl::OUString sDocumentType = aFilterProperties.getOrDefault( "Type", ::rtl::OUString() );

            // get the extension(s) for this type
            Reference< XNameAccess > xTypeDetection(
                m_aContext.createComponent( "com.sun.star.document.TypeDetection" ),
                UNO_QUERY_THROW );

            ::comphelper::NamedValueCollection aTypeProperties( xTypeDetection->getByName( sDocumentType ) );
            m_aFilterExtensions = aTypeProperties.getOrDefault( "Extensions", m_aFilterExtensions );
            m_sFilterUIName = aTypeProperties.getOrDefault( "UIName", m_sFilterUIName );
        }
        catch( const Exception& )
        {
        	DBG_UNHANDLED_EXCEPTION();
        }

        // ensure we have at least one extension
        OSL_ENSURE( m_aFilterExtensions.getLength(),
            "DatabaseLocationInputController_Impl::impl_initFilterProperties_nothrow: unable to determine the file extension(s)!" );
        if ( m_aFilterExtensions.getLength() == 0 )
        {
            m_aFilterExtensions.realloc(1);
            m_aFilterExtensions[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "*.odb" ) );
        }
    }

    // -----------------------------------------------------------------------------
    IMPL_LINK( DatabaseLocationInputController_Impl, OnControlAction, VclWindowEvent*, _pEvent )
    {
        if  (   ( _pEvent->GetWindow() == &m_rBrowseButton )
            &&  ( _pEvent->GetId() == VCLEVENT_BUTTON_CLICK )
            )
        {
            impl_onBrowseButtonClicked();
        }

        if  (   ( _pEvent->GetWindow() == &m_rLocationInput )
            &&  ( _pEvent->GetId() == VCLEVENT_EDIT_MODIFY )
            )
        {
            impl_onLocationModified();
        }

        return 0L;
    }

    // -----------------------------------------------------------------------------
    String DatabaseLocationInputController_Impl::impl_getCurrentURL() const
    {
        String sCurrentFile( m_rLocationInput.GetText() );
        if ( sCurrentFile.Len() )
        {
            ::svt::OFileNotation aCurrentFile( sCurrentFile );
            sCurrentFile = aCurrentFile.get( ::svt::OFileNotation::N_URL );
        }
        return sCurrentFile;
    }

    // -----------------------------------------------------------------------------
    void DatabaseLocationInputController_Impl::impl_onBrowseButtonClicked()
    {
        ::sfx2::FileDialogHelper aFileDlg(
            TemplateDescription::FILESAVE_AUTOEXTENSION,
            WB_STDMODAL | WB_SAVEAS,
            m_rLocationInput.GetSystemWindow()
        );
        aFileDlg.SetDisplayDirectory( impl_getCurrentURL() );

        aFileDlg.AddFilter( m_sFilterUIName, ::rtl::OUStringBuffer().appendAscii( "*." ).append( m_aFilterExtensions[0] ).makeStringAndClear() );
        aFileDlg.SetCurrentFilter( m_sFilterUIName );

        if ( aFileDlg.Execute() == ERRCODE_NONE )
        {
            INetURLObject aURL( aFileDlg.GetPath() );
            if( aURL.GetProtocol() != INET_PROT_NOT_VALID )
            {
                ::svt::OFileNotation aFileNotation( aURL.GetMainURL( INetURLObject::NO_DECODE ) );
                m_rLocationInput.SetText( aFileNotation.get( ::svt::OFileNotation::N_SYSTEM ) );
                m_rLocationInput.GetModifyHdl().Call( &m_rLocationInput );
                // the dialog already checked for the file's existence, so we don't need to, again
                m_bNeedExistenceCheck = false;
            }
        }
    }

    // -----------------------------------------------------------------------------
    void DatabaseLocationInputController_Impl::impl_onLocationModified()
    {
        m_bNeedExistenceCheck = true;
    }

    //====================================================================
	//= DatabaseLocationInputController
	//====================================================================
	//--------------------------------------------------------------------
    DatabaseLocationInputController::DatabaseLocationInputController( const ::comphelper::ComponentContext& _rContext,
            ::svt::OFileURLControl& _rLocationInput, PushButton& _rBrowseButton )
        :m_pImpl( new DatabaseLocationInputController_Impl( _rContext, _rLocationInput, _rBrowseButton ) )
    {
    }

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

	//--------------------------------------------------------------------
    bool DatabaseLocationInputController::prepareCommit()
    {
        return m_pImpl->prepareCommit();
    }

	//--------------------------------------------------------------------
    void DatabaseLocationInputController::setURL( const String& _rURL )
    {
        m_pImpl->setURL( _rURL );
    }

	//--------------------------------------------------------------------
    String DatabaseLocationInputController::getURL() const
    {
        return m_pImpl->getURL();
    }

//........................................................................
} // namespace svx
//........................................................................
