/**************************************************************
 *
 * 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_extensions.hxx"
#include "sqlcommanddesign.hxx"
#include "formstrings.hxx"
#ifndef _EXTENSIONS_FORMCTRLR_PROPRESID_HRC_
#include "formresid.hrc"
#endif
#ifndef _EXTENSIONS_PROPCTRLR_MODULEPRC_HXX_
#include "modulepcr.hxx"
#endif
#include "unourl.hxx"

/** === begin UNO includes === **/
#include <com/sun/star/awt/XWindow.hpp>
#include <com/sun/star/awt/XTopWindow.hpp>
#include <com/sun/star/uno/Sequence.hxx>
#include <com/sun/star/frame/XTitle.hpp>
#include <com/sun/star/frame/XComponentLoader.hpp>
#include <com/sun/star/frame/XController.hpp>
#include <com/sun/star/lang/NullPointerException.hpp>
#include <com/sun/star/lang/DisposedException.hpp>
#include <com/sun/star/frame/FrameSearchFlag.hpp>
#include <com/sun/star/frame/XFramesSupplier.hpp>
#include <com/sun/star/sdbc/XConnection.hpp>
#include <com/sun/star/util/XCloseable.hpp>
#include <com/sun/star/frame/XDispatchProvider.hpp>
#include <com/sun/star/beans/XPropertySetInfo.hpp>
#include <com/sun/star/sdb/CommandType.hpp>
/** === end UNO includes === **/

#include <svtools/localresaccess.hxx>
#include <tools/diagnose_ex.h>
#include <osl/diagnose.h>

//........................................................................
namespace pcr
{
//........................................................................

    /** === begin UNO using === **/
    using ::com::sun::star::uno::Reference;
    using ::com::sun::star::lang::XMultiComponentFactory;
    using ::com::sun::star::beans::PropertyChangeEvent;
    using ::com::sun::star::uno::RuntimeException;
    using ::com::sun::star::frame::XFrame;
    using ::com::sun::star::awt::XTopWindow;
    using ::com::sun::star::awt::XWindow;
    using ::com::sun::star::uno::Exception;
    using ::com::sun::star::uno::UNO_QUERY_THROW;
    using ::com::sun::star::uno::UNO_QUERY;
    using ::com::sun::star::beans::PropertyValue;
    using ::com::sun::star::uno::Sequence;
    using ::com::sun::star::lang::XComponent;
    using ::com::sun::star::frame::XComponentLoader;
    using ::com::sun::star::beans::XPropertySet;
    using ::com::sun::star::beans::XPropertySetInfo;
    using ::com::sun::star::frame::XController;
    using ::com::sun::star::frame::XTitle;
    using ::com::sun::star::lang::EventObject;
    using ::com::sun::star::lang::NullPointerException;
    using ::com::sun::star::lang::DisposedException;
    using ::com::sun::star::uno::makeAny;
    using ::com::sun::star::uno::XComponentContext;
    using ::com::sun::star::frame::XFramesSupplier;
    using ::com::sun::star::frame::XFrames;
    using ::com::sun::star::util::XCloseable;
    using ::com::sun::star::uno::TypeClass_STRING;
    using ::com::sun::star::lang::XMultiServiceFactory;
    using ::com::sun::star::frame::XDispatchProvider;
    using ::com::sun::star::frame::XDispatch;
    using ::com::sun::star::uno::Any;
    /** === end UNO using === **/
    namespace FrameSearchFlag = ::com::sun::star::frame::FrameSearchFlag;
    namespace CommandType = ::com::sun::star::sdb::CommandType;

	//====================================================================
	//= ISQLCommandAdapter
	//====================================================================
	//--------------------------------------------------------------------
    ISQLCommandAdapter::~ISQLCommandAdapter()
    {
    }

