/**************************************************************
 *
 * 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/extended/AccessibleGridControlTableCell.hxx"
#include <svtools/accessibletable.hxx>
#include "accessibility/extended/AccessibleGridControl.hxx"
#include <tools/gen.hxx>
#include <toolkit/helper/vclunohelper.hxx>
#include <com/sun/star/accessibility/AccessibleEventId.hpp>

namespace accessibility
{
	namespace
	{
		void checkIndex_Impl( sal_Int32 _nIndex, const ::rtl::OUString& _sText ) throw (::com::sun::star::lang::IndexOutOfBoundsException)
		{
			if ( _nIndex >= _sText.getLength() )
				throw ::com::sun::star::lang::IndexOutOfBoundsException();
		}

		sal_Int32 getIndex_Impl( sal_Int32 _nRow, sal_uInt16 _nColumn, sal_uInt16 _nColumnCount )
		{
			return _nRow * _nColumnCount + _nColumn;
		}
	}
	using namespace ::com::sun::star::lang;
	using namespace utl;
	using namespace comphelper;
	using ::rtl::OUString;
	using ::accessibility::AccessibleGridControl;
	using namespace ::com::sun::star::uno;
	using ::com::sun::star::accessibility::XAccessible;
	using namespace ::com::sun::star::accessibility;
	using namespace ::svt;
	using namespace ::svt::table;


	// =============================================================================
	// = AccessibleGridControlCell
	// =============================================================================
	// -----------------------------------------------------------------------------
	AccessibleGridControlCell::AccessibleGridControlCell(
			const Reference< XAccessible >& _rxParent, IAccessibleTable& _rTable,
            sal_Int32 _nRowPos, sal_uInt16 _nColPos, AccessibleTableControlObjType _eType )
        :AccessibleGridControlBase( _rxParent, _rTable, _eType )
		,m_nRowPos( _nRowPos )
		,m_nColPos( _nColPos )
	{
		// set accessible name here, because for that we need the position of the cell
		// and so the base class isn't capable of doing this
		::rtl::OUString aAccName;
		if(_eType == TCTYPE_TABLECELL)
			aAccName = _rTable.GetAccessibleObjectName( TCTYPE_TABLECELL, _nRowPos, _nColPos );
		else if(_eType == TCTYPE_ROWHEADERCELL)
			aAccName = _rTable.GetAccessibleObjectName( TCTYPE_ROWHEADERCELL, _nRowPos, 0 );
		else if(_eType == TCTYPE_COLUMNHEADERCELL)
			aAccName = _rTable.GetAccessibleObjectName( TCTYPE_COLUMNHEADERCELL, 0, _nRowPos );
		implSetName( aAccName );
	}

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

	// -----------------------------------------------------------------------------
	void SAL_CALL AccessibleGridControlCell::grabFocus() throw ( RuntimeException )
	{
		TCSolarGuard aSolarGuard;
		::osl::MutexGuard aGuard( getOslMutex() );
		m_aTable.GoToCell( m_nColPos, m_nRowPos );
	}
	//// -----------------------------------------------------------------------------
	// implementation of a table cell
	::rtl::OUString AccessibleGridControlTableCell::implGetText()
	{
		ensureIsAlive();
		return m_aTable.GetAccessibleCellText( getRowPos(),  getColumnPos() );
	}

	::com::sun::star::lang::Locale AccessibleGridControlTableCell::implGetLocale()
	{
		ensureIsAlive();
		return m_aTable.GetAccessible()->getAccessibleContext()->getLocale();
	}

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

	AccessibleGridControlTableCell::AccessibleGridControlTableCell(const Reference<XAccessible >& _rxParent,
								IAccessibleTable& _rTable,
								sal_Int32 _nRowPos,
								sal_uInt16 _nColPos,
								AccessibleTableControlObjType  eObjType)
		:AccessibleGridControlCell( _rxParent, _rTable, _nRowPos, _nColPos, eObjType )
	{
	}

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

	/** Queries for a new interface. */
	::com::sun::star::uno::Any SAL_CALL AccessibleGridControlTableCell::queryInterface(
			const ::com::sun::star::uno::Type& rType )
		throw ( ::com::sun::star::uno::RuntimeException )
	{
		Any aRet = AccessibleGridControlCell::queryInterface(rType);
		if ( !aRet.hasValue() )
			aRet = AccessibleTextHelper_BASE::queryInterface(rType);
		return aRet;
	}

	/** Aquires the object (calls acquire() on base class). */
	void SAL_CALL AccessibleGridControlTableCell::acquire() throw ()
	{
		AccessibleGridControlCell::acquire();
	}

	/** Releases the object (calls release() on base class). */
	void SAL_CALL AccessibleGridControlTableCell::release() throw ()
	{
		AccessibleGridControlCell::release();
	}

	::com::sun::star::awt::Rectangle SAL_CALL AccessibleGridControlTableCell::getCharacterBounds( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException)
	{
		TCSolarGuard aSolarGuard;
		::osl::MutexGuard aGuard( getOslMutex() );

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

		::com::sun::star::awt::Rectangle aRect;

		if ( &m_aTable )
			aRect = AWTRectangle( m_aTable.GetFieldCharacterBounds( getRowPos(), getColumnPos(), nIndex ) );
		return aRect;
	}

	sal_Int32 SAL_CALL AccessibleGridControlTableCell::getIndexAtPoint( const ::com::sun::star::awt::Point& _aPoint ) throw (RuntimeException)
	{
		TCSolarGuard aSolarGuard;
		::osl::MutexGuard aGuard( getOslMutex() );
		ensureIsAlive();

		return m_aTable.GetFieldIndexAtPoint( getRowPos(), getColumnPos(), VCLPoint( _aPoint ) );
	}

	/** @return
			The name of this class.
	*/
	::rtl::OUString SAL_CALL AccessibleGridControlTableCell::getImplementationName()
		throw ( ::com::sun::star::uno::RuntimeException )
	{
		return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.accessibility.AccessibleGridControlTableCell" ) );
	}

	/** @return  The count of visible children. */
	sal_Int32 SAL_CALL AccessibleGridControlTableCell::getAccessibleChildCount()
		throw ( ::com::sun::star::uno::RuntimeException )
	{
		return 0;
	}

	/** @return  The XAccessible interface of the specified child. */
	::com::sun::star::uno::Reference<
		::com::sun::star::accessibility::XAccessible > SAL_CALL
		AccessibleGridControlTableCell::getAccessibleChild( sal_Int32 )
			throw ( ::com::sun::star::lang::IndexOutOfBoundsException,
					::com::sun::star::uno::RuntimeException )
	{
		throw ::com::sun::star::lang::IndexOutOfBoundsException();
	}

	/** Creates a new AccessibleStateSetHelper and fills it with states of the
		current object.
		@return
			A filled AccessibleStateSetHelper.
	*/
	::utl::AccessibleStateSetHelper* AccessibleGridControlTableCell::implCreateStateSetHelper()
	{
		TCSolarGuard aSolarGuard;
		::osl::MutexGuard aGuard( getOslMutex() );

		::utl::AccessibleStateSetHelper* pStateSetHelper = new ::utl::AccessibleStateSetHelper;

		if( isAlive() )
		{
			// SHOWING done with mxParent
			if( implIsShowing() )
				pStateSetHelper->AddState( AccessibleStateType::SHOWING );

			m_aTable.FillAccessibleStateSetForCell( *pStateSetHelper, getRowPos(), static_cast< sal_uInt16 >( getColumnPos() ) );
		}
		else
			pStateSetHelper->AddState( AccessibleStateType::DEFUNC );

		return pStateSetHelper;
	}


	// XAccessible ------------------------------------------------------------

	/** @return  The XAccessibleContext interface of this object. */
	Reference< XAccessibleContext > SAL_CALL AccessibleGridControlTableCell::getAccessibleContext() throw ( RuntimeException )
	{
		ensureIsAlive();
		return this;
	}

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

	sal_Int32 SAL_CALL AccessibleGridControlTableCell::getAccessibleIndexInParent()
			throw ( ::com::sun::star::uno::RuntimeException )
	{
		TCSolarGuard aSolarGuard;
		::osl::MutexGuard aGuard( getOslMutex() );
		ensureIsAlive();

        return ( getRowPos() * m_aTable.GetColumnCount() ) + getColumnPos();
	}

	sal_Int32 SAL_CALL AccessibleGridControlTableCell::getCaretPosition(  ) throw (::com::sun::star::uno::RuntimeException)
	{
		return -1;
	}
	sal_Bool SAL_CALL AccessibleGridControlTableCell::setCaretPosition ( sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
	{
		TCSolarGuard aSolarGuard;
		::osl::MutexGuard aGuard( getOslMutex() );

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

		return sal_False;
	}
	sal_Unicode SAL_CALL AccessibleGridControlTableCell::getCharacter( sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
	{
		TCSolarGuard aSolarGuard;
		::osl::MutexGuard aGuard( getOslMutex() );
		return OCommonAccessibleText::getCharacter( nIndex );
	}
	::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > SAL_CALL AccessibleGridControlTableCell::getCharacterAttributes( sal_Int32 nIndex, const ::com::sun::star::uno::Sequence< ::rtl::OUString >& ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
	{
		TCSolarGuard aSolarGuard;
		::osl::MutexGuard aGuard( getOslMutex() );

		::rtl::OUString sText( implGetText() );

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

		return ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >();
	}
	sal_Int32 SAL_CALL AccessibleGridControlTableCell::getCharacterCount(  ) throw (::com::sun::star::uno::RuntimeException)
	{
		TCSolarGuard aSolarGuard;
		::osl::MutexGuard aGuard( getOslMutex() );
		return OCommonAccessibleText::getCharacterCount(  );
	}

	::rtl::OUString SAL_CALL AccessibleGridControlTableCell::getSelectedText(  ) throw (::com::sun::star::uno::RuntimeException)
	{
		TCSolarGuard aSolarGuard;
		::osl::MutexGuard aGuard( getOslMutex() );
		return OCommonAccessibleText::getSelectedText(  );
	}
	sal_Int32 SAL_CALL AccessibleGridControlTableCell::getSelectionStart(  ) throw (::com::sun::star::uno::RuntimeException)
	{
		TCSolarGuard aSolarGuard;
		::osl::MutexGuard aGuard( getOslMutex() );
		return OCommonAccessibleText::getSelectionStart(  );
	}
	sal_Int32 SAL_CALL AccessibleGridControlTableCell::getSelectionEnd(  ) throw (::com::sun::star::uno::RuntimeException)
	{
		TCSolarGuard aSolarGuard;
		::osl::MutexGuard aGuard( getOslMutex() );
		return OCommonAccessibleText::getSelectionEnd(  );
	}
	sal_Bool SAL_CALL AccessibleGridControlTableCell::setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
	{
		TCSolarGuard aSolarGuard;
		::osl::MutexGuard aGuard( getOslMutex() );
		if ( !implIsValidRange( nStartIndex, nEndIndex, implGetText().getLength() ) )
			throw IndexOutOfBoundsException();

		return sal_False;
	}
	::rtl::OUString SAL_CALL AccessibleGridControlTableCell::getText(  ) throw (::com::sun::star::uno::RuntimeException)
	{
		TCSolarGuard aSolarGuard;
		::osl::MutexGuard aGuard( getOslMutex() );
		return OCommonAccessibleText::getText(  );
	}
	::rtl::OUString SAL_CALL AccessibleGridControlTableCell::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
	{
		TCSolarGuard aSolarGuard;
		::osl::MutexGuard aGuard( getOslMutex() );
		return OCommonAccessibleText::getTextRange( nStartIndex, nEndIndex );
	}
	::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleGridControlTableCell::getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
	{
		TCSolarGuard aSolarGuard;
		::osl::MutexGuard aGuard( getOslMutex() );
		return OCommonAccessibleText::getTextAtIndex( nIndex ,aTextType);
	}
	::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleGridControlTableCell::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
	{
		TCSolarGuard aSolarGuard;
		::osl::MutexGuard aGuard( getOslMutex() );
		return OCommonAccessibleText::getTextBeforeIndex( nIndex ,aTextType);
	}
	::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleGridControlTableCell::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
	{
		TCSolarGuard aSolarGuard;
		::osl::MutexGuard aGuard( getOslMutex() );
		return OCommonAccessibleText::getTextBehindIndex( nIndex ,aTextType);
	}
	sal_Bool SAL_CALL AccessibleGridControlTableCell::copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
	{
		TCSolarGuard aSolarGuard;
		::osl::MutexGuard aGuard( getOslMutex() );
		::rtl::OUString sText = implGetText();
		checkIndex_Impl( nStartIndex, sText );
		checkIndex_Impl( nEndIndex, sText );

		//!!! don't know how to put a string into the clipboard
		return sal_False;
	}

	Rectangle AccessibleGridControlTableCell::implGetBoundingBox()
	{
		Window* pParent = m_aTable.GetAccessibleParentWindow();
		DBG_ASSERT( pParent, "implGetBoundingBox - missing parent window" );
		Rectangle aGridRect = m_aTable.GetWindowExtentsRelative( pParent );
		sal_Int32 nIndex = getAccessibleIndexInParent();
		Rectangle aCellRect = m_aTable.calcCellRect(nIndex%m_aTable.GetColumnCount(), nIndex/m_aTable.GetColumnCount());
		long nX = aGridRect.Left() + aCellRect.Left();
		long nY = aGridRect.Top() + aCellRect.Top();
		Rectangle aCell( Point( nX, nY ), aCellRect.GetSize());
		return aCell;
	}
	// -----------------------------------------------------------------------------
	Rectangle AccessibleGridControlTableCell::implGetBoundingBoxOnScreen()
	{
		Rectangle aGridRect = m_aTable.GetWindowExtentsRelative( NULL );
		sal_Int32 nIndex = getAccessibleIndexInParent();
		Rectangle aCellRect = m_aTable.calcCellRect(nIndex%m_aTable.GetColumnCount(), nIndex/m_aTable.GetColumnCount());
		long nX = aGridRect.Left() + aCellRect.Left();
		long nY = aGridRect.Top() + aCellRect.Top();
		Rectangle aCell( Point( nX, nY ), aCellRect.GetSize());
		return aCell;
	}
}
