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

#ifndef _COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLEROLE_HPP_
#include <com/sun/star/accessibility/AccessibleRole.hpp>
#endif
#ifndef _COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLEEVENTID_HPP_
#include <com/sun/star/accessibility/AccessibleEventId.hpp>
#endif
#ifndef _UTL_ACCESSIBLESTATESETHELPER_HXX_
#include <unotools/accessiblestatesethelper.hxx>
#endif
#ifndef _COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLESTATETYPE_HPP_
#include <com/sun/star/accessibility/AccessibleStateType.hpp>
#endif

#ifndef	_COM_SUN_STAR_BEANS_PROPERTYCHANGEEVENT_HPP_
#include <com/sun/star/beans/PropertyChangeEvent.hpp>
#endif

#ifndef _COM_SUN_STAR_AWT_XWINDOW_HPP_
#include <com/sun/star/awt/XWindow.hpp>
#endif

#ifndef _CPPUHELPER_TYPEPROVIDER_HXX_
#include <cppuhelper/typeprovider.hxx>
#endif

#ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
#include <toolkit/helper/vclunohelper.hxx>
#endif
#ifndef _TOOLKIT_HELPER_CONVERT_HXX_
#include <toolkit/helper/convert.hxx>
#endif

#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif

#ifndef _OSL_MUTEX_HXX_
#include <osl/mutex.hxx>
#endif
#ifndef _RTL_UUID_H_
#include <rtl/uuid.h>
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef _SV_GEN_HXX
#include <tools/gen.hxx>
#endif

#include <svx/dialogs.hrc>
#include "accessibility.hrc"
#include <svx/dlgctrl.hxx>

#ifndef _SVX_DIALMGR_HXX
#include <svx/dialmgr.hxx>
#endif
#ifndef COMPHELPER_ACCESSIBLE_EVENT_NOTIFIER
#include <comphelper/accessibleeventnotifier.hxx>
#endif

#include <unotools/accessiblerelationsethelper.hxx>

#ifndef _SVXPIXELACCESSIBLECONTEXT_HXX
#include "svxpixelctlaccessiblecontext.hxx"
#endif
#ifndef _COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLERELATIONTYPE_HPP_
#include <com/sun/star/accessibility/AccessibleRelationType.hpp>
#endif
using namespace ::cppu;
using namespace ::osl;
using namespace	::rtl;
using namespace	::com::sun::star;
using namespace	::com::sun::star::uno;
using namespace	::com::sun::star::accessibility;

SvxPixelCtlAccessible::SvxPixelCtlAccessible( SvxPixelCtl& rControl) :
	SvxPixelCtlAccessible_BASE(m_aMutex),
    pPixelCtl(&rControl),
    mnClientId(0)
{
    //FreeResource();
}

SvxPixelCtlAccessible::~SvxPixelCtlAccessible()
{
//	DBG_DTOR( SvxPixelCtlAccessible, NULL );

	if( IsAlive() )
	{
		osl_incrementInterlockedCount( &m_refCount );
		dispose();		// set mpRepr = NULL & release all childs
	}
}
/*-- 04.02.2002 14:11:55---------------------------------------------------

  -----------------------------------------------------------------------*/
uno::Reference< XAccessibleContext > SvxPixelCtlAccessible::getAccessibleContext(  )
    throw (uno::RuntimeException)
{
    return this;
}

sal_Int32 SvxPixelCtlAccessible::getAccessibleChildCount(  ) throw (uno::RuntimeException)
{
    ::osl::MutexGuard	aGuard( m_aMutex );
    IsValid();
	if(pPixelCtl)
	{
	    return pPixelCtl->GetSquares();
	}
	else
		return 0;
}
/*-- 04.02.2002 14:11:56---------------------------------------------------

  -----------------------------------------------------------------------*/
uno::Reference< XAccessible > SvxPixelCtlAccessible::getAccessibleChild( sal_Int32 i )
    throw (uno::RuntimeException)
{
    ::osl::MutexGuard	aGuard( m_aMutex );
    IsValid();
    if ( i < 0 || i >= getAccessibleChildCount())
	throw lang::IndexOutOfBoundsException();
    uno::Reference <XAccessible> xAcc;
    if(pPixelCtl)
	{
		return CreateChild(i, pPixelCtl->IndexToPoint(i));
	}
    else
		return xAcc;
    /*
    throw lang::IndexOutOfBoundsException (
        ::rtl::OUString::createFromAscii ("no child with index " + i),
		NULL);
    */		
}



uno::Reference< XAccessible > SvxPixelCtlAccessible::getAccessibleParent(  )
    throw (uno::RuntimeException)
{
    ::osl::MutexGuard	aGuard( m_aMutex );
    IsValid();
    uno::Reference< XAccessible > xRet;
    if(pPixelCtl)
	    xRet = pPixelCtl->GetParent()->GetAccessible( sal_True );
    return xRet;
}

sal_Int32 SvxPixelCtlAccessible::getAccessibleIndexInParent(  )
    throw (uno::RuntimeException)
{
    ::osl::MutexGuard	aGuard( m_aMutex );
    IsValid();
    sal_uInt16 nIdx = 0;
    if(pPixelCtl)
    {
        Window* pTabPage = pPixelCtl->GetParent();
        sal_uInt16 nChildren = pTabPage->GetChildCount();
        for(nIdx = 0; nIdx < nChildren; nIdx++)
            if(pTabPage->GetChild( nIdx ) == pPixelCtl)
                break;
    }
    return nIdx;
}
/*-- 04.02.2002 14:11:57---------------------------------------------------

  -----------------------------------------------------------------------*/
sal_Int16 SvxPixelCtlAccessible::getAccessibleRole(  ) throw (uno::RuntimeException)
{
    return AccessibleRole::LIST;
}

::rtl::OUString SvxPixelCtlAccessible::getAccessibleDescription(  )
    throw (uno::RuntimeException)
{

    ::osl::MutexGuard	aGuard( m_aMutex );
    IsValid();
    if(pPixelCtl)
	return pPixelCtl->GetAccessibleDescription();
    else
	return String();

}

