/**************************************************************
 *
 * 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 "toolkit/controls/geometrycontrolmodel.hxx"
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/beans/PropertyAttribute.hpp>
#include <osl/diagnose.h>
#include <rtl/instance.hxx>
#include <comphelper/property.hxx>
#include <comphelper/sequence.hxx>
#ifndef _COM_SUN_STAR_XNAMECONTAINER_HPP_
#include <toolkit/controls/eventcontainer.hxx>
#endif
#include <toolkit/helper/property.hxx>
#include <tools/debug.hxx>
#include <algorithm>
#include <functional>
#include <comphelper/sequence.hxx>


#define GCM_PROPERTY_ID_POS_X		        1
#define GCM_PROPERTY_ID_POS_Y		        2
#define GCM_PROPERTY_ID_WIDTH		        3
#define GCM_PROPERTY_ID_HEIGHT		        4
#define GCM_PROPERTY_ID_NAME		        5
#define GCM_PROPERTY_ID_TABINDEX	        6
#define GCM_PROPERTY_ID_STEP		        7
#define GCM_PROPERTY_ID_TAG			        8
#define GCM_PROPERTY_ID_RESOURCERESOLVER    9

#define GCM_PROPERTY_POS_X		        ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("PositionX"))
#define GCM_PROPERTY_POS_Y		        ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("PositionY"))
#define GCM_PROPERTY_WIDTH		        ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Width"))
#define GCM_PROPERTY_HEIGHT		        ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Height"))
#define GCM_PROPERTY_NAME		        ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Name"))
#define GCM_PROPERTY_TABINDEX	        ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TabIndex"))
#define GCM_PROPERTY_STEP		        ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Step"))
#define GCM_PROPERTY_TAG		        ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Tag"))
#define GCM_PROPERTY_RESOURCERESOLVER	::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ResourceResolver"))

#define DEFAULT_ATTRIBS()		PropertyAttribute::BOUND | PropertyAttribute::TRANSIENT

//........................................................................
// namespace toolkit
// {
//........................................................................

	using namespace ::com::sun::star;
	using namespace ::com::sun::star::uno;
	using namespace ::com::sun::star::lang;
	using namespace ::com::sun::star::beans;
	using namespace ::com::sun::star::util;
	using namespace ::com::sun::star::container;
	using namespace ::comphelper;

	//====================================================================
	//= OGeometryControlModel_Base
	//====================================================================
	//--------------------------------------------------------------------
	OGeometryControlModel_Base::OGeometryControlModel_Base(::com::sun::star::uno::XAggregation* _pAggregateInstance)
		:OPropertySetAggregationHelper( m_aBHelper )
		,OPropertyContainer( m_aBHelper )
		,OGCM_Base( m_aMutex )
		,m_nPosX(0)
		,m_nPosY(0)
		,m_nWidth(0)
		,m_nHeight(0)
		,m_nTabIndex(-1)
		,m_nStep(0)
		,m_bCloneable(sal_False)
	{
		OSL_ENSURE(NULL != _pAggregateInstance, "OGeometryControlModel_Base::OGeometryControlModel_Base: invalid aggregate!");

		increment(m_refCount);
		{
			m_xAggregate = _pAggregateInstance;

			{	// check if the aggregat is cloneable
				Reference< XCloneable > xCloneAccess(m_xAggregate, UNO_QUERY);
				m_bCloneable = xCloneAccess.is();
			}

			setAggregation(m_xAggregate);
			m_xAggregate->setDelegator(static_cast< XWeak* >(this));
		}
		decrement(m_refCount);

		registerProperties();
	}

	//--------------------------------------------------------------------
	OGeometryControlModel_Base::OGeometryControlModel_Base(Reference< XCloneable >& _rxAggregateInstance)
		:OPropertySetAggregationHelper( m_aBHelper )
		,OPropertyContainer( m_aBHelper )
		,OGCM_Base( m_aMutex )
		,m_nPosX(0)
		,m_nPosY(0)
		,m_nWidth(0)
		,m_nHeight(0)
		,m_nTabIndex(-1)
		,m_nStep(0)
		,m_bCloneable(_rxAggregateInstance.is())
	{
		increment(m_refCount);
		{
            {
                // ensure that the temporary gets destructed NOW
                m_xAggregate = Reference< XAggregation >(_rxAggregateInstance, UNO_QUERY);
            }
			OSL_ENSURE(m_xAggregate.is(), "OGeometryControlModel_Base::OGeometryControlModel_Base: invalid object given!");

			// now the aggregate has a ref count of 2, but before setting the delegator it must be 1
			_rxAggregateInstance.clear();
			// now it should be the 1 we need here ...

			setAggregation(m_xAggregate);
			m_xAggregate->setDelegator(static_cast< XWeak* >(this));
		}
		decrement(m_refCount);

		registerProperties();
	}

	//--------------------------------------------------------------------
	Sequence< Type > SAL_CALL OGeometryControlModel_Base::getTypes(  ) throw (RuntimeException)
	{
		// our own types
		Sequence< Type > aTypes = ::comphelper::concatSequences(
			OPropertySetAggregationHelper::getTypes(),
			OPropertyContainer::getTypes(),
			OGCM_Base::getTypes()
		);

		if ( m_xAggregate.is() )
		{
			// retrieve the types of the aggregate
			Reference< XTypeProvider > xAggregateTypeProv;
			m_xAggregate->queryAggregation( ::getCppuType( &xAggregateTypeProv ) ) >>= xAggregateTypeProv;
			OSL_ENSURE( xAggregateTypeProv.is(), "OGeometryControlModel_Base::getTypes: aggregate should be a type provider!" );
			Sequence< Type > aAggTypes;
			if ( xAggregateTypeProv.is() )
				aAggTypes = xAggregateTypeProv->getTypes();

			// concat the sequences
			sal_Int32 nOldSize = aTypes.getLength();
			aTypes.realloc( nOldSize + aAggTypes.getLength() );
			::std::copy(
				aAggTypes.getConstArray(),
				aAggTypes.getConstArray() + aAggTypes.getLength(),
				aTypes.getArray() + nOldSize
			);
		}

		return aTypes;
	}

	//--------------------------------------------------------------------
	void OGeometryControlModel_Base::registerProperties()
	{
		// register our members for the property handling of the OPropertyContainer
		registerProperty(GCM_PROPERTY_POS_X,	GCM_PROPERTY_ID_POS_X,		DEFAULT_ATTRIBS(), &m_nPosX, ::getCppuType(&m_nPosX));
		registerProperty(GCM_PROPERTY_POS_Y,	GCM_PROPERTY_ID_POS_Y,		DEFAULT_ATTRIBS(), &m_nPosY, ::getCppuType(&m_nPosY));
		registerProperty(GCM_PROPERTY_WIDTH,	GCM_PROPERTY_ID_WIDTH,		DEFAULT_ATTRIBS(), &m_nWidth, ::getCppuType(&m_nWidth));
		registerProperty(GCM_PROPERTY_HEIGHT,	GCM_PROPERTY_ID_HEIGHT,		DEFAULT_ATTRIBS(), &m_nHeight, ::getCppuType(&m_nHeight));
		registerProperty(GCM_PROPERTY_NAME,		GCM_PROPERTY_ID_NAME,		DEFAULT_ATTRIBS(), &m_aName, ::getCppuType(&m_aName));
		registerProperty(GCM_PROPERTY_TABINDEX,	GCM_PROPERTY_ID_TABINDEX,	DEFAULT_ATTRIBS(), &m_nTabIndex, ::getCppuType(&m_nTabIndex));
		registerProperty(GCM_PROPERTY_STEP,		GCM_PROPERTY_ID_STEP,		DEFAULT_ATTRIBS(), &m_nStep, ::getCppuType(&m_nStep));
		registerProperty(GCM_PROPERTY_TAG,		GCM_PROPERTY_ID_TAG,		DEFAULT_ATTRIBS(), &m_aTag, ::getCppuType(&m_aTag));
        registerProperty(GCM_PROPERTY_RESOURCERESOLVER, GCM_PROPERTY_ID_RESOURCERESOLVER, DEFAULT_ATTRIBS(), &m_xStrResolver, ::getCppuType(&m_xStrResolver));
	}

	//--------------------------------------------------------------------
	::com::sun::star::uno::Any OGeometryControlModel_Base::ImplGetDefaultValueByHandle(sal_Int32 nHandle) const
	{
		::com::sun::star::uno::Any aDefault;

        switch ( nHandle )
        {
            case GCM_PROPERTY_ID_POS_X:			    aDefault <<= (sal_Int32) 0; break;
            case GCM_PROPERTY_ID_POS_Y:			    aDefault <<= (sal_Int32) 0; break;
            case GCM_PROPERTY_ID_WIDTH:			    aDefault <<= (sal_Int32) 0; break;
            case GCM_PROPERTY_ID_HEIGHT:		    aDefault <<= (sal_Int32) 0; break;
            case GCM_PROPERTY_ID_NAME:			    aDefault <<= ::rtl::OUString(); break;
            case GCM_PROPERTY_ID_TABINDEX:		    aDefault <<= (sal_Int16) -1; break;
            case GCM_PROPERTY_ID_STEP:			    aDefault <<= (sal_Int32) 0; break;
            case GCM_PROPERTY_ID_TAG:			    aDefault <<= ::rtl::OUString(); break;
            case GCM_PROPERTY_ID_RESOURCERESOLVER:  aDefault <<= Reference< resource::XStringResourceResolver >(); break;
            default:							DBG_ERROR( "ImplGetDefaultValueByHandle - unknown Property" );
        }

		return aDefault;
	}

	//--------------------------------------------------------------------
	::com::sun::star::uno::Any OGeometryControlModel_Base::ImplGetPropertyValueByHandle(sal_Int32 nHandle) const
	{
		::com::sun::star::uno::Any aValue;

        switch ( nHandle )
        {
            case GCM_PROPERTY_ID_POS_X:			aValue <<= m_nPosX; break;
            case GCM_PROPERTY_ID_POS_Y:			aValue <<= m_nPosY; break;
            case GCM_PROPERTY_ID_WIDTH:			aValue <<= m_nWidth; break;
            case GCM_PROPERTY_ID_HEIGHT:		aValue <<= m_nHeight; break;
            case GCM_PROPERTY_ID_NAME:			aValue <<= m_aName; break;
            case GCM_PROPERTY_ID_TABINDEX:		aValue <<= m_nTabIndex; break;
            case GCM_PROPERTY_ID_STEP:			aValue <<= m_nStep; break;
            case GCM_PROPERTY_ID_TAG:			aValue <<= m_aTag; break;
            case GCM_PROPERTY_ID_RESOURCERESOLVER: aValue <<= m_xStrResolver; break;
            default:							DBG_ERROR( "ImplGetPropertyValueByHandle - unknown Property" );
        }

		return aValue;
	}

	//--------------------------------------------------------------------
	void OGeometryControlModel_Base::ImplSetPropertyValueByHandle(sal_Int32 nHandle, const :: com::sun::star::uno::Any& aValue)
	{
        switch ( nHandle )
        {
            case GCM_PROPERTY_ID_POS_X:			aValue >>= m_nPosX; break;
            case GCM_PROPERTY_ID_POS_Y:			aValue >>= m_nPosY; break;
            case GCM_PROPERTY_ID_WIDTH:			aValue >>= m_nWidth; break;
            case GCM_PROPERTY_ID_HEIGHT:		aValue >>= m_nHeight; break;
            case GCM_PROPERTY_ID_NAME:			aValue >>= m_aName; break;
            case GCM_PROPERTY_ID_TABINDEX:		aValue >>= m_nTabIndex; break;
            case GCM_PROPERTY_ID_STEP:			aValue >>= m_nStep; break;
            case GCM_PROPERTY_ID_TAG:			aValue >>= m_aTag; break;
            case GCM_PROPERTY_ID_RESOURCERESOLVER: aValue >>= m_xStrResolver; break;
            default:							DBG_ERROR( "ImplSetPropertyValueByHandle - unknown Property" );
        }
	}

	//--------------------------------------------------------------------
	Any SAL_CALL OGeometryControlModel_Base::queryAggregation( const Type& _rType ) throw(RuntimeException)
	{
		Any aReturn;
		if (_rType.equals(::getCppuType(static_cast< Reference< XCloneable>* >(NULL))) && !m_bCloneable)
			// somebody is asking for the XCloneable interface, but our aggregate does not support it
			// -> outta here
			// (need this extra check, cause OGCM_Base::queryAggregation would return this interface
			// in every case)
			return aReturn;

		aReturn = OGCM_Base::queryAggregation(_rType);
			// the basic interfaces (XInterface, XAggregation etc)

		if (!aReturn.hasValue())
			aReturn = OPropertySetAggregationHelper::queryInterface(_rType);
			// the property set related interfaces

		if (!aReturn.hasValue() && m_xAggregate.is())
			aReturn = m_xAggregate->queryAggregation(_rType);
			// the interfaces our aggregate can provide

		return aReturn;
	}

	//--------------------------------------------------------------------
	Any SAL_CALL OGeometryControlModel_Base::queryInterface( const Type& _rType ) throw(RuntimeException)
	{
		return OGCM_Base::queryInterface(_rType);
	}

	//--------------------------------------------------------------------
	void SAL_CALL OGeometryControlModel_Base::acquire(  ) throw()
	{
		OGCM_Base::acquire();
	}

	//--------------------------------------------------------------------
	void SAL_CALL OGeometryControlModel_Base::release(  ) throw()
	{
		OGCM_Base::release();
	}

	//--------------------------------------------------------------------
	void OGeometryControlModel_Base::releaseAggregation()
	{
		// release the aggregate (_before_ clearing m_xAggregate)
		if (m_xAggregate.is())
			m_xAggregate->setDelegator(NULL);
		setAggregation(NULL);
	}

	//--------------------------------------------------------------------
	OGeometryControlModel_Base::~OGeometryControlModel_Base()
	{
		releaseAggregation();
	}

	//--------------------------------------------------------------------
	sal_Bool SAL_CALL OGeometryControlModel_Base::convertFastPropertyValue(Any& _rConvertedValue, Any& _rOldValue,
			sal_Int32 _nHandle, const Any& _rValue) throw (IllegalArgumentException)
	{
		return OPropertyContainer::convertFastPropertyValue(_rConvertedValue, _rOldValue, _nHandle, _rValue);
	}

	//--------------------------------------------------------------------
	void SAL_CALL OGeometryControlModel_Base::setFastPropertyValue_NoBroadcast(sal_Int32 _nHandle, const Any& _rValue) throw (Exception)
	{
		OPropertyContainer::setFastPropertyValue_NoBroadcast(_nHandle, _rValue);
	}

	//--------------------------------------------------------------------
	void SAL_CALL OGeometryControlModel_Base::getFastPropertyValue(Any& _rValue, sal_Int32 _nHandle) const
	{
		OPropertyArrayAggregationHelper& rPH = static_cast<OPropertyArrayAggregationHelper&>(const_cast<OGeometryControlModel_Base*>(this)->getInfoHelper());
		::rtl::OUString sPropName;
		sal_Int32	nOriginalHandle = -1;

		if (rPH.fillAggregatePropertyInfoByHandle(&sPropName, &nOriginalHandle, _nHandle))
			OPropertySetAggregationHelper::getFastPropertyValue(_rValue, _nHandle);
		else
			OPropertyContainer::getFastPropertyValue(_rValue, _nHandle);
	}

	//--------------------------------------------------------------------
	::com::sun::star::beans::PropertyState OGeometryControlModel_Base::getPropertyStateByHandle(sal_Int32 nHandle)
	{
		::com::sun::star::uno::Any aValue = ImplGetPropertyValueByHandle( nHandle );
		::com::sun::star::uno::Any aDefault = ImplGetDefaultValueByHandle( nHandle );

		return CompareProperties( aValue, aDefault ) ? ::com::sun::star::beans::PropertyState_DEFAULT_VALUE : ::com::sun::star::beans::PropertyState_DIRECT_VALUE;
	}

	//--------------------------------------------------------------------
	void OGeometryControlModel_Base::setPropertyToDefaultByHandle(sal_Int32 nHandle)
	{
		ImplSetPropertyValueByHandle( nHandle , ImplGetDefaultValueByHandle( nHandle ) );
	}

	//--------------------------------------------------------------------
	::com::sun::star::uno::Any OGeometryControlModel_Base::getPropertyDefaultByHandle( sal_Int32 nHandle ) const
	{
		return ImplGetDefaultValueByHandle( nHandle );
	}

	//--------------------------------------------------------------------
	Reference< XPropertySetInfo> SAL_CALL OGeometryControlModel_Base::getPropertySetInfo() throw(RuntimeException)
	{
		return OPropertySetAggregationHelper::createPropertySetInfo(getInfoHelper());
	}

	//--------------------------------------------------------------------
	Reference< XCloneable > SAL_CALL OGeometryControlModel_Base::createClone(  ) throw(RuntimeException)
	{
		OSL_ENSURE(m_bCloneable, "OGeometryControlModel_Base::createClone: invalid call!");
		if (!m_bCloneable)
			return Reference< XCloneable >();

		// let the aggregate create it's own clone
		// the interface
		Reference< XCloneable > xCloneAccess;
		m_xAggregate->queryAggregation(::getCppuType(&xCloneAccess)) >>= xCloneAccess;
		OSL_ENSURE(xCloneAccess.is(), "OGeometryControlModel_Base::createClone: suspicious aggregate!");
		if (!xCloneAccess.is())
			return Reference< XCloneable >();
		// the aggregate's clone
		Reference< XCloneable > xAggregateClone = xCloneAccess->createClone();
		OSL_ENSURE(xAggregateClone.is(), "OGeometryControlModel_Base::createClone: suspicious return of the aggregate!");

		// create a new wrapper aggregating this return value
		OGeometryControlModel_Base* pOwnClone = createClone_Impl(xAggregateClone);
		OSL_ENSURE(pOwnClone, "OGeometryControlModel_Base::createClone: invalid derivee behaviour!");
		OSL_ENSURE(!xAggregateClone.is(), "OGeometryControlModel_Base::createClone: invalid ctor behaviour!");
			// should have been reset

		// set properties
		pOwnClone->m_nPosX		= m_nPosX;
		pOwnClone->m_nPosY		= m_nPosY;
		pOwnClone->m_nWidth		= m_nWidth;
		pOwnClone->m_nHeight	= m_nHeight;
		pOwnClone->m_aName		= m_aName;
		pOwnClone->m_nTabIndex	= m_nTabIndex;
		pOwnClone->m_nStep		= m_nStep;
		pOwnClone->m_aTag		= m_aTag;


        // Clone event container
		Reference< ::com::sun::star::script::XScriptEventsSupplier > xEventsSupplier =
            static_cast< ::com::sun::star::script::XScriptEventsSupplier* >( this );
		Reference< ::com::sun::star::script::XScriptEventsSupplier > xCloneEventsSupplier =
            static_cast< ::com::sun::star::script::XScriptEventsSupplier* >( pOwnClone );

		if( xEventsSupplier.is() && xCloneEventsSupplier.is() )
		{
			Reference< XNameContainer > xEventCont = xEventsSupplier->getEvents();
			Reference< XNameContainer > xCloneEventCont = xCloneEventsSupplier->getEvents();

			::com::sun::star::uno::Sequence< ::rtl::OUString > aNames =
                xEventCont->getElementNames();
			const ::rtl::OUString* pNames = aNames.getConstArray();
			sal_Int32 i, nNameCount = aNames.getLength();

			for( i = 0 ; i < nNameCount ; i++ )
			{
                ::rtl::OUString aName = pNames[ i ];
				::com::sun::star::uno::Any aElement = xEventCont->getByName( aName );
                xCloneEventCont->insertByName( aName, aElement );
			}
		}

		return pOwnClone;
	}

	//--------------------------------------------------------------------
	Reference< XNameContainer > SAL_CALL OGeometryControlModel_Base::getEvents() throw(RuntimeException)
	{
		if( !mxEventContainer.is() )
			mxEventContainer = (XNameContainer*)new toolkit::ScriptEventContainer();
		return mxEventContainer;
	}

	//--------------------------------------------------------------------
    void SAL_CALL OGeometryControlModel_Base::disposing()
	{
		OGCM_Base::disposing();
		OPropertySetAggregationHelper::disposing();

		Reference<XComponent>  xComp;
		if ( query_aggregation( m_xAggregate, xComp ) )
			xComp->dispose();
	}

	//====================================================================
	//= OCommonGeometryControlModel
	//====================================================================
	//--------------------------------------------------------------------

	typedef	::std::hash_map< ::rtl::OUString, sal_Int32, ::comphelper::UStringHash > HashMapString2Int;
	typedef ::std::vector< ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property > >	PropSeqArray;
	typedef ::std::vector< ::std::vector< sal_Int32 > > IntArrayArray;

	// for creating class-unique PropertySetInfo's, we need some info:
	namespace { struct ServiceSpecifierMap : public rtl::Static< HashMapString2Int, ServiceSpecifierMap > {}; }
	// this one maps from a String, which is the service specifier for our
	// aggregate, to a unique id

	namespace { struct AggregateProperties : public rtl::Static< PropSeqArray, AggregateProperties > {}; }
	// this one contains the properties which belong to all the unique ids
	// in ServiceSpecifierMap

	namespace { struct AmbiguousPropertyIds : public rtl::Static< IntArrayArray, AmbiguousPropertyIds > {}; }
	// the ids of the properties which we as well as our aggregate supply
	// For such props, we let our base class handle them, and whenever such
	// a prop is set, we forward this to our aggregate.

	// With this, we can ensure that two instances of this class share the
	// same PropertySetInfo if and only if both aggregates have the same
	// service specifier.


	//--------------------------------------------------------------------
	OCommonGeometryControlModel::OCommonGeometryControlModel( Reference< XCloneable >& _rxAgg, const ::rtl::OUString& _rServiceSpecifier )
		:OGeometryControlModel_Base( _rxAgg )
		,m_sServiceSpecifier( _rServiceSpecifier )
		,m_nPropertyMapId( 0 )
	{
		Reference< XPropertySetInfo > xPI;
		if ( m_xAggregateSet.is() )
			xPI = m_xAggregateSet->getPropertySetInfo();
		if ( !xPI.is() )
		{
			releaseAggregation();
			throw IllegalArgumentException();
		}

	        HashMapString2Int &rMap = ServiceSpecifierMap::get();
		HashMapString2Int::iterator aPropMapIdPos = rMap.find( m_sServiceSpecifier );
		if ( rMap.end() == aPropMapIdPos )
		{
			PropSeqArray &rAggProperties = AggregateProperties::get();
			m_nPropertyMapId = rAggProperties.size();
			rAggProperties.push_back( xPI->getProperties() );
			AmbiguousPropertyIds::get().push_back( IntArrayArray::value_type() );

			rMap[ m_sServiceSpecifier ] = m_nPropertyMapId;
		}
		else
			m_nPropertyMapId = aPropMapIdPos->second;
	}

	//--------------------------------------------------------------------
	struct PropertyNameLess : public ::std::binary_function< Property, Property, bool >
	{
		bool operator()( const Property& _rLHS, const Property& _rRHS )
		{
			return _rLHS.Name < _rRHS.Name ? true : false;
		}
	};

	//--------------------------------------------------------------------
	struct PropertyNameEqual : public ::std::unary_function< Property, bool >
	{
		const ::rtl::OUString&	m_rCompare;
		PropertyNameEqual( const ::rtl::OUString& _rCompare ) : m_rCompare( _rCompare ) { }

		bool operator()( const Property& _rLHS )
		{
			return _rLHS.Name == m_rCompare ? true : false;
		}
	};

	//--------------------------------------------------------------------
	::cppu::IPropertyArrayHelper* OCommonGeometryControlModel::createArrayHelper( sal_Int32 _nId ) const
	{
		OSL_ENSURE( _nId == m_nPropertyMapId, "OCommonGeometryControlModel::createArrayHelper: invalid argument!" );
		OSL_ENSURE( _nId < (sal_Int32)AggregateProperties::get().size(), "OCommonGeometryControlModel::createArrayHelper: invalid status info (1)!" );
		OSL_ENSURE( _nId < (sal_Int32)AmbiguousPropertyIds::get().size(), "OCommonGeometryControlModel::createArrayHelper: invalid status info (2)!" );

		// our own properties
		Sequence< Property > aProps;
		OPropertyContainer::describeProperties( aProps );

		// the aggregate properties
		Sequence< Property > aAggregateProps;
		aAggregateProps = AggregateProperties::get()[ _nId ];

		// look for duplicates, and remember them
		IntArrayArray::value_type& rDuplicateIds = AmbiguousPropertyIds::get()[ _nId ];
		// for this, sort the aggregate properties
		::std::sort(
			aAggregateProps.getArray(),
			aAggregateProps.getArray() + aAggregateProps.getLength(),
			PropertyNameLess()
		);
		const Property* pAggProps = aAggregateProps.getConstArray();
		const Property* pAggPropsEnd = aAggregateProps.getConstArray() + aAggregateProps.getLength();

		// now loop through our own props
		const Property* pProp = aProps.getConstArray();
		const Property* pPropEnd = aProps.getConstArray() + aProps.getLength();
		while ( pProp < pPropEnd )
		{
			// look for the current property in the properties of our aggregate
			const Property* pAggPropPos = ::std::find_if( pAggProps, pAggPropsEnd, PropertyNameEqual( pProp->Name ) );
			if ( pAggPropPos != pAggPropsEnd )
			{	// found a duplicate
				// -> remove from the aggregate property sequence
				::comphelper::removeElementAt( aAggregateProps, pAggPropPos - pAggProps );
				// which means we have to adjust the pointers
				pAggProps = aAggregateProps.getConstArray(),
				pAggPropsEnd = aAggregateProps.getConstArray() + aAggregateProps.getLength(),

				// and additionally, remember the id of this property
				rDuplicateIds.push_back( pProp->Handle );
			}

			++pProp;
		}

		// now, finally, sort the duplicates
		::std::sort( rDuplicateIds.begin(), rDuplicateIds.end(), ::std::less< sal_Int32 >() );

		return new OPropertyArrayAggregationHelper(aProps, aAggregateProps);
	}

	//--------------------------------------------------------------------
	::cppu::IPropertyArrayHelper& SAL_CALL OCommonGeometryControlModel::getInfoHelper()
	{
		return *getArrayHelper( m_nPropertyMapId );
	}

	//--------------------------------------------------------------------
	OGeometryControlModel_Base* OCommonGeometryControlModel::createClone_Impl( Reference< XCloneable >& _rxAggregateInstance )
	{
		return new OCommonGeometryControlModel( _rxAggregateInstance, m_sServiceSpecifier );
	}

	//--------------------------------------------------------------------
	Sequence< sal_Int8 > SAL_CALL OCommonGeometryControlModel::getImplementationId(  ) throw (RuntimeException)
	{
		static ::cppu::OImplementationId * pId = NULL;
		if ( !pId )
		{
			::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
			if ( !pId )
			{
				static ::cppu::OImplementationId s_aId;
				pId = &s_aId;
			}
		}
		return pId->getImplementationId();
	}

	//--------------------------------------------------------------------
	struct Int32Equal : public ::std::unary_function< sal_Int32, bool >
	{
		sal_Int32	m_nCompare;
		Int32Equal( sal_Int32 _nCompare ) : m_nCompare( _nCompare ) { }

		bool operator()( sal_Int32 _nLHS )
		{
			return _nLHS == m_nCompare ? true  : false;
		}
	};

	//--------------------------------------------------------------------
	void SAL_CALL OCommonGeometryControlModel::setFastPropertyValue_NoBroadcast( sal_Int32 _nHandle, const Any& _rValue ) throw ( Exception )
	{
		OGeometryControlModel_Base::setFastPropertyValue_NoBroadcast( _nHandle, _rValue );

		// look if this id is one we recognized as duplicate
		IntArrayArray::value_type& rDuplicateIds = AmbiguousPropertyIds::get()[ m_nPropertyMapId ];

		IntArrayArray::value_type::const_iterator aPos = ::std::find_if(
			rDuplicateIds.begin(),
			rDuplicateIds.end(),
			Int32Equal( _nHandle )
		);

		if ( rDuplicateIds.end() != aPos )
		{
			// yes, it is such a property
			::rtl::OUString sPropName;
			sal_Int16 nAttributes(0);
			static_cast< OPropertyArrayAggregationHelper* >( getArrayHelper( m_nPropertyMapId ) )->fillPropertyMembersByHandle( &sPropName, &nAttributes, _nHandle );

			if ( m_xAggregateSet.is() && sPropName.getLength() )
				m_xAggregateSet->setPropertyValue( sPropName, _rValue );
		}
	}

//........................................................................
// }	// namespace toolkit
//........................................................................