    //====================================================================
	//= SQLCommandDesigner
	//====================================================================
	//--------------------------------------------------------------------
    SQLCommandDesigner::SQLCommandDesigner( const Reference< XComponentContext >& _rxContext,
            const ::rtl::Reference< ISQLCommandAdapter >& _rxPropertyAdapter,
            const ::dbtools::SharedConnection& _rConnection, const Link& _rCloseLink )
        :m_xContext( _rxContext )
        ,m_xConnection( _rConnection )
        ,m_xObjectAdapter( _rxPropertyAdapter )
        ,m_aCloseLink( _rCloseLink )
    {
        if ( m_xContext.is() )
            m_xORB = m_xContext->getServiceManager();
        if ( !m_xORB.is() || !_rxPropertyAdapter.is() || !m_xConnection.is() )
            throw NullPointerException();

        impl_doOpenDesignerFrame_nothrow();
    }

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

    //--------------------------------------------------------------------
    void SAL_CALL SQLCommandDesigner::propertyChange( const PropertyChangeEvent& Event ) throw (RuntimeException)
    {
        OSL_ENSURE( m_xDesigner.is() && ( Event.Source == m_xDesigner ), "SQLCommandDesigner::propertyChange: where did this come from?" );

        if ( m_xDesigner.is() && ( Event.Source == m_xDesigner ) )
        {
            try
            {
                if ( PROPERTY_ACTIVECOMMAND == Event.PropertyName )
                {
                    ::rtl::OUString sCommand;
                    OSL_VERIFY( Event.NewValue >>= sCommand );
                    m_xObjectAdapter->setSQLCommand( sCommand );
                }
                else if ( PROPERTY_ESCAPE_PROCESSING == Event.PropertyName )
                {
                    sal_Bool bEscapeProcessing( sal_False );
                    OSL_VERIFY( Event.NewValue >>= bEscapeProcessing );
                    m_xObjectAdapter->setEscapeProcessing( bEscapeProcessing );
                }
            }
            catch( const RuntimeException& ) { throw; }
            catch( const Exception& )
            {
                // not allowed to leave, so silence it
                DBG_UNHANDLED_EXCEPTION();
            }
        }
    }

    //--------------------------------------------------------------------
    void SAL_CALL SQLCommandDesigner::disposing( const EventObject& Source ) throw (RuntimeException)
    {
        if ( m_xDesigner.is() && ( Source.Source == m_xDesigner ) )
        {
            impl_designerClosed_nothrow();
            m_xDesigner.clear();
        }
    }

    //--------------------------------------------------------------------
    void SQLCommandDesigner::dispose()
    {
        if ( impl_isDisposed() )
            return;

        if ( isActive() )
            impl_closeDesigner_nothrow();

        m_xConnection.clear();
        m_xContext.clear();
        m_xORB.clear();
    }

    //--------------------------------------------------------------------
    void SQLCommandDesigner::impl_checkDisposed_throw() const
    {
        if ( impl_isDisposed() )
            throw DisposedException();
    }

    //--------------------------------------------------------------------
    void SQLCommandDesigner::raise() const
    {
        impl_checkDisposed_throw();
        impl_raise_nothrow();
    }

	//------------------------------------------------------------------------
    bool SQLCommandDesigner::suspend() const
    {
        impl_checkDisposed_throw();
        return impl_trySuspendDesigner_nothrow();
    }

    //--------------------------------------------------------------------
    void SQLCommandDesigner::impl_raise_nothrow() const
    {
        OSL_PRECOND( isActive(), "SQLCommandDesigner::impl_raise_nothrow: not active!" );
        if ( !isActive() )
            return;

        try
        {
            // activate the frame for this component
            Reference< XFrame >     xFrame( m_xDesigner->getFrame(), UNO_QUERY_THROW );
            Reference< XWindow >    xWindow( xFrame->getContainerWindow(), UNO_QUERY_THROW );
            Reference< XTopWindow > xTopWindow( xWindow, UNO_QUERY_THROW );

            xTopWindow->toFront();
            xWindow->setFocus();
        }
        catch( const Exception& )
        {
            DBG_UNHANDLED_EXCEPTION();
        }
    }