::rtl::OUString SvxPixelCtlAccessible::getAccessibleName(  )
    throw (uno::RuntimeException)
{
	
    ::osl::MutexGuard	aGuard( m_aMutex );
    IsValid();
    if(pPixelCtl)
	    return pPixelCtl->GetAccessibleName();
    else
	    return String();

}

uno::Reference< XAccessibleRelationSet > SvxPixelCtlAccessible::getAccessibleRelationSet(  )
    throw (uno::RuntimeException)
{
    ::osl::MutexGuard	aGuard( m_aMutex );
    IsValid();
	Window* pWindow = (Window*)pPixelCtl;
	utl::AccessibleRelationSetHelper* rRelationSet = new utl::AccessibleRelationSetHelper;
	uno::Reference< accessibility::XAccessibleRelationSet > rSet = rRelationSet;
	if ( pWindow )
	{
		Window *pLabeledBy = pWindow->GetAccessibleRelationLabeledBy();
		if ( pLabeledBy && pLabeledBy != pWindow )
		{
			uno::Sequence< uno::Reference< uno::XInterface > > aSequence(1);
			aSequence[0] = pLabeledBy->GetAccessible();
			rRelationSet->AddRelation( accessibility::AccessibleRelation( accessibility::AccessibleRelationType::LABELED_BY, aSequence ) );
		}

		Window* pMemberOf = pWindow->GetAccessibleRelationMemberOf();
		if ( pMemberOf && pMemberOf != pWindow )
		{
			uno::Sequence< uno::Reference< uno::XInterface > > aSequence(1);
			aSequence[0] = pMemberOf->GetAccessible();
			rRelationSet->AddRelation( accessibility::AccessibleRelation( accessibility::AccessibleRelationType::MEMBER_OF, aSequence ) );
		}
		return rSet;
	}
    
    return new utl::AccessibleRelationSetHelper;
}


uno::Reference< XAccessibleStateSet > SvxPixelCtlAccessible::getAccessibleStateSet(  )
    throw (uno::RuntimeException)
{
    ::osl::MutexGuard	aGuard( m_aMutex );
    utl::AccessibleStateSetHelper* pStateSetHelper = new utl::AccessibleStateSetHelper;
    uno::Reference< XAccessibleStateSet > xRet = pStateSetHelper;
	
    if(!pPixelCtl)
        pStateSetHelper->AddState(AccessibleStateType::DEFUNC);
    else
    {
        const sal_Int16 aStandardStates[] =
        {
            AccessibleStateType::FOCUSABLE,
				AccessibleStateType::SELECTABLE,
				AccessibleStateType::SHOWING,
				AccessibleStateType::VISIBLE,
				AccessibleStateType::OPAQUE,
				0};
			
			sal_Int16 nState = 0;
			while(aStandardStates[nState])
			{
				pStateSetHelper->AddState(aStandardStates[nState++]);
			}
			if(pPixelCtl->IsEnabled())
				pStateSetHelper->AddState(AccessibleStateType::ENABLED);
			if(pPixelCtl->HasFocus())
				pStateSetHelper->AddState(AccessibleStateType::FOCUSED);
			pStateSetHelper->AddState(AccessibleStateType::MANAGES_DESCENDANTS);	
    }
    return xRet;
}


com::sun::star::lang::Locale SvxPixelCtlAccessible::getLocale(  )
    throw (IllegalAccessibleComponentStateException, uno::RuntimeException)
{
	::osl::MutexGuard	aGuard( m_aMutex );
	if( getAccessibleParent().is() )
    {
    	uno::Reference< XAccessibleContext >		xParentContext( getAccessibleParent()->getAccessibleContext() );
        if( xParentContext.is() )
	    	return xParentContext->getLocale();
    }

    //	No locale and no parent.  Therefore throw exception to indicate this
    //	cluelessness.
    throw IllegalAccessibleComponentStateException();
}


sal_Bool SvxPixelCtlAccessible::containsPoint( const awt::Point& aPt )
    throw (uno::RuntimeException)
{
    ::osl::MutexGuard	aGuard( m_aMutex );
    IsValid();
    Point aPoint(aPt.X, aPt.Y);
    if(pPixelCtl)
	    return (aPoint.X() >= 0)
	        && (aPoint.X() < pPixelCtl->GetSizePixel().getWidth())
	        && (aPoint.Y() >= 0)
	        && (aPoint.Y() < pPixelCtl->GetSizePixel().getHeight());
    else
	    return sal_False;
}
uno::Reference<XAccessible > SAL_CALL SvxPixelCtlAccessible::getAccessibleAtPoint (
        const awt::Point& aPoint) 
    throw (uno::RuntimeException)
{
	::osl::MutexGuard	aGuard( m_aMutex );
	ensureIsAlive();
	uno::Reference <XAccessible> xAcc;

	Point childPoint;
	childPoint.X() = aPoint.X;
	childPoint.Y() = aPoint.Y;

    if(pPixelCtl)
   	{
		Point pt= pPixelCtl->PixelToLogic(childPoint);
		long nIndex = pPixelCtl->PointToIndex(pt);
	    return CreateChild(nIndex,pPixelCtl->IndexToPoint(nIndex));
    }
    else
	   return xAcc;

}

awt::Rectangle SvxPixelCtlAccessible::getBounds(  ) throw (uno::RuntimeException)
{
    ::osl::MutexGuard	aGuard( m_aMutex );
    IsValid();
    Size aSz;
    Point aPos(0,0);
    awt::Rectangle aRet;
	if(pPixelCtl)
	{
	    aSz = pPixelCtl->GetSizePixel();	
	    aPos = pPixelCtl->GetPosPixel();
	    aRet.X = aPos.X();
	    aRet.Y = aPos.Y();
	    aRet.Width = aSz.Width();
	    aRet.Height = aSz.Height();
	}
    return aRet;
}

