/**************************************************************
 *
 * 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_TOGGLEBUTTONTOOLBARCONTROLLER_HXX
#include "uielement/togglebuttontoolbarcontroller.hxx"
#endif

//_________________________________________________________________________________________________________________
//	my own includes
//_________________________________________________________________________________________________________________
#include <framework/addonsoptions.hxx>
#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/frame/XControlNotificationListener.hpp>
#include "com/sun/star/util/XMacroExpander.hpp"
#include "com/sun/star/uno/XComponentContext.hpp"
#include "com/sun/star/beans/XPropertySet.hpp"

//_________________________________________________________________________________________________________________
//	other includes
//_________________________________________________________________________________________________________________

#include <rtl/uri.hxx>
#include <vos/mutex.hxx>
#include <comphelper/processfactory.hxx>
#include <unotools/ucbstreamhelper.hxx>
#include <tools/urlobj.hxx>
#include <vcl/svapp.hxx>
#include <vcl/mnemonic.hxx>
#include <vcl/window.hxx>
#include <vcl/graph.hxx>
#include <vcl/bitmap.hxx>
#include <svtools/filter.hxx>
#include <svtools/miscopt.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::util;

namespace framework
{

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

ToggleButtonToolbarController::ToggleButtonToolbarController(
    const Reference< XMultiServiceFactory >& rServiceManager,
    const Reference< XFrame >&               rFrame,
    ToolBox*                                 pToolbar,
    sal_uInt16                                   nID,
    Style                                    eStyle,
    const ::rtl::OUString&                          aCommand ) :
    ComplexToolbarController( rServiceManager, rFrame, pToolbar, nID, aCommand ),
    m_eStyle( eStyle )
{
    if ( eStyle == STYLE_DROPDOWNBUTTON )
        m_pToolbar->SetItemBits( m_nID, TIB_DROPDOWNONLY | m_pToolbar->GetItemBits( m_nID ) );
    else if ( eStyle == STYLE_TOGGLE_DROPDOWNBUTTON )
	    m_pToolbar->SetItemBits( m_nID, TIB_DROPDOWN | m_pToolbar->GetItemBits( m_nID ) );
}

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

ToggleButtonToolbarController::~ToggleButtonToolbarController()
{
}

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

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

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

    // Add key modifier to argument list
    aArgs[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "KeyModifier" ));
    aArgs[0].Value <<= KeyModifier;
    aArgs[1].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Text" ));
    aArgs[1].Value <<= m_aCurrentSelection;
    return aArgs;
}

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

uno::Reference< awt::XWindow > SAL_CALL ToggleButtonToolbarController::createPopupWindow()
throw (::com::sun::star::uno::RuntimeException)
{
    uno::Reference< awt::XWindow > xWindow;

    vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
    if (( m_eStyle == STYLE_DROPDOWNBUTTON ) ||
        ( m_eStyle == STYLE_TOGGLE_DROPDOWNBUTTON ))
    {
        // create popup menu
        PopupMenu aPopup;
        const sal_uInt32 nCount = m_aDropdownMenuList.size();
        for ( sal_uInt32 i = 0; i < nCount; i++ )
        {
            rtl::OUString aLabel( m_aDropdownMenuList[i] );
            aPopup.InsertItem( sal_uInt16( i+1 ), aLabel );
            if ( aLabel == m_aCurrentSelection )
                aPopup.CheckItem( sal_uInt16( i+1 ), sal_True );
            else
                aPopup.CheckItem( sal_uInt16( i+1 ), sal_False );
        }

        m_pToolbar->SetItemDown( m_nID, sal_True );
        aPopup.SetSelectHdl( LINK( this, ToggleButtonToolbarController, MenuSelectHdl ));
        aPopup.Execute( m_pToolbar, m_pToolbar->GetItemRect( m_nID ));
        m_pToolbar->SetItemDown( m_nID, sal_False );
    }

    return xWindow;
}

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

void ToggleButtonToolbarController::executeControlCommand( const ::com::sun::star::frame::ControlCommand& rControlCommand )
{
    vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );

    if (( m_eStyle == STYLE_DROPDOWNBUTTON ) ||
        ( m_eStyle == STYLE_TOGGLE_DROPDOWNBUTTON ))
    {
        if ( rControlCommand.Command.equalsAsciiL( "SetList", 7 ))
        {
            for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
            {
                if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "List", 4 ))
                {
                    Sequence< ::rtl::OUString > aList;
                    m_aDropdownMenuList.clear();

                    rControlCommand.Arguments[i].Value >>= aList;
                    for ( sal_Int32 j = 0; j < aList.getLength(); j++ )
                        m_aDropdownMenuList.push_back( aList[j] );

                    // send notification
                    uno::Sequence< beans::NamedValue > aInfo( 1 );
                    aInfo[0].Name  = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "List" ));
                    aInfo[0].Value <<= aList;
                    addNotifyInfo( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ListChanged" )),
                                getDispatchFromCommand( m_aCommandURL ),
                                aInfo );

                    break;
                }
            }
        }
        else if ( rControlCommand.Command.equalsAsciiL( "CheckItemPos", 12 ))
        {
            for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
            {
                if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "Pos", 3 ))
                {
                    sal_Int32 nPos( -1 );

                    rControlCommand.Arguments[i].Value >>= nPos;
                    if ( nPos >= 0 &&
                         ( sal::static_int_cast< sal_uInt32 >(nPos)
                           < m_aDropdownMenuList.size() ) )
                    {
                        m_aCurrentSelection = m_aDropdownMenuList[nPos];

                        // send notification
                        uno::Sequence< beans::NamedValue > aInfo( 1 );
                        aInfo[0].Name  = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ItemChecked" ));
                        aInfo[0].Value <<= nPos;
                        addNotifyInfo( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Pos" )),
                                    getDispatchFromCommand( m_aCommandURL ),
                                    aInfo );
                    }
                    break;
                }
            }
        }
        else if ( rControlCommand.Command.equalsAsciiL( "AddEntry", 8 ))
        {
            rtl::OUString   aText;
            for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
            {
                if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "Text", 4 ))
                {
                    if ( rControlCommand.Arguments[i].Value >>= aText )
                        m_aDropdownMenuList.push_back( aText );
                    break;
                }
            }
        }
        else if ( rControlCommand.Command.equalsAsciiL( "InsertEntry", 11 ))
        {
            sal_Int32      nPos( COMBOBOX_APPEND );
            sal_Int32      nSize = sal_Int32( m_aDropdownMenuList.size() );
            rtl::OUString  aText;
            for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
            {
                if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "Pos", 3 ))
                {
                    sal_Int32 nTmpPos = 0;
                    if ( rControlCommand.Arguments[i].Value >>= nTmpPos )
                    {
                        if (( nTmpPos >= 0 ) && ( nTmpPos < sal_Int32( nSize )))
                            nPos = nTmpPos;
                    }
                }
                else if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "Text", 4 ))
                    rControlCommand.Arguments[i].Value >>= aText;
            }

            std::vector< ::rtl::OUString >::iterator aIter = m_aDropdownMenuList.begin();
            aIter += nPos;
		    m_aDropdownMenuList.insert( aIter, aText );
        }
        else if ( rControlCommand.Command.equalsAsciiL( "RemoveEntryPos", 14 ))
        {
            for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
            {
                if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "Pos", 3 ))
                {
                    sal_Int32 nPos( -1 );
                    if ( rControlCommand.Arguments[i].Value >>= nPos )
                    {
                        if ( nPos < sal_Int32( m_aDropdownMenuList.size() ))
                        {
                            std::vector< ::rtl::OUString >::iterator aIter = m_aDropdownMenuList.begin();
                            aIter += nPos;
		                    m_aDropdownMenuList.erase( aIter );
                        }
                    }
                    break;
                }
            }
        }
        else if ( rControlCommand.Command.equalsAsciiL( "RemoveEntryText", 15 ))
        {
            for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
            {
                if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "Text", 4 ))
                {
                    rtl::OUString aText;
                    if ( rControlCommand.Arguments[i].Value >>= aText )
                    {
                        sal_Int32 nSize = sal_Int32( m_aDropdownMenuList.size() );
                        for ( sal_Int32 j = 0; j < nSize; j++ )
                        {
                            if ( m_aDropdownMenuList[j] == aText )
                            {
                                std::vector< ::rtl::OUString >::iterator aIter = m_aDropdownMenuList.begin();
                                aIter += j;
		                        m_aDropdownMenuList.erase( aIter );
                                break;
                            }
                        }
                    }
                    break;
                }
            }
        }
    }
}

IMPL_LINK( ToggleButtonToolbarController, MenuSelectHdl, Menu *, pMenu )
{
    vos::OGuard aGuard( Application::GetSolarMutex() );

    sal_uInt16 nItemId = pMenu->GetCurItemId();
    if ( nItemId > 0 && nItemId <= m_aDropdownMenuList.size() )
    {
        m_aCurrentSelection = m_aDropdownMenuList[nItemId-1];

        execute( 0 );
    }
    return 0;
}

} // namespace