    //--------------------------------------------------------------------
    void SQLCommandDesigner::impl_doOpenDesignerFrame_nothrow()
    {
        OSL_PRECOND( !isActive(),
            "SQLCommandDesigner::impl_doOpenDesignerFrame_nothrow: already active!" );
        OSL_PRECOND( m_xConnection.is(), "SQLCommandDesigner::impl_doOpenDesignerFrame_nothrow: this will crash!" );
        osl_incrementInterlockedCount(&m_refCount);

        try
        {
            // for various reasons, we don't want the new frame to appear in the desktop's frame list
            // thus, we create a blank frame at the desktop, remove it from the desktop's frame list
            // immediately, and then load the component into this blank (and now parent-less) frame
			Reference< XComponentLoader > xLoader( impl_createEmptyParentlessTask_nothrow(), UNO_QUERY_THROW );
            Sequence< PropertyValue > aArgs( 5 );
            aArgs[0].Name = PROPERTY_ACTIVE_CONNECTION;
            aArgs[0].Value <<= m_xConnection.getTyped();

            aArgs[1].Name  = PROPERTY_COMMAND;
            aArgs[1].Value <<= m_xObjectAdapter->getSQLCommand();
            aArgs[2].Name  = PROPERTY_COMMANDTYPE;
            aArgs[2].Value <<= (sal_Int32)CommandType::COMMAND;
            aArgs[3].Name  = PROPERTY_ESCAPE_PROCESSING;
            aArgs[3].Value <<= m_xObjectAdapter->getEscapeProcessing();

            aArgs[4].Name  = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "GraphicalDesign" ) );
            aArgs[4].Value <<= m_xObjectAdapter->getEscapeProcessing();

