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


#include <com/sun/star/accessibility/AccessibleRole.hpp>
#include <com/sun/star/accessibility/AccessibleStateType.hpp>
#include <com/sun/star/accessibility/AccessibleEventId.hpp>
#include <com/sun/star/accessibility/XAccessibleEventListener.hpp>
#include <com/sun/star/accessibility/AccessibleRelationType.hpp>
#include <toolkit/awt/vclxaccessiblecomponent.hxx>
#include <toolkit/helper/externallock.hxx>
#include <toolkit/awt/vclxwindow.hxx>
#include <toolkit/helper/convert.hxx>
#include <toolkit/awt/vclxfont.hxx>
#include <vcl/dialog.hxx>
#include <vcl/window.hxx>
//Solution:Need methods in Edit.
#include <vcl/edit.hxx>
#include <tools/debug.hxx>
#include <unotools/accessiblestatesethelper.hxx>
#include <unotools/accessiblerelationsethelper.hxx>
#include <vcl/svapp.hxx>
#include <vcl/menu.hxx>

#ifndef VCLEVENT_WINDOW_FRAMETITLECHANGED
#define VCLEVENT_WINDOW_FRAMETITLECHANGED   1018    // pData = XubString* = oldTitle
#endif

using namespace ::com::sun::star;
using namespace ::comphelper;


DBG_NAME(VCLXAccessibleComponent)


//	----------------------------------------------------
//	class VCLXAccessibleComponent
//	----------------------------------------------------
VCLXAccessibleComponent::VCLXAccessibleComponent( VCLXWindow* pVCLXindow )
	: AccessibleExtendedComponentHelper_BASE( new VCLExternalSolarLock() )
	, OAccessibleImplementationAccess( )
{
	DBG_CTOR( VCLXAccessibleComponent, 0 );
	mpVCLXindow = pVCLXindow;
	mxWindow = pVCLXindow;

	m_pSolarLock = static_cast< VCLExternalSolarLock* >( getExternalLock( ) );

	DBG_ASSERT( pVCLXindow->GetWindow(), "VCLXAccessibleComponent - no window!" );
	if ( pVCLXindow->GetWindow() )
    {
	  pVCLXindow->GetWindow()->AddEventListener( LINK( this, VCLXAccessibleComponent, WindowEventListener ) );
	  pVCLXindow->GetWindow()->AddChildEventListener( LINK( this, VCLXAccessibleComponent, WindowChildEventListener ) );
    }

	// announce the XAccessible of our creator to the base class
	lateInit( pVCLXindow );
}

VCLXAccessibleComponent::~VCLXAccessibleComponent()
{
	DBG_DTOR( VCLXAccessibleComponent, 0 );

    ensureDisposed();

	if ( mpVCLXindow && mpVCLXindow->GetWindow() )
    {
		mpVCLXindow->GetWindow()->RemoveEventListener( LINK( this, VCLXAccessibleComponent, WindowEventListener ) );
		mpVCLXindow->GetWindow()->RemoveChildEventListener( LINK( this, VCLXAccessibleComponent, WindowChildEventListener ) );
    }

	delete m_pSolarLock;
	m_pSolarLock = NULL;
	// This is not completely safe. If we assume that the base class dtor calls some method which
	// uses this lock, the we crash. However, as the base class' dtor does not have a chance to call _out_
	// virtual methods, this is no problem as long as the base class is safe, i.e. does not use the external
	// lock from within it's dtor. At the moment, we _know_ the base class is safe in this respect, so
	// let's assume it keeps this way.
	// @see OAccessibleContextHelper::OAccessibleContextHelper( IMutex* )
}

IMPLEMENT_FORWARD_XINTERFACE3( VCLXAccessibleComponent, AccessibleExtendedComponentHelper_BASE, OAccessibleImplementationAccess, VCLXAccessibleComponent_BASE )
IMPLEMENT_FORWARD_XTYPEPROVIDER3( VCLXAccessibleComponent, AccessibleExtendedComponentHelper_BASE, OAccessibleImplementationAccess, VCLXAccessibleComponent_BASE )

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

sal_Bool VCLXAccessibleComponent::supportsService( const ::rtl::OUString& rServiceName ) throw (uno::RuntimeException)
{
	uno::Sequence< ::rtl::OUString > aNames( getSupportedServiceNames() );
	const ::rtl::OUString* pNames = aNames.getConstArray();
	const ::rtl::OUString* pEnd = pNames + aNames.getLength();
	for ( ; pNames != pEnd && !pNames->equals( rServiceName ); ++pNames )
		;

	return pNames != pEnd;
}

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