awt::Point SvxPixelCtlAccessible::getLocation(  ) throw (uno::RuntimeException)
{
    ::osl::MutexGuard	aGuard( m_aMutex );
    IsValid();
    Point aPos;
    aPos = pPixelCtl->GetPosPixel();
    awt::Point aRet(aPos.X(), aPos.Y());
    return aRet;
}

awt::Point SvxPixelCtlAccessible::getLocationOnScreen(  ) throw (uno::RuntimeException)
{
    ::osl::MutexGuard	aGuard( m_aMutex );
    IsValid();
    Rectangle rect;
    rect = pPixelCtl->GetWindowExtentsRelative(NULL);
    awt::Point aRet(rect.Left(),rect.Top() );
    return aRet;
}

awt::Size SvxPixelCtlAccessible::getSize(  ) throw (uno::RuntimeException)
{
    ::osl::MutexGuard	aGuard( m_aMutex );
    IsValid();
    Size aSz;
    aSz = pPixelCtl->GetSizePixel();
    awt::Size aRet(aSz.Width(),aSz.Height());
    return aRet;
}
void SvxPixelCtlAccessible::grabFocus(  ) throw (uno::RuntimeException)
{
    ::osl::MutexGuard	aGuard( m_aMutex );
    IsValid();
    if(pPixelCtl)
	pPixelCtl->GrabFocus();
}

sal_Int32 SvxPixelCtlAccessible::getForeground(  )
        throw (::com::sun::star::uno::RuntimeException)
{
    uno::Any aRet;
    ::osl::MutexGuard	aGuard( m_aMutex );
    IsValid();
    return pPixelCtl->GetControlForeground().GetColor();
}

sal_Int32 SvxPixelCtlAccessible::getBackground(  )
        throw (::com::sun::star::uno::RuntimeException)
{
    uno::Any aRet;
    ::osl::MutexGuard	aGuard( m_aMutex );
    IsValid();
    return pPixelCtl->GetControlBackground().GetColor();
}

::rtl::OUString SvxPixelCtlAccessible::getImplementationName(  ) throw (uno::RuntimeException)
{
    return rtl::OUString::createFromAscii("SvxPixelCtlAccessible");
}
/*-- 04.02.2002 14:12:05---------------------------------------------------

  -----------------------------------------------------------------------*/
const sal_Char sAccessible[]          = "Accessible";
const sal_Char sAccessibleContext[]   = "AccessibleContext";
const sal_Char sAccessibleComponent[] = "AccessibleComponent";
//const sal_Char sAccessibleTable[] = "AccessibleTable";

sal_Bool SvxPixelCtlAccessible::supportsService( const ::rtl::OUString& rServiceName )
    throw (uno::RuntimeException)
{
    return  rServiceName.equalsAsciiL( sAccessible         , sizeof(sAccessible         )-1 ) ||
            rServiceName.equalsAsciiL( sAccessibleContext  , sizeof(sAccessibleContext  )-1 ) ||
            rServiceName.equalsAsciiL( sAccessibleComponent, sizeof(sAccessibleComponent)-1 );// ||
//            rServiceName.equalsAsciiL( sAccessibleTable, sizeof(sAccessibleTable)-1 );
}
/*-- 04.02.2002 14:12:05---------------------------------------------------

  -----------------------------------------------------------------------*/
uno::Sequence< ::rtl::OUString > SvxPixelCtlAccessible::getSupportedServiceNames(  )
    throw (uno::RuntimeException)
{
    uno::Sequence< OUString > aRet(2);
	OUString* pArray = aRet.getArray();
    pArray[0] = OUString( RTL_CONSTASCII_USTRINGPARAM(sAccessible         ) );
    pArray[1] = OUString( RTL_CONSTASCII_USTRINGPARAM(sAccessibleContext  ) );
    pArray[2] = OUString( RTL_CONSTASCII_USTRINGPARAM(sAccessibleComponent) );
//    pArray[3] = OUString( RTL_CONSTASCII_USTRINGPARAM(sAccessibleTable) );
    return aRet;
}

// -----------------------------------------------------------------------------
// XAccessibleSelection
// -----------------------------------------------------------------------------
void SAL_CALL SvxPixelCtlAccessible::selectAccessibleChild( sal_Int32 nChildIndex ) throw (lang::IndexOutOfBoundsException, RuntimeException)
{
    ::osl::MutexGuard	aGuard( m_aMutex );
    IsValid();
	
	if ( nChildIndex < 0 || nChildIndex >= getAccessibleChildCount())
		throw lang::IndexOutOfBoundsException();

	long nIndex = pPixelCtl->ShowPosition(pPixelCtl->IndexToPoint(nChildIndex));
	NotifyChild(nIndex,sal_True,sal_False);
}
// -----------------------------------------------------------------------------
sal_Bool SAL_CALL SvxPixelCtlAccessible::isAccessibleChildSelected( sal_Int32 nChildIndex ) throw (lang::IndexOutOfBoundsException, RuntimeException)
{
    ::osl::MutexGuard	aGuard( m_aMutex );
	
    IsValid();

	return pPixelCtl->GetFoucsPosIndex() == nChildIndex;
}
// -----------------------------------------------------------------------------
void SAL_CALL SvxPixelCtlAccessible::clearAccessibleSelection(  ) throw (RuntimeException)
{
    ::osl::MutexGuard	aGuard( m_aMutex );
	
    IsValid();
	
}
// -----------------------------------------------------------------------------
void SAL_CALL SvxPixelCtlAccessible::selectAllAccessibleChildren(  ) throw (RuntimeException)
{
    ::osl::MutexGuard	aGuard( m_aMutex );
	
    IsValid();
	
}
// -----------------------------------------------------------------------------
sal_Int32 SAL_CALL SvxPixelCtlAccessible::getSelectedAccessibleChildCount(  ) throw (RuntimeException)
{
    ::osl::MutexGuard	aGuard( m_aMutex );
	
    IsValid();
	
	return 1;
}
// -----------------------------------------------------------------------------
uno::Reference< XAccessible > SAL_CALL SvxPixelCtlAccessible::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (lang::IndexOutOfBoundsException, RuntimeException)
{
    ::osl::MutexGuard	aGuard( m_aMutex );
	
    IsValid();
	
	if ( nSelectedChildIndex >= 1)
		throw lang::IndexOutOfBoundsException();
	
	uno::Reference< XAccessible > xChild;
	if(pPixelCtl)
	{
		if(m_xCurChild.is())
		{
			xChild = m_xCurChild;
		}
	}
	return xChild;
}
// -----------------------------------------------------------------------------
void SAL_CALL SvxPixelCtlAccessible::deselectAccessibleChild( sal_Int32 ) throw (lang::IndexOutOfBoundsException, RuntimeException)
{
    ::osl::MutexGuard	aGuard( m_aMutex );
	
    IsValid();
	
	
}

