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

#ifndef __FRAMEWORK_UIELEMENT_COMPLEXTOOLBARCONTROLLER_HXX
#include "uielement/complextoolbarcontroller.hxx"
#endif

//_________________________________________________________________________________________________________________
//	my own includes
//_________________________________________________________________________________________________________________

#ifndef __FRAMEWORK_TOOLBAR_HXX_
#include "uielement/toolbar.hxx"
#endif

//_________________________________________________________________________________________________________________
//	interface includes
//_________________________________________________________________________________________________________________
#include <com/sun/star/util/XURLTransformer.hpp>
#include <com/sun/star/frame/XDispatchProvider.hpp>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/lang/DisposedException.hpp>
#include <com/sun/star/frame/status/ItemStatus.hpp>
#include <com/sun/star/frame/status/ItemState.hpp>
#include <com/sun/star/frame/status/Visibility.hpp>
#include <com/sun/star/frame/XControlNotificationListener.hpp>

//_________________________________________________________________________________________________________________
//	other includes
//_________________________________________________________________________________________________________________
#include <svtools/toolboxcontroller.hxx>
#include <vos/mutex.hxx>
#include <vcl/svapp.hxx>
#ifndef _VCL_MNEMONIC_HXX_
#include <vcl/mnemonic.hxx>
#endif
#include <tools/urlobj.hxx>
#include <dispatch/uieventloghelper.hxx>

using namespace ::com::sun::star;
using namespace ::com::sun::star::awt;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::frame;
using namespace ::com::sun::star::frame::status;
using namespace ::com::sun::star::util;

namespace framework
{

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

ComplexToolbarController::ComplexToolbarController(
    const Reference< XMultiServiceFactory >& rServiceManager,
    const Reference< XFrame >&               rFrame,
    ToolBox*                                 pToolbar,
    sal_uInt16                                   nID,
    const ::rtl::OUString&                          aCommand ) :
    svt::ToolboxController( rServiceManager, rFrame, aCommand )
    ,   m_pToolbar( pToolbar )
    ,   m_nID( nID )
    ,   m_bMadeInvisible( sal_False )
{
    m_xURLTransformer.set( m_xServiceManager->createInstance(
                                                        rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ))),
                                                      UNO_QUERY_THROW );
}

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

ComplexToolbarController::~ComplexToolbarController()
{
}

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

void SAL_CALL ComplexToolbarController::dispose()
throw ( RuntimeException )
{
    vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );

    m_pToolbar->SetItemWindow( m_nID, 0 );
    svt::ToolboxController::dispose();

    m_xURLTransformer.clear();
    m_pToolbar = 0;
    m_nID = 0;
}

// ------------------------------------------------------------------
Sequence<PropertyValue> ComplexToolbarController::getExecuteArgs(sal_Int16 KeyModifier) const
{
    Sequence<PropertyValue> aArgs( 1 );

    // Add key modifier to argument list
    aArgs[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "KeyModifier" ));
    aArgs[0].Value <<= KeyModifier;
    return aArgs;
}
// -----------------------------------------------------------------------------
void SAL_CALL ComplexToolbarController::execute( sal_Int16 KeyModifier )
throw ( RuntimeException )
{
    Reference< XDispatch >       xDispatch;
    Reference< XURLTransformer > xURLTransformer;
    ::rtl::OUString                     aCommandURL;
    ::com::sun::star::util::URL  aTargetURL;
    Sequence<PropertyValue> aArgs;

    {
        vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );

        if ( m_bDisposed )
            throw DisposedException();

        if ( m_bInitialized &&
             m_xFrame.is() &&
             m_xServiceManager.is() &&
             m_aCommandURL.getLength() )
        {
            xURLTransformer = m_xURLTransformer;
            xDispatch = getDispatchFromCommand( m_aCommandURL );
            aCommandURL = m_aCommandURL;
            aTargetURL = getInitializedURL();
            aArgs = getExecuteArgs(KeyModifier);
        }
    }

    if ( xDispatch.is() && aTargetURL.Complete.getLength() > 0 )
    {
        // Execute dispatch asynchronously
        ExecuteInfo* pExecuteInfo = new ExecuteInfo;
        pExecuteInfo->xDispatch     = xDispatch;
        pExecuteInfo->aTargetURL    = aTargetURL;
        pExecuteInfo->aArgs         = aArgs;
        if(::comphelper::UiEventsLogger::isEnabled()) //#i88653#
            UiEventLogHelper(::rtl::OUString::createFromAscii("ComplexToolbarController")).log(
                m_xServiceManager,
                m_xFrame,
                aTargetURL,
                aArgs);
        Application::PostUserEvent( STATIC_LINK(0, ComplexToolbarController , ExecuteHdl_Impl), pExecuteInfo );
    }
}

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