IMPL_LINK( VCLXAccessibleComponent, WindowEventListener, VclSimpleEvent*, pEvent )
{
	DBG_CHKTHIS(VCLXAccessibleComponent,0);

	DBG_ASSERT( pEvent && dynamic_cast< VclWindowEvent* >(pEvent), "Unknown WindowEvent!" );

        /* Ignore VCLEVENT_WINDOW_ENDPOPUPMODE, because the UNO accessibility wrapper
         * might have been destroyed by the previous VCLEventListener (if no AT tool
         * is running), e.g. sub-toolbars in impress.
         */
	if ( pEvent && dynamic_cast< VclWindowEvent* >(pEvent) && mxWindow.is() /* #122218# */ && (pEvent->GetId() != VCLEVENT_WINDOW_ENDPOPUPMODE) )
	{
		DBG_ASSERT( ((VclWindowEvent*)pEvent)->GetWindow(), "Window???" );
        if( !((VclWindowEvent*)pEvent)->GetWindow()->IsAccessibilityEventsSuppressed() || ( pEvent->GetId() == VCLEVENT_OBJECT_DYING ) )
		{
		    ProcessWindowEvent( *(VclWindowEvent*)pEvent );
		}
	}
	return 0;
}

IMPL_LINK( VCLXAccessibleComponent, WindowChildEventListener, VclSimpleEvent*, pEvent )
{
	DBG_CHKTHIS(VCLXAccessibleComponent,0);

    DBG_ASSERT( pEvent && dynamic_cast< VclWindowEvent* >(pEvent), "Unknown WindowEvent!" );
	if ( pEvent && dynamic_cast< VclWindowEvent* >(pEvent) && mxWindow.is() /* #i68079# */ )
	{
		DBG_ASSERT( ((VclWindowEvent*)pEvent)->GetWindow(), "Window???" );
        if( !((VclWindowEvent*)pEvent)->GetWindow()->IsAccessibilityEventsSuppressed() )
		{
			// #103087# to prevent an early release of the component
			uno::Reference< accessibility::XAccessibleContext > xTmp = this;

		    ProcessWindowChildEvent( *(VclWindowEvent*)pEvent );
		}
	}
	return 0;
}

uno::Reference< accessibility::XAccessible > VCLXAccessibleComponent::GetChildAccessible( const VclWindowEvent& rVclWindowEvent )
{
    // checks if the data in the window event is our direct child
    // and returns its accessible

    // MT: Change this later, normaly a show/hide event shouldn't have the Window* in pData.
    Window* pChildWindow = (Window *) rVclWindowEvent.GetData();
    if( pChildWindow && GetWindow() == pChildWindow->GetAccessibleParentWindow() )
        return pChildWindow->GetAccessible( rVclWindowEvent.GetId() == VCLEVENT_WINDOW_SHOW );
    else
        return uno::Reference< accessibility::XAccessible > ();
}

void VCLXAccessibleComponent::ProcessWindowChildEvent( const VclWindowEvent& rVclWindowEvent )
{
	uno::Any aOldValue, aNewValue;
    uno::Reference< accessibility::XAccessible > xAcc;

	switch ( rVclWindowEvent.GetId() )
	{
        case VCLEVENT_WINDOW_SHOW:  // send create on show for direct accessible children
        {
            xAcc = GetChildAccessible( rVclWindowEvent );
            if( xAcc.is() )
            {
                aNewValue <<= xAcc;
                NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD, aOldValue, aNewValue );
            }
        }
        break;
        case VCLEVENT_WINDOW_HIDE:  // send destroy on hide for direct accessible children
        {
            xAcc = GetChildAccessible( rVclWindowEvent );
            if( xAcc.is() )
            {
                aOldValue <<= xAcc;
                NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD, aOldValue, aNewValue );
            }
        }
        break;
	}
}