// Added by lq
void SvxPixelCtlAccessible::ensureIsAlive() const
    throw ( lang::DisposedException )
{
    if( !IsAlive() )
        throw lang::DisposedException();
}

void SvxPixelCtlAccessible::ensureIsValidRow( sal_Int32 nRow )
    throw ( lang::IndexOutOfBoundsException )
{
    if( nRow >= pPixelCtl->GetHeight() || nRow <0)
        throw lang::IndexOutOfBoundsException(
            OUString( RTL_CONSTASCII_USTRINGPARAM( "row index is invalid" ) ), *this );
}

void SvxPixelCtlAccessible::ensureIsValidColumn( sal_Int32 nColumn )
    throw ( lang::IndexOutOfBoundsException )
{
    if( nColumn >= pPixelCtl->GetWidth() || nColumn <0 )
        throw lang::IndexOutOfBoundsException(
            OUString( RTL_CONSTASCII_USTRINGPARAM("column index is invalid") ), *this );
}

void SvxPixelCtlAccessible::ensureIsValidAddress(
        sal_Int32 nRow, sal_Int32 nColumn )
    throw ( lang::IndexOutOfBoundsException )
{
    ensureIsValidRow( nRow );
    ensureIsValidColumn( nColumn );
}

void SvxPixelCtlAccessible::ensureIsValidIndex( sal_Int32 nChildIndex )
    throw ( lang::IndexOutOfBoundsException )
{
    if( nChildIndex >=  pPixelCtl->GetSquares())
        throw lang::IndexOutOfBoundsException(
            OUString( RTL_CONSTASCII_USTRINGPARAM("child index is invalid") ), *this );
}

