/**************************************************************
 * 
 * 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_accessibility.hxx"
#include <accessibility/standard/vclxaccessiblemenuitem.hxx>
#include <accessibility/helper/accresmgr.hxx>
#include <accessibility/helper/accessiblestrings.hrc>
#include <toolkit/helper/convert.hxx>
#include <accessibility/helper/characterattributeshelper.hxx>
#include <comphelper/accessiblekeybindinghelper.hxx>
#include <com/sun/star/awt/KeyModifier.hpp>

#include <com/sun/star/accessibility/AccessibleRole.hpp>
#include <com/sun/star/accessibility/AccessibleStateType.hpp>
#include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
#include <com/sun/star/datatransfer/clipboard/XFlushableClipboard.hpp>
#include <unotools/accessiblestatesethelper.hxx>
#include <comphelper/sequence.hxx>
#include <vcl/svapp.hxx>
#include <vcl/window.hxx>
#include <vcl/menu.hxx>
#include <vcl/unohelp2.hxx>

#include <memory>


using namespace ::com::sun::star::accessibility;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star;
using namespace ::comphelper;


// -----------------------------------------------------------------------------
// class VCLXAccessibleMenuItem
// -----------------------------------------------------------------------------

VCLXAccessibleMenuItem::VCLXAccessibleMenuItem( Menu* pParent, sal_uInt16 nItemPos, Menu* pMenu )
	:OAccessibleMenuItemComponent( pParent, nItemPos, pMenu )
{
}

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

VCLXAccessibleMenuItem::~VCLXAccessibleMenuItem()
{
}

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

sal_Bool VCLXAccessibleMenuItem::IsFocused()
{
    return IsHighlighted();
}

// -----------------------------------------------------------------------------
		
sal_Bool VCLXAccessibleMenuItem::IsSelected()
{
    return IsHighlighted();
}

// -----------------------------------------------------------------------------
		
sal_Bool VCLXAccessibleMenuItem::IsChecked()
{
	sal_Bool bChecked = sal_False;

	if ( m_pParent )
	{
		sal_uInt16 nItemId = m_pParent->GetItemId( m_nItemPos );
		if ( m_pParent->IsItemChecked( nItemId ) )
			bChecked = sal_True;
	}

	return bChecked;
}

// -----------------------------------------------------------------------------
		
sal_Bool VCLXAccessibleMenuItem::IsHighlighted()
{
	sal_Bool bHighlighted = sal_False;

    if ( m_pParent && m_pParent->IsHighlighted( m_nItemPos ) )
        bHighlighted = sal_True;

	return bHighlighted;
}

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

void VCLXAccessibleMenuItem::FillAccessibleStateSet( utl::AccessibleStateSetHelper& rStateSet )
{
    OAccessibleMenuItemComponent::FillAccessibleStateSet( rStateSet );

    rStateSet.AddState( AccessibleStateType::FOCUSABLE );

    if ( IsFocused() )
        rStateSet.AddState( AccessibleStateType::FOCUSED );

    rStateSet.AddState( AccessibleStateType::SELECTABLE );

    if ( IsSelected() )
        rStateSet.AddState( AccessibleStateType::SELECTED );

    if ( IsChecked() )
        rStateSet.AddState( AccessibleStateType::CHECKED );
}

// -----------------------------------------------------------------------------
// OCommonAccessibleText
// -----------------------------------------------------------------------------

::rtl::OUString VCLXAccessibleMenuItem::implGetText()
{
	return m_sItemText;
}

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

Locale VCLXAccessibleMenuItem::implGetLocale()
{
	return Application::GetSettings().GetLocale();
}

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

void VCLXAccessibleMenuItem::implGetSelection( sal_Int32& nStartIndex, sal_Int32& nEndIndex )
{
	nStartIndex = 0;
	nEndIndex = 0;
}

// -----------------------------------------------------------------------------
// XInterface
// -----------------------------------------------------------------------------

IMPLEMENT_FORWARD_XINTERFACE2( VCLXAccessibleMenuItem, OAccessibleMenuItemComponent, VCLXAccessibleMenuItem_BASE )

// -----------------------------------------------------------------------------
// XTypeProvider
// -----------------------------------------------------------------------------

IMPLEMENT_FORWARD_XTYPEPROVIDER2( VCLXAccessibleMenuItem, OAccessibleMenuItemComponent, VCLXAccessibleMenuItem_BASE )

// -----------------------------------------------------------------------------
// XServiceInfo
// -----------------------------------------------------------------------------

::rtl::OUString VCLXAccessibleMenuItem::getImplementationName() throw (RuntimeException)
{
	return ::rtl::OUString::createFromAscii( "com.sun.star.comp.toolkit.AccessibleMenuItem" );
}

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

Sequence< ::rtl::OUString > VCLXAccessibleMenuItem::getSupportedServiceNames() throw (RuntimeException)
{
	Sequence< ::rtl::OUString > aNames(1);
	aNames[0] = ::rtl::OUString::createFromAscii( "com.sun.star.awt.AccessibleMenuItem" );
	return aNames;
}

// -----------------------------------------------------------------------------
// XAccessibleContext
// -----------------------------------------------------------------------------

sal_Int16 VCLXAccessibleMenuItem::getAccessibleRole(  ) throw (RuntimeException)
{
	OExternalLockGuard aGuard( this );
	// IA2 CWS. MT: We had the aditional roles in UAA for ever, but never used them anywhere.
	// Looks reasonable, but need to verify in Orca and VoiceOver.
	sal_Int16 nRole = AccessibleRole::MENU_ITEM;
	if ( m_pParent )
	{
		sal_uInt16 nItemId = m_pParent->GetItemId( m_nItemPos );
		MenuItemBits nItemBits = m_pParent->GetItemBits(nItemId);
		if(  nItemBits & MIB_RADIOCHECK)
			nRole = AccessibleRole::RADIO_MENU_ITEM;
		else if( nItemBits & MIB_CHECKABLE)
			nRole = AccessibleRole::CHECK_MENU_ITEM;
	}
	return nRole;
}

// -----------------------------------------------------------------------------
// XAccessibleText
// -----------------------------------------------------------------------------

sal_Int32 VCLXAccessibleMenuItem::getCaretPosition() throw (RuntimeException)
{
	OExternalLockGuard aGuard( this );

	return -1;
}

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

sal_Bool VCLXAccessibleMenuItem::setCaretPosition( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException)
{

	OExternalLockGuard aGuard( this );

    if ( !implIsValidRange( nIndex, nIndex, implGetText().getLength() ) )
        throw IndexOutOfBoundsException();

	return sal_False;
}

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

sal_Unicode VCLXAccessibleMenuItem::getCharacter( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException)
{
	OExternalLockGuard aGuard( this );
    
	return OCommonAccessibleText::getCharacter( nIndex );	
}

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

Sequence< PropertyValue > VCLXAccessibleMenuItem::getCharacterAttributes( sal_Int32 nIndex, const Sequence< ::rtl::OUString >& aRequestedAttributes ) throw (IndexOutOfBoundsException, RuntimeException)
{
	OExternalLockGuard aGuard( this );

	Sequence< PropertyValue > aValues;
	::rtl::OUString sText( implGetText() );

    if ( !implIsValidIndex( nIndex, sText.getLength() ) )
        throw IndexOutOfBoundsException();

	Font aFont = Application::GetSettings().GetStyleSettings().GetMenuFont();
	sal_Int32 nBackColor = getBackground();
	sal_Int32 nColor = getForeground();
    ::std::auto_ptr< CharacterAttributesHelper > pHelper( new CharacterAttributesHelper( aFont, nBackColor, nColor ) );
    aValues = pHelper->GetCharacterAttributes( aRequestedAttributes );

    return aValues;
}

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

awt::Rectangle VCLXAccessibleMenuItem::getCharacterBounds( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException)
{
	OExternalLockGuard aGuard( this );

    if ( !implIsValidIndex( nIndex, implGetText().getLength() ) )
        throw IndexOutOfBoundsException();

	awt::Rectangle aBounds( 0, 0, 0, 0 );
	if ( m_pParent )
	{
		sal_uInt16 nItemId = m_pParent->GetItemId( m_nItemPos );
		Rectangle aItemRect = m_pParent->GetBoundingRectangle( m_nItemPos );
		Rectangle aCharRect = m_pParent->GetCharacterBounds( nItemId, nIndex );
		aCharRect.Move( -aItemRect.Left(), -aItemRect.Top() );
		aBounds = AWTRectangle( aCharRect );
	}

	return aBounds;
}

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

sal_Int32 VCLXAccessibleMenuItem::getCharacterCount() throw (RuntimeException)
{
	OExternalLockGuard aGuard( this );

	return OCommonAccessibleText::getCharacterCount();		
}

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

sal_Int32 VCLXAccessibleMenuItem::getIndexAtPoint( const awt::Point& aPoint ) throw (RuntimeException)
{
	OExternalLockGuard aGuard( this );

	sal_Int32 nIndex = -1;
	if ( m_pParent )
	{
		sal_uInt16 nItemId = 0;
		Rectangle aItemRect = m_pParent->GetBoundingRectangle( m_nItemPos );
		Point aPnt( VCLPoint( aPoint ) );
		aPnt += aItemRect.TopLeft();
		sal_Int32 nI = m_pParent->GetIndexForPoint( aPnt, nItemId );
		if ( nI != -1 && m_pParent->GetItemId( m_nItemPos ) == nItemId )
			nIndex = nI;
	}

	return nIndex;
}

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

::rtl::OUString VCLXAccessibleMenuItem::getSelectedText() throw (RuntimeException)
{
	OExternalLockGuard aGuard( this );
	
	return OCommonAccessibleText::getSelectedText();				
}

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

sal_Int32 VCLXAccessibleMenuItem::getSelectionStart() throw (RuntimeException)
{
	OExternalLockGuard aGuard( this );
	
	return OCommonAccessibleText::getSelectionStart();
}

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

sal_Int32 VCLXAccessibleMenuItem::getSelectionEnd() throw (RuntimeException)
{
	OExternalLockGuard aGuard( this );
	
	return OCommonAccessibleText::getSelectionEnd();	
}

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

sal_Bool VCLXAccessibleMenuItem::setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (IndexOutOfBoundsException, RuntimeException)
{
	OExternalLockGuard aGuard( this );

    if ( !implIsValidRange( nStartIndex, nEndIndex, implGetText().getLength() ) )
        throw IndexOutOfBoundsException();

	return sal_False;
}

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

::rtl::OUString VCLXAccessibleMenuItem::getText() throw (RuntimeException)
{
	OExternalLockGuard aGuard( this );
	
	return OCommonAccessibleText::getText();
}

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

::rtl::OUString VCLXAccessibleMenuItem::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (IndexOutOfBoundsException, RuntimeException)
{
	OExternalLockGuard aGuard( this );
	
	return OCommonAccessibleText::getTextRange( nStartIndex, nEndIndex );		
}

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

::com::sun::star::accessibility::TextSegment VCLXAccessibleMenuItem::getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
{
	OExternalLockGuard aGuard( this );
	
	return OCommonAccessibleText::getTextAtIndex( nIndex, aTextType );
}

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

::com::sun::star::accessibility::TextSegment VCLXAccessibleMenuItem::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
{
	OExternalLockGuard aGuard( this );
	
	return OCommonAccessibleText::getTextBeforeIndex( nIndex, aTextType );
}

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

::com::sun::star::accessibility::TextSegment VCLXAccessibleMenuItem::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
{
	OExternalLockGuard aGuard( this );
	
	return OCommonAccessibleText::getTextBehindIndex( nIndex, aTextType );
}

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

sal_Bool VCLXAccessibleMenuItem::copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (IndexOutOfBoundsException, RuntimeException)
{
	OExternalLockGuard aGuard( this );

	sal_Bool bReturn = sal_False;

	if ( m_pParent )
	{
		Window* pWindow = m_pParent->GetWindow();		
		if ( pWindow )
		{
			Reference< datatransfer::clipboard::XClipboard > xClipboard = pWindow->GetClipboard();
			if ( xClipboard.is() )
			{
				::rtl::OUString sText( getTextRange( nStartIndex, nEndIndex ) );

				::vcl::unohelper::TextDataObject* pDataObj = new ::vcl::unohelper::TextDataObject( sText );
				const sal_uInt32 nRef = Application::ReleaseSolarMutex();
				xClipboard->setContents( pDataObj, NULL );

				Reference< datatransfer::clipboard::XFlushableClipboard > xFlushableClipboard( xClipboard, uno::UNO_QUERY );
				if( xFlushableClipboard.is() )
					xFlushableClipboard->flushClipboard();
				
				Application::AcquireSolarMutex( nRef );

				bReturn = sal_True;
			}
		}
	}

	return bReturn;
}

// -----------------------------------------------------------------------------
// XAccessibleAction
// -----------------------------------------------------------------------------

sal_Int32 VCLXAccessibleMenuItem::getAccessibleActionCount( ) throw (RuntimeException)
{
	OExternalLockGuard aGuard( this );

	return 1;	
}

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

sal_Bool VCLXAccessibleMenuItem::doAccessibleAction ( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException)
{
	OExternalLockGuard aGuard( this );

	if ( nIndex < 0 || nIndex >= getAccessibleActionCount() )
        throw IndexOutOfBoundsException();

	Click();

	return sal_True;
}

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

::rtl::OUString VCLXAccessibleMenuItem::getAccessibleActionDescription ( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException)
{
	OExternalLockGuard aGuard( this );

	if ( nIndex < 0 || nIndex >= getAccessibleActionCount() )
        throw IndexOutOfBoundsException();
	return ::rtl::OUString( TK_RES_STRING( RID_STR_ACC_ACTION_SELECT ) );
}

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

Reference< XAccessibleKeyBinding > VCLXAccessibleMenuItem::getAccessibleActionKeyBinding( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException)
{
	OExternalLockGuard aGuard( this );

	if ( nIndex < 0 || nIndex >= getAccessibleActionCount() )
        throw IndexOutOfBoundsException();
	
	OAccessibleKeyBindingHelper* pKeyBindingHelper = new OAccessibleKeyBindingHelper();
	Reference< XAccessibleKeyBinding > xKeyBinding = pKeyBindingHelper;

	if ( m_pParent )
	{
		// create auto mnemonics
		if ( Application::GetSettings().GetStyleSettings().GetAutoMnemonic() && !( m_pParent->GetMenuFlags() & MENU_FLAG_NOAUTOMNEMONICS ) )
			m_pParent->CreateAutoMnemonics();

		// activation key
		KeyEvent aKeyEvent = m_pParent->GetActivationKey( m_pParent->GetItemId( m_nItemPos ) );
		KeyCode aKeyCode = aKeyEvent.GetKeyCode();
		Sequence< awt::KeyStroke > aSeq1(1);
		aSeq1[0].Modifiers = 0;
		Reference< XAccessible > xParent( getAccessibleParent() );
		if ( xParent.is() )
		{
			Reference< XAccessibleContext > xParentContext( xParent->getAccessibleContext() );
			if ( xParentContext.is() && xParentContext->getAccessibleRole() == AccessibleRole::MENU_BAR )
				aSeq1[0].Modifiers |= awt::KeyModifier::MOD2;
		}
		aSeq1[0].KeyCode = aKeyCode.GetCode();
		aSeq1[0].KeyChar = aKeyEvent.GetCharCode();
        aSeq1[0].KeyFunc = static_cast< sal_Int16 >( aKeyCode.GetFunction() );
		pKeyBindingHelper->AddKeyBinding( aSeq1 );

		// complete menu activation key sequence
		Sequence< awt::KeyStroke > aSeq;
		if ( xParent.is() )
		{
			Reference< XAccessibleContext > xParentContext( xParent->getAccessibleContext() );
			if ( xParentContext.is() && xParentContext->getAccessibleRole() == AccessibleRole::MENU )
			{
				Reference< XAccessibleAction > xAction( xParentContext, UNO_QUERY );
				if ( xAction.is() && xAction->getAccessibleActionCount() > 0 )
				{
					Reference< XAccessibleKeyBinding > xKeyB( xAction->getAccessibleActionKeyBinding( 0 ) );
					if ( xKeyB.is() && xKeyB->getAccessibleKeyBindingCount() > 1 )
						aSeq = xKeyB->getAccessibleKeyBinding( 1 );					
				}
			}
		}
		Sequence< awt::KeyStroke > aSeq2 = ::comphelper::concatSequences( aSeq, aSeq1 );
		pKeyBindingHelper->AddKeyBinding( aSeq2 );

        // accelerator key
        KeyCode aAccelKeyCode = m_pParent->GetAccelKey( m_pParent->GetItemId( m_nItemPos ) );
        if ( aAccelKeyCode.GetCode() != 0 )
        {
            Sequence< awt::KeyStroke > aSeq3(1);
            aSeq3[0].Modifiers = 0;
            if ( aAccelKeyCode.IsShift() )
                aSeq3[0].Modifiers |= awt::KeyModifier::SHIFT;
            if ( aAccelKeyCode.IsMod1() )
                aSeq3[0].Modifiers |= awt::KeyModifier::MOD1;
            if ( aAccelKeyCode.IsMod2() )
                aSeq3[0].Modifiers |= awt::KeyModifier::MOD2;
            if ( aAccelKeyCode.IsMod3() )
                aSeq3[0].Modifiers |= awt::KeyModifier::MOD3;
            aSeq3[0].KeyCode = aAccelKeyCode.GetCode();
            aSeq3[0].KeyFunc = static_cast< sal_Int16 >( aAccelKeyCode.GetFunction() );
            pKeyBindingHelper->AddKeyBinding( aSeq3 );
        }
	}

	return xKeyBinding;
}

// -----------------------------------------------------------------------------
// XAccessibleValue
// -----------------------------------------------------------------------------

Any VCLXAccessibleMenuItem::getCurrentValue(  ) throw (RuntimeException)
{
	OExternalLockGuard aGuard( this );

	Any aValue;
	if ( IsSelected() )
		aValue <<= (sal_Int32) 1;
	else
		aValue <<= (sal_Int32) 0;

	return aValue;
}

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

sal_Bool VCLXAccessibleMenuItem::setCurrentValue( const Any& aNumber ) throw (RuntimeException)
{
	OExternalLockGuard aGuard( this );

	sal_Bool bReturn = sal_False;
	sal_Int32 nValue = 0;
	OSL_VERIFY( aNumber >>= nValue );

	if ( nValue <= 0 )
	{
		DeSelect();
		bReturn = sal_True;
	}
	else if ( nValue >= 1 )
	{
		Select();
		bReturn = sal_True;
	}

	return bReturn;
}

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

Any VCLXAccessibleMenuItem::getMaximumValue(  ) throw (RuntimeException)
{
	OExternalLockGuard aGuard( this );

	Any aValue;
	aValue <<= (sal_Int32) 1;
	
	return aValue;
}

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

Any VCLXAccessibleMenuItem::getMinimumValue(  ) throw (RuntimeException)
{
	OExternalLockGuard aGuard( this );

	Any aValue;
	aValue <<= (sal_Int32) 0;
	
	return aValue;
}

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