void VCLXAccessibleComponent::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
{
	uno::Any aOldValue, aNewValue;

	Window* pAccWindow = rVclWindowEvent.GetWindow();
	DBG_ASSERT( pAccWindow, "VCLXAccessibleComponent::ProcessWindowEvent - Window?" );

	switch ( rVclWindowEvent.GetId() )
	{
        case VCLEVENT_OBJECT_DYING:
        {
		    pAccWindow->RemoveEventListener( LINK( this, VCLXAccessibleComponent, WindowEventListener ) );
		    pAccWindow->RemoveChildEventListener( LINK( this, VCLXAccessibleComponent, WindowChildEventListener ) );
	        mxWindow.clear();
	        mpVCLXindow = NULL;
        }
        break;
        //
        // dont handle CHILDCREATED events here
        // they are handled separately as child events, see ProcessWindowChildEvent above
        //
        /*
        case VCLEVENT_WINDOW_CHILDCREATED:
        {
            Window* pWindow = (Window*) rVclWindowEvent.GetData();
            DBG_ASSERT( pWindow, "VCLEVENT_WINDOW_CHILDCREATED - Window=?" );
            aNewValue <<= pWindow->GetAccessible();
            NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD, aOldValue, aNewValue );
        }
        break;
        */
        case VCLEVENT_WINDOW_CHILDDESTROYED:
        {
            Window* pWindow = (Window*) rVclWindowEvent.GetData();
            DBG_ASSERT( pWindow, "VCLEVENT_WINDOW_CHILDDESTROYED - Window=?" );
            if ( pWindow->GetAccessible( sal_False ).is() )
            {
                aOldValue <<= pWindow->GetAccessible( sal_False );
                NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD, aOldValue, aNewValue );
            }
        }
        break;

        //
        // show and hide will be handled as child events only and are
        // responsible for sending create/destroy events, see ProcessWindowChildEvent above
        //
        /*
		case VCLEVENT_WINDOW_SHOW:
		{
			aNewValue <<= accessibility::AccessibleStateType::VISIBLE;
			NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );

			aNewValue <<= accessibility::AccessibleStateType::SHOWING;
			NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );

			aNewValue.clear();
			aOldValue <<= accessibility::AccessibleStateType::INVALID;
			NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
		}
		break;
		case VCLEVENT_WINDOW_HIDE:
		{
			aOldValue <<= accessibility::AccessibleStateType::VISIBLE;
			NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );

			aOldValue <<= accessibility::AccessibleStateType::SHOWING;
			NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );

			aOldValue.clear();
			aNewValue <<= accessibility::AccessibleStateType::INVALID;
			NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
		}
		break;
        */
		case VCLEVENT_WINDOW_ACTIVATE:
		{
            // avoid notification if a child frame is already active
            // only one frame may be active at a given time
            if ( !pAccWindow->HasActiveChildFrame() && 
                 ( getAccessibleRole() == accessibility::AccessibleRole::FRAME || 
                   getAccessibleRole() == accessibility::AccessibleRole::ALERT || 
                   getAccessibleRole() == accessibility::AccessibleRole::DIALOG ) )  // #i18891#
            {
			    aNewValue <<= accessibility::AccessibleStateType::ACTIVE;
			    NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
            }
		}
		break;
		case VCLEVENT_WINDOW_DEACTIVATE:
		{
            if ( getAccessibleRole() == accessibility::AccessibleRole::FRAME || 
                 getAccessibleRole() == accessibility::AccessibleRole::ALERT || 
                 getAccessibleRole() == accessibility::AccessibleRole::DIALOG )  // #i18891#
            {
                aOldValue <<= accessibility::AccessibleStateType::ACTIVE;
                NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
            }
		}
		break;
		case VCLEVENT_WINDOW_GETFOCUS:
		case VCLEVENT_CONTROL_GETFOCUS:
		{
            if( (pAccWindow->IsCompoundControl() && rVclWindowEvent.GetId() == VCLEVENT_CONTROL_GETFOCUS) ||
                (!pAccWindow->IsCompoundControl() && rVclWindowEvent.GetId() == VCLEVENT_WINDOW_GETFOCUS) )
            {
                // if multiple listeners were registered it is possible that the
                // focus was changed during event processing (eg SfxTopWindow )
                // #106082# allow ChildPathFocus only for CompoundControls, for windows the focus must be in the window itself
                if( (pAccWindow->IsCompoundControl() && pAccWindow->HasChildPathFocus()) ||
                    (!pAccWindow->IsCompoundControl() && pAccWindow->HasFocus()) )
                {
			        aNewValue <<= accessibility::AccessibleStateType::FOCUSED;
			        NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
                }
            }
		}
		break;
		case VCLEVENT_WINDOW_LOSEFOCUS:
		case VCLEVENT_CONTROL_LOSEFOCUS:
		{
            if( (pAccWindow->IsCompoundControl() && rVclWindowEvent.GetId() == VCLEVENT_CONTROL_LOSEFOCUS) ||
                (!pAccWindow->IsCompoundControl() && rVclWindowEvent.GetId() == VCLEVENT_WINDOW_LOSEFOCUS) )
            {
			    aOldValue <<= accessibility::AccessibleStateType::FOCUSED;
			    NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
            }
		}
		break;
        case VCLEVENT_WINDOW_FRAMETITLECHANGED:
        {
            ::rtl::OUString aOldName( *((::rtl::OUString*) rVclWindowEvent.GetData()) );
            ::rtl::OUString aNewName( getAccessibleName() );
			aOldValue <<= aOldName;
            aNewValue <<= aNewName;
			NotifyAccessibleEvent( accessibility::AccessibleEventId::NAME_CHANGED, aOldValue, aNewValue );
        }
        break;
		case VCLEVENT_WINDOW_ENABLED:
		{
			aNewValue <<= accessibility::AccessibleStateType::ENABLED;
			NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
            aNewValue <<= accessibility::AccessibleStateType::SENSITIVE;
            NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
		}
		break;
		case VCLEVENT_WINDOW_DISABLED:
		{
            aOldValue <<= accessibility::AccessibleStateType::SENSITIVE;
			NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );

            aOldValue <<= accessibility::AccessibleStateType::ENABLED;
            NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
		}
		break;
		case VCLEVENT_WINDOW_MOVE:
		case VCLEVENT_WINDOW_RESIZE:
		{
			NotifyAccessibleEvent( accessibility::AccessibleEventId::BOUNDRECT_CHANGED, aOldValue, aNewValue );
		}
		break;
		case VCLEVENT_WINDOW_MENUBARADDED:
		{
            MenuBar* pMenuBar = (MenuBar*) rVclWindowEvent.GetData();
			if ( pMenuBar )
			{
				uno::Reference< accessibility::XAccessible > xChild( pMenuBar->GetAccessible() );
				if ( xChild.is() )
				{
					aNewValue <<= xChild;
					NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD, aOldValue, aNewValue );
				}
			}
		}
		break;
		case VCLEVENT_WINDOW_MENUBARREMOVED:
		{
            MenuBar* pMenuBar = (MenuBar*) rVclWindowEvent.GetData();
			if ( pMenuBar )
			{
				uno::Reference< accessibility::XAccessible > xChild( pMenuBar->GetAccessible() );
				if ( xChild.is() )
				{
					aOldValue <<= xChild;
					NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD, aOldValue, aNewValue );
				}
			}
		}
		break;
		case VCLEVENT_WINDOW_MINIMIZE:
		{
			aNewValue <<= accessibility::AccessibleStateType::ICONIFIED;
			NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
		}
		break;
		case VCLEVENT_WINDOW_NORMALIZE:
		{
			aOldValue <<= accessibility::AccessibleStateType::ICONIFIED;
			NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
		}
		break;
		default:
		{
		}
		break;
	}
}