// XAccessibleTable -----------------------------------------------------------
/*
sal_Int32 SAL_CALL SvxPixelCtlAccessible::getAccessibleRowCount()
    throw ( uno::RuntimeException )
{
   ::osl::MutexGuard	aGuard( m_aMutex );
   ensureIsAlive();
    return pPixelCtl->GetLineCount();
}

sal_Int32 SAL_CALL SvxPixelCtlAccessible::getAccessibleColumnCount()
    throw ( uno::RuntimeException )
{
    ::osl::MutexGuard	aGuard( m_aMutex );
    ensureIsAlive();
    return pPixelCtl->GetLineCount();
}

sal_Int32 SAL_CALL SvxPixelCtlAccessible::getAccessibleRowExtentAt(
        sal_Int32 nRow, sal_Int32 nColumn )
    throw ( lang::IndexOutOfBoundsException, uno::RuntimeException )
{
    ::osl::MutexGuard	aGuard( m_aMutex );
    ensureIsAlive();
    return 1;   // merged cells not supported
}

sal_Int32 SAL_CALL SvxPixelCtlAccessible::getAccessibleColumnExtentAt(
        sal_Int32 nRow, sal_Int32 nColumn )
    throw ( lang::IndexOutOfBoundsException, uno::RuntimeException )
{
    ::osl::MutexGuard	aGuard( m_aMutex );
    ensureIsAlive();
    return 1;   // merged cells not supported
}

uno::Reference< XAccessible > SAL_CALL SvxPixelCtlAccessible::getAccessibleCaption()
    throw ( uno::RuntimeException )
{
	uno::Reference< XAccessible > xAccessble;
    ensureIsAlive();
    return xAccessble;    // not supported
}

uno::Reference< XAccessible > SAL_CALL SvxPixelCtlAccessible::getAccessibleSummary()
    throw ( uno::RuntimeException )
{
	uno::Reference< XAccessible > xAccessble;
    ensureIsAlive();
    return xAccessble;    // not supported
}

sal_Int32 SAL_CALL SvxPixelCtlAccessible::getAccessibleIndex(
        sal_Int32 nRow, sal_Int32 nColumn )
    throw ( lang::IndexOutOfBoundsException, uno::RuntimeException )
{
    ::osl::MutexGuard	aGuard( m_aMutex );
    ensureIsAlive();
    ensureIsValidAddress(nRow,nColumn);
    return nRow + nColumn * pPixelCtl->GetLineCount() ;
}

sal_Int32 SAL_CALL SvxPixelCtlAccessible::getAccessibleRow( sal_Int32 nChildIndex )
    throw ( lang::IndexOutOfBoundsException, uno::RuntimeException )
{
    ::osl::MutexGuard	aGuard( m_aMutex );
    ensureIsAlive();
    ensureIsValidIndex( nChildIndex );
    return nChildIndex/pPixelCtl->GetLineCount();
}

sal_Int32 SAL_CALL SvxPixelCtlAccessible::getAccessibleColumn( sal_Int32 nChildIndex )
    throw ( lang::IndexOutOfBoundsException, uno::RuntimeException )
{
    ::osl::MutexGuard	aGuard( m_aMutex );
    ensureIsAlive();
    ensureIsValidIndex( nChildIndex );
    return nChildIndex%pPixelCtl->GetLineCount();
}

::rtl::OUString SAL_CALL SvxPixelCtlAccessible::getAccessibleRowDescription( sal_Int32 nRow )
    throw ( lang::IndexOutOfBoundsException, uno::RuntimeException )
{
    ::osl::MutexGuard	aGuard( m_aMutex );
    ensureIsAlive();
    ensureIsValidRow( nRow );
    return ::rtl::OUString::createFromAscii ("");
}

::rtl::OUString SAL_CALL SvxPixelCtlAccessible::getAccessibleColumnDescription( sal_Int32 nColumn )
    throw ( lang::IndexOutOfBoundsException, uno::RuntimeException )
{
    ::osl::MutexGuard	aGuard( m_aMutex );
    ensureIsAlive();
    ensureIsValidColumn( nColumn );
    return ::rtl::OUString::createFromAscii ("");
}

uno::Reference< XAccessibleTable > SAL_CALL SvxPixelCtlAccessible::getAccessibleRowHeaders()
    throw ( uno::RuntimeException )
{
    ::osl::MutexGuard	aGuard( m_aMutex );
    uno::Reference< XAccessibleTable > xAccessble;
    ensureIsAlive();
    return xAccessble;
}

uno::Reference< XAccessibleTable > SAL_CALL SvxPixelCtlAccessible::getAccessibleColumnHeaders()
    throw ( uno::RuntimeException )
{
    ::osl::MutexGuard	aGuard( m_aMutex );
    uno::Reference< XAccessibleTable > xAccessble;
    ensureIsAlive();
    return xAccessble;
}

Sequence< sal_Int32 > SAL_CALL SvxPixelCtlAccessible::getSelectedAccessibleRows()
    throw ( uno::RuntimeException )
{
    ::osl::MutexGuard	aGuard( m_aMutex );
    Sequence< sal_Int32 > accRows;
    ensureIsAlive();

    return accRows;
}

Sequence< sal_Int32 > SAL_CALL SvxPixelCtlAccessible::getSelectedAccessibleColumns()
    throw ( uno::RuntimeException )
{
    ::osl::MutexGuard	aGuard( m_aMutex );
    Sequence< sal_Int32 > accColumns;
    ensureIsAlive();

    return accColumns;
}

sal_Bool SAL_CALL SvxPixelCtlAccessible::isAccessibleRowSelected( sal_Int32 nRow )
    throw ( lang::IndexOutOfBoundsException, uno::RuntimeException )
{
    ::osl::MutexGuard	aGuard( m_aMutex );
    ensureIsAlive();
    ensureIsValidRow( nRow );
    return sal_False;
}

sal_Bool SAL_CALL SvxPixelCtlAccessible::isAccessibleColumnSelected( sal_Int32 nColumn )
    throw ( lang::IndexOutOfBoundsException, uno::RuntimeException )
{
    ::osl::MutexGuard	aGuard( m_aMutex );
    ensureIsAlive();
    ensureIsValidColumn( nColumn );
    return sal_False;
}

uno::Reference< XAccessible > SAL_CALL SvxPixelCtlAccessible::getAccessibleCellAt(
        sal_Int32 nRow, sal_Int32 nColumn )
    throw ( lang::IndexOutOfBoundsException, uno::RuntimeException )
{
    ::osl::MutexGuard	aGuard( m_aMutex );
    ensureIsAlive();
    ensureIsValidAddress( nRow, nColumn );
    return getAccessibleChild(nRow*pPixelCtl->GetLineCount()+nColumn);
}

sal_Bool SAL_CALL SvxPixelCtlAccessible::isAccessibleSelected(
        sal_Int32 nRow, sal_Int32 nColumn )
    throw ( lang::IndexOutOfBoundsException, uno::RuntimeException )
{
    ::osl::MutexGuard	aGuard( m_aMutex );
    ensureIsAlive();
    ensureIsValidAddress( nRow, nColumn );
    return isAccessibleChildSelected(nRow*pPixelCtl->GetLineCount()+nColumn);
}
// Added by lq end
*/

//XAccessibleEventBroadcaster
void SAL_CALL SvxPixelCtlAccessible::addEventListener( const uno::Reference< XAccessibleEventListener >& xListener )  throw( RuntimeException )
{
	if (xListener.is())
    {
		::osl::MutexGuard	aGuard( m_aMutex );
		if (!mnClientId)
	            mnClientId = comphelper::AccessibleEventNotifier::registerClient( );
		comphelper::AccessibleEventNotifier::addEventListener( mnClientId, xListener );
    }
}

void SAL_CALL SvxPixelCtlAccessible::removeEventListener( const uno::Reference< XAccessibleEventListener >& xListener )
    throw( RuntimeException )
{
	if (xListener.is())
	{
    	::osl::MutexGuard	aGuard( m_aMutex );

        sal_Int32 nListenerCount = comphelper::AccessibleEventNotifier::removeEventListener( mnClientId, xListener );
		if ( !nListenerCount )
		{
			comphelper::AccessibleEventNotifier::revokeClient( mnClientId );
			mnClientId = 0;
		}
	}
}
void SvxPixelCtlAccessible::CommitChange( const AccessibleEventObject& rEvent )
{
	if (mnClientId)
		comphelper::AccessibleEventNotifier::addEvent( mnClientId, rEvent );
}

//Solution:Add the event handling method
void SvxPixelCtlAccessible::FireAccessibleEvent (short nEventId, const ::com::sun::star::uno::Any& rOld, const ::com::sun::star::uno::Any& rNew)
{
	const uno::Reference< XInterface >	xSource( *this );
	CommitChange( AccessibleEventObject( xSource, nEventId, rNew,rOld ) );
}

void SAL_CALL SvxPixelCtlAccessible::disposing()
{
	if( !rBHelper.bDisposed )
	{
		{
			::osl::MutexGuard	aGuard( m_aMutex );
			if ( mnClientId )
			{
				comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( mnClientId, *this );
				mnClientId =  0;
			}
		}
	    //mxParent = uno::Reference< XAccessible >();
	    
	}
}
void SvxPixelCtlAccessible::Invalidate()
{
	pPixelCtl = 0;
}
void SvxPixelCtlAccessible::ThrowExceptionIfNotAlive( void ) throw( lang::DisposedException )
{
	if( IsNotAlive() )
		throw lang::DisposedException();
}
void SvxPixelCtlAccessible::IsValid() throw (uno::RuntimeException)
{
    if(!pPixelCtl)
        throw uno::RuntimeException();
}


