/**************************************************************
 * 
 * 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