void VCLXAccessibleComponent::disposing()
{
	if ( mpVCLXindow && mpVCLXindow->GetWindow() )
    {
		mpVCLXindow->GetWindow()->RemoveEventListener( LINK( this, VCLXAccessibleComponent, WindowEventListener ) );
		mpVCLXindow->GetWindow()->RemoveChildEventListener( LINK( this, VCLXAccessibleComponent, WindowChildEventListener ) );
    }

	AccessibleExtendedComponentHelper_BASE::disposing();

	mxWindow.clear();
	mpVCLXindow = NULL;
}

Window* VCLXAccessibleComponent::GetWindow() const
{
	return GetVCLXWindow() ? GetVCLXWindow()->GetWindow() : NULL;
}

void VCLXAccessibleComponent::FillAccessibleRelationSet( utl::AccessibleRelationSetHelper& rRelationSet )
{
	Window* pWindow = GetWindow();
	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* pLabelFor = pWindow->GetAccessibleRelationLabelFor();
		if ( pLabelFor && pLabelFor != pWindow )
		{
			uno::Sequence< uno::Reference< uno::XInterface > > aSequence(1);
			aSequence[0] = pLabelFor->GetAccessible();
			rRelationSet.AddRelation( accessibility::AccessibleRelation( accessibility::AccessibleRelationType::LABEL_FOR, 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 ) );
		}
		uno::Sequence< uno::Reference< uno::XInterface > > aFlowToSequence = pWindow->GetAccFlowToSequence();
		if( aFlowToSequence.getLength() > 0 )
		{
			rRelationSet.AddRelation( accessibility::AccessibleRelation( accessibility::AccessibleRelationType::CONTENT_FLOWS_TO, aFlowToSequence ) );		
		}
	}
}