void ComplexToolbarController::statusChanged( const FeatureStateEvent& Event )
throw ( RuntimeException )
{
    vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );

    if ( m_bDisposed )
        return;

    if ( m_pToolbar )
    {
        m_pToolbar->EnableItem( m_nID, Event.IsEnabled );

        sal_uInt16 nItemBits = m_pToolbar->GetItemBits( m_nID );
        nItemBits &= ~TIB_CHECKABLE;
	    TriState eTri = STATE_NOCHECK;

        sal_Bool        bValue = sal_Bool();
        rtl::OUString   aStrValue;
        ItemStatus      aItemState;
        Visibility      aItemVisibility;
        ControlCommand  aControlCommand;

        if ( Event.State >>= bValue )
        {
            // Boolean, treat it as checked/unchecked
            if ( m_bMadeInvisible )
                m_pToolbar->ShowItem( m_nID, sal_True );
            m_pToolbar->CheckItem( m_nID, bValue );
            if ( bValue )
                eTri = STATE_CHECK;
		    nItemBits |= TIB_CHECKABLE;
        }
        else if ( Event.State >>= aStrValue )
        {
            ::rtl::OUString aText( MnemonicGenerator::EraseAllMnemonicChars( aStrValue ) );
            m_pToolbar->SetItemText( m_nID, aText );
            m_pToolbar->SetQuickHelpText( m_nID, aText );

            if ( m_bMadeInvisible )
                m_pToolbar->ShowItem( m_nID, sal_True );
        }
        else if ( Event.State >>= aItemState )
        {
			eTri = STATE_DONTKNOW;
            nItemBits |= TIB_CHECKABLE;
            if ( m_bMadeInvisible )
                m_pToolbar->ShowItem( m_nID, sal_True );
        }
        else if ( Event.State >>= aItemVisibility )
        {
            m_pToolbar->ShowItem( m_nID, aItemVisibility.bVisible );
            m_bMadeInvisible = !aItemVisibility.bVisible;
        }
        else if ( Event.State >>= aControlCommand )
        {
            executeControlCommand( aControlCommand );
            if ( m_bMadeInvisible )
                m_pToolbar->ShowItem( m_nID, sal_True );
        }

        else if ( m_bMadeInvisible )
            m_pToolbar->ShowItem( m_nID, sal_True );

        m_pToolbar->SetItemState( m_nID, eTri );
	    m_pToolbar->SetItemBits( m_nID, nItemBits );
    }
}

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

IMPL_STATIC_LINK_NOINSTANCE( ComplexToolbarController, ExecuteHdl_Impl, ExecuteInfo*, pExecuteInfo )
{
   const sal_uInt32 nRef = Application::ReleaseSolarMutex();
   try
   {
       // Asynchronous execution as this can lead to our own destruction!
       // Framework can recycle our current frame and the layout manager disposes all user interface
       // elements if a component gets detached from its frame!
       pExecuteInfo->xDispatch->dispatch( pExecuteInfo->aTargetURL, pExecuteInfo->aArgs );
   }
   catch ( Exception& )
   {
   }

   Application::AcquireSolarMutex( nRef );
   delete pExecuteInfo;
   return 0;
}

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