void SvxPixelCtlAccessible::NotifyChild(long nIndex,sal_Bool bSelect ,sal_Bool bCheck)
{
	DBG_ASSERT( !(!bSelect && !bCheck),"" );//non is false

	SvxPixelCtlAccessibleChild *pChild= NULL;
	
	if (m_xCurChild.is())
	{
		pChild= static_cast<SvxPixelCtlAccessibleChild*>(m_xCurChild.get());
		DBG_ASSERT(pChild,"Child Must be Valid");
		if (pChild->getAccessibleIndexInParent() == nIndex )
		{
			if (bSelect)
			{
				pChild->SelectChild(sal_True);
			}
			if (bCheck)
			{
				pChild->ChangePixelColorOrBG(sal_Bool(pPixelCtl->GetBitmapPixel(sal_uInt16(nIndex))));
				pChild->CheckChild();
			}
			return ;
		}
	}
	uno::Reference <XAccessible> xNewChild =CreateChild(nIndex, pPixelCtl->IndexToPoint(nIndex));
	SvxPixelCtlAccessibleChild *pNewChild= static_cast<SvxPixelCtlAccessibleChild*>(xNewChild.get());
	DBG_ASSERT(pNewChild,"Child Must be Valid");

	Any aNewValue,aOldValue;
	aNewValue<<= xNewChild;
	FireAccessibleEvent(	AccessibleEventId::ACTIVE_DESCENDANT_CHANGED,
							aOldValue,
							aNewValue );

	if (bSelect)
	{
		if (pChild)
		{
			pChild->SelectChild(sal_False);
		}
		pNewChild->SelectChild(sal_True);
	}
	if (bCheck)
	{
		pNewChild->CheckChild();
	}
	m_xCurChild= xNewChild;


}

uno::Reference<XAccessible> SvxPixelCtlAccessible::CreateChild (long nIndex,Point mPoint)
{
	long nX = mPoint.X();
	long nY = mPoint.Y();
	if( Application::GetSettings().GetLayoutRTL())
	{
	    nX = (sal_uInt16) pPixelCtl->GetWidth() - 1 - nX;
	}

	sal_Bool bPixelColorOrBG= sal_Bool(pPixelCtl->GetBitmapPixel(sal_uInt16(nIndex)));
	Size size(pPixelCtl->GetWidth() / pPixelCtl->GetLineCount(),pPixelCtl->GetHeight() / pPixelCtl->GetLineCount());
	uno::Reference<XAccessible> xChild;
	xChild = new SvxPixelCtlAccessibleChild(pPixelCtl, 
				bPixelColorOrBG, 
				Point(nX,nY),
				Rectangle(mPoint,size),
				this,
				nIndex);

	return xChild;
}


void SvxPixelCtlAccessible::LoseFocus()
{
	m_xCurChild = uno::Reference< XAccessible >() ;
}

void SvxPixelCtlAccessibleChild::CheckChild()
{
	Any aChecked;
	aChecked <<= AccessibleStateType::CHECKED;

	if (m_bPixelColorOrBG)//Current Child State
	{
		FireAccessibleEvent(	AccessibleEventId::STATE_CHANGED,								
								Any(),
								aChecked);
	}
	else
	{
		FireAccessibleEvent(	AccessibleEventId::STATE_CHANGED,
								aChecked,
								Any() );
	}
}

void SvxPixelCtlAccessibleChild::SelectChild( sal_Bool bSelect)
{
	Any aSelected;
	aSelected <<= AccessibleStateType::SELECTED;

	if (bSelect)
	{
		FireAccessibleEvent(	AccessibleEventId::STATE_CHANGED,
								Any(),
								aSelected);
	}
	else
	{
		FireAccessibleEvent(	AccessibleEventId::STATE_CHANGED,
								aSelected,
								Any());
	}
}
void SvxPixelCtlAccessibleChild::FireAccessibleEvent (
	short nEventId, 
	const ::com::sun::star::uno::Any& rOld, 
	const ::com::sun::star::uno::Any& rNew)
{
	const uno::Reference< XInterface >	xSource( *this );
	CommitChange( AccessibleEventObject( xSource, nEventId, rNew,rOld ) );
}



DBG_NAME( SvxPixelCtlAccessibleChild )


SvxPixelCtlAccessibleChild::SvxPixelCtlAccessibleChild(
	SvxPixelCtl* rWindow, 
	sal_Bool bPixelColorOrBG,
	const Point &aPoint,
	const Rectangle& rBoundingBox,
	const uno::Reference<XAccessible>&	rxParent,
	long nIndexInParent ) :
	SvxPixelCtlAccessibleChild_BASE( m_aMutex ),
	mrParentWindow( rWindow ),
	mxParent(rxParent),
	m_bPixelColorOrBG(bPixelColorOrBG),
	maPoint(aPoint),
	mpBoundingBox( new Rectangle( rBoundingBox ) ),
	mnIndexInParent( nIndexInParent ),
	mnClientId( 0 )
{
	DBG_CTOR( SvxPixelCtlAccessibleChild, NULL );
}


SvxPixelCtlAccessibleChild::~SvxPixelCtlAccessibleChild()
{
	DBG_DTOR( SvxPixelCtlAccessibleChild, NULL );

	if( IsAlive() )
	{
		osl_incrementInterlockedCount( &m_refCount );
		dispose();		// set mpRepr = NULL & release all childs
	}
}

//=====  XAccessible  =========================================================

uno::Reference< XAccessibleContext> SAL_CALL SvxPixelCtlAccessibleChild::getAccessibleContext( void ) throw( RuntimeException )
{
	return this;
}