void VCLXAccessibleComponent::FillAccessibleStateSet( utl::AccessibleStateSetHelper& rStateSet )
{
	Window* pWindow = GetWindow();
	if ( pWindow )
	{
		if ( pWindow->IsVisible() )
		{
			rStateSet.AddState( accessibility::AccessibleStateType::VISIBLE );
			rStateSet.AddState( accessibility::AccessibleStateType::SHOWING );
		}
		else
		{
			rStateSet.AddState( accessibility::AccessibleStateType::INVALID );
		}

		if ( pWindow->IsEnabled() )
        {
			rStateSet.AddState( accessibility::AccessibleStateType::ENABLED );
            rStateSet.AddState( accessibility::AccessibleStateType::SENSITIVE );
        }

        if ( pWindow->HasChildPathFocus() &&
             ( getAccessibleRole() == accessibility::AccessibleRole::FRAME || 
               getAccessibleRole() == accessibility::AccessibleRole::ALERT || 
               getAccessibleRole() == accessibility::AccessibleRole::DIALOG ) )  // #i18891#
			rStateSet.AddState( accessibility::AccessibleStateType::ACTIVE );

        // #104290# MT: This way, a ComboBox doesn't get state FOCUSED.
        // I also don't understand 
        // a) why WINDOW_FIRSTCHILD is used here (which btw is a border window in the case of a combo box)
        // b) why HasFocus() is nout "enough" for a compound control
        /*
		Window* pChild = pWindow->GetWindow( WINDOW_FIRSTCHILD );
		if ( ( !pWindow->IsCompoundControl() && pWindow->HasFocus() ) ||
		     ( pWindow->IsCompoundControl() && pChild && pChild->HasFocus() ) )
			rStateSet.AddState( accessibility::AccessibleStateType::FOCUSED );
	    */
		if ( pWindow->HasFocus() || ( pWindow->IsCompoundControl() && pWindow->HasChildPathFocus() ) )
			rStateSet.AddState( accessibility::AccessibleStateType::FOCUSED );

		if ( pWindow->IsWait() )
			rStateSet.AddState( accessibility::AccessibleStateType::BUSY );

		if ( pWindow->GetStyle() & WB_SIZEABLE )
			rStateSet.AddState( accessibility::AccessibleStateType::RESIZABLE );
		// 6. frame doesn't have MOVABLE state
		// 10. for password text, where is the sensitive state? 
		if( ( getAccessibleRole() == accessibility::AccessibleRole::FRAME ||getAccessibleRole() == accessibility::AccessibleRole::DIALOG )&& pWindow->GetStyle() & WB_MOVEABLE )
			rStateSet.AddState( accessibility::AccessibleStateType::MOVEABLE );
        if( pWindow->IsDialog() )
        {
            Dialog *pDlg = static_cast< Dialog* >( pWindow );
            if( pDlg->IsInExecute() )
			    rStateSet.AddState( accessibility::AccessibleStateType::MODAL );
        }
        //Solution:If a combobox or list's edit child isn't read-only,EDITABLE state
        //         should be set.
		if( pWindow && pWindow->GetType() == WINDOW_COMBOBOX )
		{
			if( !( pWindow->GetStyle() & WB_READONLY) ||  
			    !((Edit*)pWindow)->IsReadOnly() )
					rStateSet.AddState( accessibility::AccessibleStateType::EDITABLE );	
		}
		
		Window* pChild = pWindow->GetWindow( WINDOW_FIRSTCHILD );
		
		while( pWindow && pChild )
		{
			Window* pWinTemp = pChild->GetWindow( WINDOW_FIRSTCHILD );
			if( pWinTemp && pWinTemp->GetType() == WINDOW_EDIT )
			{
				if( !( pWinTemp->GetStyle() & WB_READONLY) || 
					!((Edit*)pWinTemp)->IsReadOnly() )
					rStateSet.AddState( accessibility::AccessibleStateType::EDITABLE );
				break;	
			}
			if( pChild->GetType() == WINDOW_EDIT )
			{
				if( !( pChild->GetStyle() & WB_READONLY) || 
					!((Edit*)pChild)->IsReadOnly())
					rStateSet.AddState( accessibility::AccessibleStateType::EDITABLE );
				break;	
			}
			pChild = pChild->GetWindow( WINDOW_NEXT );
		}
	}
	else
	{
		rStateSet.AddState( accessibility::AccessibleStateType::DEFUNC );
	}

/*

MUST BE SET FROM DERIVED CLASSES:

CHECKED
COLLAPSED
EXPANDED
EXPANDABLE
EDITABLE
FOCUSABLE
HORIZONTAL
VERTICAL
ICONIFIED
MULTILINE
MULTI_SELECTABLE
PRESSED
SELECTABLE
SELECTED
SINGLE_LINE
TRANSIENT

	*/
}