IMPL_STATIC_LINK_NOINSTANCE( ComplexToolbarController, Notify_Impl, NotifyInfo*, pNotifyInfo )
{
   const sal_uInt32 nRef = Application::ReleaseSolarMutex();
   try
   {
       // Asynchronous execution: As this can lead to our own destruction!
       // Framework can recycle our current frame and the layout manager disposes all user interface
       // elements if a component gets detached from its frame!
       frame::ControlEvent aEvent;
       aEvent.aURL  = pNotifyInfo->aSourceURL;
       aEvent.Event = pNotifyInfo->aEventName;
       aEvent.aInformation = pNotifyInfo->aInfoSeq;
       pNotifyInfo->xNotifyListener->controlEvent( aEvent );
   }
   catch ( Exception& )
   {
   }

   Application::AcquireSolarMutex( nRef );
   delete pNotifyInfo;
   return 0;
}

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

void ComplexToolbarController::addNotifyInfo(
    const rtl::OUString&                      aEventName,
    const uno::Reference< frame::XDispatch >& xDispatch,
    const uno::Sequence< beans::NamedValue >& rInfo )
{
    uno::Reference< frame::XControlNotificationListener > xControlNotify( xDispatch, uno::UNO_QUERY );

    if ( xControlNotify.is() )
    {
        // Execute notification asynchronously
        NotifyInfo* pNotifyInfo = new NotifyInfo;

        pNotifyInfo->aEventName      = aEventName;
        pNotifyInfo->xNotifyListener = xControlNotify;
        pNotifyInfo->aSourceURL      = getInitializedURL();

        // Add frame as source to the information sequence
        sal_Int32 nCount = rInfo.getLength();
        uno::Sequence< beans::NamedValue > aInfoSeq( rInfo );
        aInfoSeq.realloc( nCount+1 );
        aInfoSeq[nCount].Name  = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Source" ));
        aInfoSeq[nCount].Value = uno::makeAny( getFrameInterface() );
        pNotifyInfo->aInfoSeq  = aInfoSeq;

        Application::PostUserEvent( STATIC_LINK(0, ComplexToolbarController, Notify_Impl), pNotifyInfo );
    }
}

// --------------------------------------------------------
sal_Int32 ComplexToolbarController::getFontSizePixel( const Window* pWindow )
{
	const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
    const Font&          rFont     = rSettings.GetAppFont();

    // Calculate height of the application font used by window
    sal_Int32 nHeight = sal_Int32( rFont.GetHeight() );
    ::Size aPixelSize = pWindow->LogicToPixel( ::Size( 0, nHeight ), MAP_APPFONT );
    return aPixelSize.Height();
}

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

uno::Reference< frame::XDispatch > ComplexToolbarController::getDispatchFromCommand( const rtl::OUString& aCommand ) const
{
    uno::Reference< frame::XDispatch > xDispatch;

    if ( m_bInitialized && m_xFrame.is() && m_xServiceManager.is() && aCommand.getLength() )
    {
        URLToDispatchMap::const_iterator pIter = m_aListenerMap.find( aCommand );
        if ( pIter != m_aListenerMap.end() )
            xDispatch = pIter->second;
    }

    return xDispatch;
}

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

const ::com::sun::star::util::URL& ComplexToolbarController::getInitializedURL()
{
    if ( m_aURL.Complete.getLength() == 0 )
    {
        m_aURL.Complete = m_aCommandURL;
        m_xURLTransformer->parseStrict( m_aURL );
    }
    return m_aURL;
}

void ComplexToolbarController::notifyFocusGet()
{
    // send focus get notification
    uno::Sequence< beans::NamedValue > aInfo;
    addNotifyInfo( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FocusSet" )),
                    getDispatchFromCommand( m_aCommandURL ),
                    aInfo );
}

void ComplexToolbarController::notifyFocusLost()
{
    // send focus lost notification
    uno::Sequence< beans::NamedValue > aInfo;
    addNotifyInfo( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FocusLost" )),
                    getDispatchFromCommand( m_aCommandURL ),
                    aInfo );
}

void ComplexToolbarController::notifyTextChanged( const ::rtl::OUString& aText )
{
    // send text changed notification
    uno::Sequence< beans::NamedValue > aInfo( 1 );
    aInfo[0].Name  = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Text" ));
    aInfo[0].Value <<= aText;
    addNotifyInfo( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TextChanged" )),
                   getDispatchFromCommand( m_aCommandURL ),
                   aInfo );
}

} // namespace