//=====  XAccessibleComponent  ================================================

sal_Bool SAL_CALL SvxPixelCtlAccessibleChild::containsPoint( const awt::Point& rPoint ) throw( RuntimeException )
{
	// no guard -> done in getBounds()
//	return GetBoundingBox().IsInside( VCLPoint( rPoint ) );
	return Rectangle( Point( 0, 0 ), GetBoundingBox().GetSize() ).IsInside( VCLPoint( rPoint ) );
}

uno::Reference< XAccessible > SAL_CALL SvxPixelCtlAccessibleChild::getAccessibleAtPoint( const awt::Point& ) throw( RuntimeException )
{
	return uno::Reference< XAccessible >();
}

awt::Rectangle SAL_CALL SvxPixelCtlAccessibleChild::getBounds() throw( RuntimeException )
{
	// no guard -> done in getBoundingBox()
	//Modified by lq, 09/26
	//return AWTRectangle( GetBoundingBox() );
	awt::Rectangle rect = AWTRectangle( GetBoundingBox() );
	rect.X = rect.X + mrParentWindow->GetClientWindowExtentsRelative(NULL).Left()-mrParentWindow->GetWindowExtentsRelative(NULL).Left();
	rect.Y = rect.Y + mrParentWindow->GetClientWindowExtentsRelative(NULL).Top()-mrParentWindow->GetWindowExtentsRelative(NULL).Top();
	return rect;
	// End
}

awt::Point SAL_CALL SvxPixelCtlAccessibleChild::getLocation() throw( RuntimeException )
{
	// no guard -> done in getBoundingBox()
	return AWTPoint( GetBoundingBox().TopLeft() );
}

awt::Point SAL_CALL SvxPixelCtlAccessibleChild::getLocationOnScreen() throw( RuntimeException )
{
	// no guard -> done in getBoundingBoxOnScreen()
	return AWTPoint( GetBoundingBoxOnScreen().TopLeft() );
}

awt::Size SAL_CALL SvxPixelCtlAccessibleChild::getSize() throw( RuntimeException )
{
	// no guard -> done in getBoundingBox()
	return AWTSize( GetBoundingBox().GetSize() );
}

void SAL_CALL SvxPixelCtlAccessibleChild::grabFocus() throw( RuntimeException )
{
}

sal_Int32 SvxPixelCtlAccessibleChild::getForeground(  ) 
        throw (::com::sun::star::uno::RuntimeException)
{
    //::vos::OGuard       aSolarGuard( Application::GetSolarMutex() );
    ::osl::MutexGuard   aGuard( m_aMutex );
    ThrowExceptionIfNotAlive();
    return mrParentWindow->GetControlForeground().GetColor();
}
sal_Int32 SvxPixelCtlAccessibleChild::getBackground(  ) 
        throw (::com::sun::star::uno::RuntimeException)
{
    //::vos::OGuard       aSolarGuard( Application::GetSolarMutex() );
    ::osl::MutexGuard   aGuard( m_aMutex );

    ThrowExceptionIfNotAlive();
    return mrParentWindow->GetControlBackground().GetColor();
}

//=====  XAccessibleContext  ==================================================

sal_Int32 SAL_CALL SvxPixelCtlAccessibleChild::getAccessibleChildCount( void ) throw( RuntimeException )
{
	return 0;
}

uno::Reference< XAccessible > SAL_CALL SvxPixelCtlAccessibleChild::getAccessibleChild( sal_Int32 ) throw ( RuntimeException )
{
	throw lang::IndexOutOfBoundsException();
}

uno::Reference< XAccessible > SAL_CALL SvxPixelCtlAccessibleChild::getAccessibleParent( void ) throw( RuntimeException )
{
	return mxParent;
}

sal_Int32 SAL_CALL SvxPixelCtlAccessibleChild::getAccessibleIndexInParent( void ) throw( RuntimeException )
{
   return mnIndexInParent;
}

sal_Int16 SAL_CALL SvxPixelCtlAccessibleChild::getAccessibleRole( void ) throw( RuntimeException )
{
	return AccessibleRole::CHECK_BOX;
}

OUString SAL_CALL SvxPixelCtlAccessibleChild::getAccessibleDescription( void ) throw( RuntimeException )
{
	::osl::MutexGuard	aGuard( m_aMutex );

	return  GetName();
}

OUString SAL_CALL SvxPixelCtlAccessibleChild::getAccessibleName( void ) throw( RuntimeException )
{
	::osl::MutexGuard	aGuard( m_aMutex );	
	return  GetName();
}

/**	Return empty uno::Reference to indicate that the relation set is not
	supported.
*/
uno::Reference<XAccessibleRelationSet> SAL_CALL SvxPixelCtlAccessibleChild::getAccessibleRelationSet( void ) throw( RuntimeException )
{
	return uno::Reference< XAccessibleRelationSet >();
}

uno::Reference< XAccessibleStateSet > SAL_CALL SvxPixelCtlAccessibleChild::getAccessibleStateSet( void ) throw( RuntimeException )
{
	::osl::MutexGuard						aGuard( m_aMutex );
	utl::AccessibleStateSetHelper*			pStateSetHelper = new utl::AccessibleStateSetHelper;

	if( IsAlive() )
	{

		pStateSetHelper->AddState( AccessibleStateType::TRANSIENT );
		pStateSetHelper->AddState( AccessibleStateType::ENABLED );
		pStateSetHelper->AddState( AccessibleStateType::OPAQUE );
		pStateSetHelper->AddState( AccessibleStateType::SELECTABLE );
		pStateSetHelper->AddState( AccessibleStateType::SHOWING );
		pStateSetHelper->AddState( AccessibleStateType::VISIBLE );

		if (mrParentWindow )
		{
			long nIndex = mrParentWindow->GetFoucsPosIndex();
			if ( nIndex == mnIndexInParent)
			{
				pStateSetHelper->AddState( AccessibleStateType::SELECTED );
			}
			//IAccessibility2 Implementation 2009-----
			if (mrParentWindow->GetBitmapPixel(sal_uInt16(mnIndexInParent)))
			//-----IAccessibility2 Implementation 2009
			{
				pStateSetHelper->AddState( AccessibleStateType::CHECKED );
			}
		}
	}
	else
		pStateSetHelper->AddState( AccessibleStateType::DEFUNC );

	return pStateSetHelper;
}