			Reference< XComponent > xQueryDesign = xLoader->loadComponentFromURL(
                ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".component:DB/QueryDesign" ) ),
				::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_self" ) ),
				FrameSearchFlag::TASKS | FrameSearchFlag::CREATE,
				aArgs
			);

            // remember this newly loaded component - we need to care for it e.g. when we're suspended
            m_xDesigner = m_xDesigner.query( xQueryDesign );
            OSL_ENSURE( m_xDesigner.is() || !xQueryDesign.is(), "SQLCommandDesigner::impl_doOpenDesignerFrame_nothrow: the component is expected to be a controller!" );
            if ( m_xDesigner.is() )
            {
                Reference< XPropertySet > xQueryDesignProps( m_xDesigner, UNO_QUERY );
                OSL_ENSURE( xQueryDesignProps.is(), "SQLCommandDesigner::impl_doOpenDesignerFrame_nothrow: the controller should have properties!" );
                if ( xQueryDesignProps.is() )
                {
                    xQueryDesignProps->addPropertyChangeListener( PROPERTY_ACTIVECOMMAND, this );
                    xQueryDesignProps->addPropertyChangeListener( PROPERTY_ESCAPE_PROCESSING, this );
                }
            }

            // get the frame which we just opened and set it's title
            Reference< XTitle> xTitle(xQueryDesign,UNO_QUERY);
            if ( xTitle.is() )
            {
                ::svt::OLocalResourceAccess aEnumStrings( PcrRes( RID_RSC_ENUM_COMMAND_TYPE ), RSC_RESOURCE );
	            ::rtl::OUString sDisplayName = String( PcrRes( CommandType::COMMAND + 1 ) );
    	        xTitle->setTitle( sDisplayName );
            }
        }
        catch( const Exception& )
        {
            DBG_UNHANDLED_EXCEPTION();
            m_xDesigner.clear();
        }
        osl_decrementInterlockedCount(&m_refCount);
    }

	//------------------------------------------------------------------------
    Reference< XFrame > SQLCommandDesigner::impl_createEmptyParentlessTask_nothrow( ) const
    {
        OSL_PRECOND( m_xORB.is(), "SQLCommandDesigner::impl_createEmptyParentlessTask_nothrow: this will crash!" );

        Reference< XFrame > xFrame;
        try
        {
            Reference< XInterface      > xDesktop          ( m_xORB->createInstanceWithContext( SERVICE_DESKTOP, m_xContext ) );
            Reference< XFrame          > xDesktopFrame     ( xDesktop,      UNO_QUERY_THROW );
            Reference< XFramesSupplier > xSuppDesktopFrames( xDesktopFrame, UNO_QUERY_THROW );

            Reference< XFrames > xDesktopFramesCollection( xSuppDesktopFrames->getFrames(), UNO_QUERY_THROW );
            xFrame = xDesktopFrame->findFrame( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_blank" ) ), FrameSearchFlag::CREATE );
            OSL_ENSURE( xFrame.is(), "SQLCommandDesigner::impl_createEmptyParentlessTask_nothrow: could not create an empty frame!" );
            xDesktopFramesCollection->remove( xFrame );
        }
        catch( const Exception& )
        {
            DBG_UNHANDLED_EXCEPTION();
        }
        return xFrame;
    }

	//------------------------------------------------------------------------
    void SQLCommandDesigner::impl_designerClosed_nothrow()
    {
        if ( m_aCloseLink.IsSet() )
            m_aCloseLink.Call( this );
    }

	//------------------------------------------------------------------------
    void SQLCommandDesigner::impl_closeDesigner_nothrow()
    {
        OSL_PRECOND( isActive(), "SQLCommandDesigner::impl_closeDesigner_nothrow: invalid calle!" );
        // close it
        try
        {
            // do not listen anymore ....
            Reference< XPropertySet > xProps( m_xDesigner, UNO_QUERY );
            if ( xProps.is() )
                xProps->removePropertyChangeListener( PROPERTY_ACTIVECOMMAND, this );

            // we need to close the frame via the "user interface", by dispatching a close command,
            // instead of calling XCloseable::close directly. The latter method would also close
            // the frame, but not care for things like shutting down the office when the last
            // frame is gone ...
            const UnoURL aCloseURL( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:CloseDoc" ) ),
                Reference< XMultiServiceFactory >( m_xORB, UNO_QUERY ) );

            Reference< XDispatchProvider > xProvider( m_xDesigner->getFrame(), UNO_QUERY_THROW );
            Reference< XDispatch > xDispatch( xProvider->queryDispatch( aCloseURL, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_top" ) ), FrameSearchFlag::SELF ) );
            OSL_ENSURE( xDispatch.is(), "SQLCommandDesigner::impl_closeDesigner_nothrow: no dispatcher for the CloseDoc command!" );
            if ( xDispatch.is() )
            {
                xDispatch->dispatch( aCloseURL, Sequence< PropertyValue >( ) );
            }
            else
            {
                // fallback: use the XCloseable::close (with all possible disadvantages)
                Reference< XCloseable > xClose( m_xDesigner->getFrame(), UNO_QUERY );
                if ( xClose.is() )
                    xClose->close( sal_True );
            }
        }
        catch( const Exception& )
        {
            DBG_UNHANDLED_EXCEPTION();
        }

        m_xDesigner.clear();
    }

	//------------------------------------------------------------------------
    bool SQLCommandDesigner::impl_trySuspendDesigner_nothrow() const
    {
        OSL_PRECOND( isActive(), "SQLCommandDesigner::impl_trySuspendDesigner_nothrow: no active designer, this will crash!" );
        sal_Bool bAllow = sal_True;
        try
        {
            bAllow = m_xDesigner->suspend( sal_True );
        }
        catch( const Exception& )
        {
            DBG_UNHANDLED_EXCEPTION();
        }
        return bAllow;
    }

//........................................................................
} // namespace pcr
//........................................................................