// accessibility::XAccessibleContext
sal_Int32 VCLXAccessibleComponent::getAccessibleChildCount() throw (uno::RuntimeException)
{
	OExternalLockGuard aGuard( this );

	sal_Int32 nChildren = 0;
	if ( GetWindow() )
		nChildren = GetWindow()->GetAccessibleChildWindowCount();

	return nChildren;
}

uno::Reference< accessibility::XAccessible > VCLXAccessibleComponent::getAccessibleChild( sal_Int32 i ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
{
	OExternalLockGuard aGuard( this );

	if ( i >= getAccessibleChildCount() )
		throw lang::IndexOutOfBoundsException();

	uno::Reference< accessibility::XAccessible > xAcc;
	if ( GetWindow() )
	{
		Window* pChild = GetWindow()->GetAccessibleChildWindow( (sal_uInt16)i );
		if ( pChild )
			xAcc = pChild->GetAccessible();
	}

	return xAcc;
}

uno::Reference< accessibility::XAccessible > VCLXAccessibleComponent::getVclParent() const
{
	uno::Reference< accessibility::XAccessible > xAcc;
	if ( GetWindow() )
	{
		Window* pParent = GetWindow()->GetAccessibleParentWindow();
		if ( pParent )
			xAcc = pParent->GetAccessible();
	}
	return xAcc;
}

uno::Reference< accessibility::XAccessible > VCLXAccessibleComponent::getAccessibleParent(	) throw (uno::RuntimeException)
{
	OExternalLockGuard aGuard( this );

	uno::Reference< accessibility::XAccessible > xAcc( implGetForeignControlledParent() );
	if ( !xAcc.is() )
		// we do _not_ have a foreign-controlled parent -> default to our VCL parent
		xAcc = getVclParent();

	return xAcc;
}

sal_Int32 VCLXAccessibleComponent::getAccessibleIndexInParent(	) throw (uno::RuntimeException)
{
	OExternalLockGuard aGuard( this );

	sal_Int32 nIndex = -1;

	uno::Reference< accessibility::XAccessible > xAcc( implGetForeignControlledParent() );
	if ( xAcc.is() )
	{	// we _do_ have a foreign-controlled parent -> use the base class' implementation,
		// which goes the UNO way
		nIndex = AccessibleExtendedComponentHelper_BASE::getAccessibleIndexInParent( );
	}
	else
	{
		if ( GetWindow() )
		{
			Window* pParent = GetWindow()->GetAccessibleParentWindow();
			if ( pParent )
			{
                /*
				for ( sal_uInt16 n = pParent->GetAccessibleChildWindowCount(); n; )
				{
					Window* pChild = pParent->GetAccessibleChildWindow( --n );
					if ( pChild == GetWindow() )
					{
						nIndex = n;
						break;
					}
				}
                */
                //	Iterate over all the parent's children and search for this object.
                // this should be compatible with the code in SVX
                uno::Reference< accessibility::XAccessible > xParentAcc( pParent->GetAccessible() );
                if ( xParentAcc.is() )
                {
                    uno::Reference< accessibility::XAccessibleContext > xParentContext ( xParentAcc->getAccessibleContext() );
                    if ( xParentContext.is() )
                    {
                        sal_Int32 nChildCount = xParentContext->getAccessibleChildCount();
                        for ( sal_Int32 i=0; i<nChildCount; i++ )
                        {
                            uno::Reference< accessibility::XAccessible > xChild( xParentContext->getAccessibleChild(i) );
                            if ( xChild.is() )
                            {
                                uno::Reference< accessibility::XAccessibleContext > xChildContext = xChild->getAccessibleContext();
	                            if ( xChildContext == (accessibility::XAccessibleContext*) this )
                                {
                                    nIndex = i;
                                    break;
                                }
                            }
                        }
                    }
                }
			}
		}
	}
	return nIndex;
}

sal_Int16 VCLXAccessibleComponent::getAccessibleRole(  ) throw (uno::RuntimeException)
{
	OExternalLockGuard aGuard( this );

	sal_Int16 nRole = 0;

	if ( GetWindow() )
		nRole = GetWindow()->GetAccessibleRole();

	return nRole;
}

::rtl::OUString VCLXAccessibleComponent::getAccessibleDescription(	) throw (uno::RuntimeException)
{
	OExternalLockGuard aGuard( this );

	::rtl::OUString aDescription;

	if ( GetWindow() )
		aDescription = GetWindow()->GetAccessibleDescription();

	return aDescription;
}

::rtl::OUString VCLXAccessibleComponent::getAccessibleName(  ) throw (uno::RuntimeException)
{
	OExternalLockGuard aGuard( this );

	::rtl::OUString aName;
	if ( GetWindow() )
	{
		aName = GetWindow()->GetAccessibleName();
#if OSL_DEBUG_LEVEL > 1
		aName += String( RTL_CONSTASCII_USTRINGPARAM( " (Type = " ) );
		aName += String::CreateFromInt32( GetWindow()->GetType() );
		aName += String( RTL_CONSTASCII_USTRINGPARAM( ")" ) );
#endif
	}
	return aName;
}

uno::Reference< accessibility::XAccessibleRelationSet > VCLXAccessibleComponent::getAccessibleRelationSet(	) throw (uno::RuntimeException)
{
	OExternalLockGuard aGuard( this );

    utl::AccessibleRelationSetHelper* pRelationSetHelper = new utl::AccessibleRelationSetHelper;
	uno::Reference< accessibility::XAccessibleRelationSet > xSet = pRelationSetHelper;
	FillAccessibleRelationSet( *pRelationSetHelper );
    return xSet;
}

uno::Reference< accessibility::XAccessibleStateSet > VCLXAccessibleComponent::getAccessibleStateSet(  ) throw (uno::RuntimeException)
{
	OExternalLockGuard aGuard( this );

	utl::AccessibleStateSetHelper* pStateSetHelper = new utl::AccessibleStateSetHelper;
	uno::Reference< accessibility::XAccessibleStateSet > xSet = pStateSetHelper;
	FillAccessibleStateSet( *pStateSetHelper );
	return xSet;
}

lang::Locale VCLXAccessibleComponent::getLocale() throw (accessibility::IllegalAccessibleComponentStateException, uno::RuntimeException)
{
	OExternalLockGuard aGuard( this );

	return Application::GetSettings().GetLocale();
}

uno::Reference< accessibility::XAccessible > VCLXAccessibleComponent::getAccessibleAtPoint( const awt::Point& rPoint ) throw (uno::RuntimeException)
{
	OExternalLockGuard aGuard( this );

    uno::Reference< accessibility::XAccessible > xChild;
	for ( sal_uInt32 i = 0, nCount = getAccessibleChildCount(); i < nCount; ++i )
	{
		uno::Reference< accessibility::XAccessible > xAcc = getAccessibleChild( i );
		if ( xAcc.is() )
		{			
			uno::Reference< accessibility::XAccessibleComponent > xComp( xAcc->getAccessibleContext(), uno::UNO_QUERY );				
			if ( xComp.is() )
			{
				Rectangle aRect = VCLRectangle( xComp->getBounds() );
				Point aPos = VCLPoint( rPoint );
				if ( aRect.IsInside( aPos ) )
				{
					xChild = xAcc;
					break;
				}
			}
		}
	}

	return xChild;
}

// accessibility::XAccessibleComponent
awt::Rectangle VCLXAccessibleComponent::implGetBounds() throw (uno::RuntimeException)
{
	awt::Rectangle aBounds ( 0, 0, 0, 0 );

	Window* pWindow = GetWindow();
	if ( pWindow )
	{
		Rectangle aRect = pWindow->GetWindowExtentsRelative( NULL );
		aBounds = AWTRectangle( aRect );
		Window* pParent = pWindow->GetAccessibleParentWindow();
		if ( pParent )
		{
			Rectangle aParentRect = pParent->GetWindowExtentsRelative( NULL );
			awt::Point aParentScreenLoc = AWTPoint( aParentRect.TopLeft() );
			aBounds.X -= aParentScreenLoc.X;
			aBounds.Y -= aParentScreenLoc.Y;
		}
	}

	uno::Reference< accessibility::XAccessible > xParent( implGetForeignControlledParent() );
	if ( xParent.is() )
	{	// hmm, we can't rely on our VCL coordinates, as in the Accessibility Hierarchy, somebody gave
		// us a parent which is different from our VCL parent
		// (actually, we did not check if it's really different ...)

		// the screen location of the foreign parent
		uno::Reference< accessibility::XAccessibleComponent > xParentComponent( xParent->getAccessibleContext(), uno::UNO_QUERY );
		DBG_ASSERT( xParentComponent.is(), "VCLXAccessibleComponent::implGetBounds: invalid (foreign) parent component!" );

		awt::Point aScreenLocForeign( 0, 0 );
		if ( xParentComponent.is() )
			aScreenLocForeign = xParentComponent->getLocationOnScreen();

		// the screen location of the VCL parent
		xParent = getVclParent();
		if ( xParent.is() )
			xParentComponent = xParentComponent.query( xParent->getAccessibleContext() );

		awt::Point aScreenLocVCL( 0, 0 );
		if ( xParentComponent.is() )
			aScreenLocVCL = xParentComponent->getLocationOnScreen();

		// the difference between them
		awt::Size aOffset( aScreenLocVCL.X - aScreenLocForeign.X, aScreenLocVCL.Y - aScreenLocForeign.Y );
		// move the bounds
		aBounds.X += aOffset.Width;
		aBounds.Y += aOffset.Height;
	}

	return aBounds;
}

awt::Point VCLXAccessibleComponent::getLocationOnScreen(  ) throw (uno::RuntimeException)
{
	OExternalLockGuard aGuard( this );

	awt::Point aPos;
	if ( GetWindow() )
	{
		Rectangle aRect = GetWindow()->GetWindowExtentsRelative( NULL );
		aPos.X = aRect.Left();
		aPos.Y = aRect.Top();
	}

	return aPos;
}

void VCLXAccessibleComponent::grabFocus(  ) throw (uno::RuntimeException)
{
	OExternalLockGuard aGuard( this );

	uno::Reference< accessibility::XAccessibleStateSet > xStates = getAccessibleStateSet();
	if ( mxWindow.is() && xStates.is() && xStates->contains( accessibility::AccessibleStateType::FOCUSABLE ) )
		mxWindow->setFocus();
}

sal_Int32 SAL_CALL VCLXAccessibleComponent::getForeground(	) throw (uno::RuntimeException)
{
	OExternalLockGuard aGuard( this );

	sal_Int32 nColor = 0;
	Window* pWindow = GetWindow();
	if ( pWindow )
	{
		if ( pWindow->IsControlForeground() )
			nColor = pWindow->GetControlForeground().GetColor();
		else
		{
			Font aFont;
			if ( pWindow->IsControlFont() )
				aFont = pWindow->GetControlFont();
			else
				aFont = pWindow->GetFont();
			nColor = aFont.GetColor().GetColor();
// COL_AUTO is not very meaningful for AT
			if ( nColor == (sal_Int32)COL_AUTO)
				nColor = pWindow->GetTextColor().GetColor();
		}
	}

	return nColor;
}

sal_Int32 SAL_CALL VCLXAccessibleComponent::getBackground(	) throw (uno::RuntimeException)
{
	OExternalLockGuard aGuard( this );

	sal_Int32 nColor = 0;
	Window* pWindow = GetWindow();
	if ( pWindow )
	{
		if ( pWindow->IsControlBackground() )
			nColor = pWindow->GetControlBackground().GetColor();
		else
			nColor = pWindow->GetBackground().GetColor().GetColor();
	}

	return nColor;
}

// XAccessibleExtendedComponent

uno::Reference< awt::XFont > SAL_CALL VCLXAccessibleComponent::getFont(  ) throw (uno::RuntimeException)
{
	OExternalLockGuard aGuard( this );

	uno::Reference< awt::XFont > xFont;
	Window* pWindow = GetWindow();
	if ( pWindow )
	{
		uno::Reference< awt::XDevice > xDev( pWindow->GetComponentInterface(), uno::UNO_QUERY );
		if ( xDev.is() )
		{
			Font aFont;
			if ( pWindow->IsControlFont() )
				aFont = pWindow->GetControlFont();
			else
				aFont = pWindow->GetFont();
			VCLXFont* pVCLXFont = new VCLXFont;
			pVCLXFont->Init( *xDev.get(), aFont );
			xFont = pVCLXFont;
		}
	}

	return xFont;
}

::rtl::OUString SAL_CALL VCLXAccessibleComponent::getTitledBorderText(	) throw (uno::RuntimeException)
{
	OExternalLockGuard aGuard( this );

	::rtl::OUString sRet;
	if ( GetWindow() )
		sRet = GetWindow()->GetText();

	return sRet;
}

::rtl::OUString SAL_CALL VCLXAccessibleComponent::getToolTipText(  ) throw (uno::RuntimeException)
{
	OExternalLockGuard aGuard( this );

	::rtl::OUString sRet;
	if ( GetWindow() )
		sRet = GetWindow()->GetQuickHelpText();

	return sRet;
}