lang::Locale SAL_CALL SvxPixelCtlAccessibleChild::getLocale( void ) throw( IllegalAccessibleComponentStateException, RuntimeException )
{
	::osl::MutexGuard						aGuard( m_aMutex );
	if( mxParent.is() )
    {
    	uno::Reference< XAccessibleContext >		xParentContext( mxParent->getAccessibleContext() );
        if( xParentContext.is() )
	    	return xParentContext->getLocale();
    }

    //	No locale and no parent.  Therefore throw exception to indicate this
    //	cluelessness.
    throw IllegalAccessibleComponentStateException();
}

void SAL_CALL SvxPixelCtlAccessibleChild::addEventListener( const uno::Reference< XAccessibleEventListener >& xListener )
    throw( RuntimeException )
{
	if (xListener.is())
    {
    	::osl::MutexGuard	aGuard( m_aMutex );
		if (!mnClientId)
            mnClientId = comphelper::AccessibleEventNotifier::registerClient( );
		comphelper::AccessibleEventNotifier::addEventListener( mnClientId, xListener );
    }
}




void SAL_CALL SvxPixelCtlAccessibleChild::removeEventListener( const uno::Reference< XAccessibleEventListener >& xListener )
    throw( RuntimeException )
{
	if (xListener.is())
	{
    	::osl::MutexGuard	aGuard( m_aMutex );

        sal_Int32 nListenerCount = comphelper::AccessibleEventNotifier::removeEventListener( mnClientId, xListener );
		if ( !nListenerCount )
		{
			// no listeners anymore
			// -> revoke ourself. This may lead to the notifier thread dying (if we were the last client),
			// and at least to us not firing any events anymore, in case somebody calls
			// NotifyAccessibleEvent, again
			comphelper::AccessibleEventNotifier::revokeClient( mnClientId );
			mnClientId = 0;
		}
	}
}


//=====  XServiceInfo  ========================================================

OUString SAL_CALL SvxPixelCtlAccessibleChild::getImplementationName( void ) throw( RuntimeException )
{
	return OUString( RTL_CONSTASCII_USTRINGPARAM( "SvxPixelCtlAccessibleChild" ) );
}

sal_Bool SAL_CALL SvxPixelCtlAccessibleChild::supportsService( const OUString& rServiceName ) throw( RuntimeException )
{
    return  rServiceName.equalsAsciiL( sAccessible         , sizeof(sAccessible         )-1 ) ||
            rServiceName.equalsAsciiL( sAccessibleContext  , sizeof(sAccessibleContext  )-1 ) ||
            rServiceName.equalsAsciiL( sAccessibleComponent, sizeof(sAccessibleComponent)-1 );

}

Sequence< OUString > SAL_CALL SvxPixelCtlAccessibleChild::getSupportedServiceNames( void ) throw( RuntimeException )
{
    uno::Sequence< OUString > aRet(3);
	OUString* pArray = aRet.getArray();
    pArray[0] = OUString( RTL_CONSTASCII_USTRINGPARAM(sAccessible         ) );
    pArray[1] = OUString( RTL_CONSTASCII_USTRINGPARAM(sAccessibleContext  ) );
    pArray[2] = OUString( RTL_CONSTASCII_USTRINGPARAM(sAccessibleComponent) );
    return aRet;
}

//=====  internal  ============================================================

void SvxPixelCtlAccessibleChild::CommitChange( const AccessibleEventObject& rEvent )
{
	if (mnClientId)
		comphelper::AccessibleEventNotifier::addEvent( mnClientId, rEvent );
}

void SAL_CALL SvxPixelCtlAccessibleChild::disposing()
{
	if( !rBHelper.bDisposed )
	{
		::osl::MutexGuard	aGuard( m_aMutex );

        // Send a disposing to all listeners.
	    if ( mnClientId )
	    {
            comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( mnClientId, *this );
		    mnClientId =  0;
	    }

		mxParent = uno::Reference< XAccessible >();
        
	    delete mpBoundingBox;
	}
}

void SvxPixelCtlAccessibleChild::ThrowExceptionIfNotAlive( void ) throw( lang::DisposedException )
{
	if( IsNotAlive() )
		throw lang::DisposedException();
}

Rectangle SvxPixelCtlAccessibleChild::GetBoundingBoxOnScreen( void ) throw( RuntimeException )
{
	::osl::MutexGuard	aGuard( m_aMutex );

	// no ThrowExceptionIfNotAlive() because its done in GetBoundingBox()
	Rectangle			aRect( GetBoundingBox() );

	return Rectangle( mrParentWindow->OutputToAbsoluteScreenPixel( aRect.TopLeft() ), aRect.GetSize() );
}

Rectangle SvxPixelCtlAccessibleChild::GetBoundingBox( void ) throw( RuntimeException )
{
	// no guard neccessary, because no one changes mpBoundingBox after creating it
	ThrowExceptionIfNotAlive();

	return *mpBoundingBox;
}

::rtl::OUString SvxPixelCtlAccessibleChild::GetName()
{
	sal_Int32 nXIndex = mnIndexInParent % mrParentWindow->GetLineCount();
	sal_Int32 nYIndex = mnIndexInParent / mrParentWindow->GetLineCount();
	
	OUString str;
	str += OUString::createFromAscii("(");
	str += OUString::valueOf(nXIndex);
	str += OUString::createFromAscii(",");
	str += OUString::valueOf(nYIndex);
// 	str += OUString::createFromAscii(",");
// 	str += OUString::valueOf(m_bPixelColorOrBG);
	str += OUString::createFromAscii(")");
	return str;
}