/**************************************************************
 *
 * 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/beans/PropertyState.hpp>
#include <com/sun/star/beans/PropertyAttribute.hpp>
#include <com/sun/star/awt/FontDescriptor.hpp>
#include <com/sun/star/awt/FontWidth.hpp>
#include <com/sun/star/awt/FontWeight.hpp>
#include <com/sun/star/awt/FontSlant.hpp>
#include <com/sun/star/awt/MouseWheelBehavior.hpp>
#include <com/sun/star/graphic/XGraphicProvider.hpp>
#include <com/sun/star/awt/XDevice.hpp>
#include <com/sun/star/text/WritingMode2.hpp>
#include <com/sun/star/io/XMarkableStream.hpp>
#include <toolkit/controls/unocontrolmodel.hxx>
#include <toolkit/helper/macros.hxx>
#include <cppuhelper/typeprovider.hxx>
#include <rtl/memory.h>
#include <rtl/uuid.h>
#include <tools/diagnose_ex.h>
#include <tools/string.hxx>
#include <tools/table.hxx>
#include <tools/date.hxx>
#include <tools/time.hxx>
#include <tools/urlobj.hxx>
#include <tools/debug.hxx>
#include <toolkit/helper/property.hxx>
#include <toolkit/helper/vclunohelper.hxx>
#include <toolkit/helper/emptyfontdescriptor.hxx>
#include <com/sun/star/lang/Locale.hpp>
#include <unotools/localedatawrapper.hxx>
#include <unotools/configmgr.hxx>
#include <comphelper/processfactory.hxx>
#include <comphelper/sequence.hxx>
#include <comphelper/extract.hxx>
#include <vcl/svapp.hxx>
#include <uno/data.h>

#include <memory>

using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::i18n;
using ::com::sun::star::awt::FontDescriptor;

struct ImplControlProperty
{
private:
	sal_uInt16					nId;
	::com::sun::star::uno::Any	aValue;

public:
	ImplControlProperty( const ImplControlProperty& rProp ) : aValue( rProp.aValue )
	{
		nId = rProp.nId;
	}

	ImplControlProperty( sal_uInt16 nT )
	{
		nId = nT;
	}

	ImplControlProperty( sal_uInt16 nT, const ::com::sun::star::uno::Any& rValue ) : aValue( rValue )
	{
		nId = nT;
	}

	sal_uInt16							GetId() const 											{ return nId; }
	const ::com::sun::star::uno::Any&	GetValue() const 										{ return aValue; }
	void								SetValue( const ::com::sun::star::uno::Any& rValue )	{ aValue = rValue; }
};

DECLARE_TABLE( ImplPropertyTable, ImplControlProperty* )

#define UNOCONTROL_STREAMVERSION	(short)2

static void lcl_ImplMergeFontProperty( FontDescriptor& rFD, sal_uInt16 nPropId, const Any& rValue )
{
	// some props are defined with other types than the matching FontDescriptor members have
	// (e.g. FontWidth, FontSlant)
	// 78474 - 09/19/2000 - FS
	float		nExtractFloat = 0;
	sal_Int16	nExtractShort = 0;

	switch ( nPropId )
	{
		case BASEPROPERTY_FONTDESCRIPTORPART_NAME: 			rValue >>= rFD.Name;
															break;
		case BASEPROPERTY_FONTDESCRIPTORPART_STYLENAME:		rValue >>= rFD.StyleName;
															break;
		case BASEPROPERTY_FONTDESCRIPTORPART_FAMILY: 		rValue >>= rFD.Family;
															break;
		case BASEPROPERTY_FONTDESCRIPTORPART_CHARSET: 		rValue >>= rFD.CharSet;
															break;
		case BASEPROPERTY_FONTDESCRIPTORPART_HEIGHT: 		rValue >>= nExtractFloat; rFD.Height = (sal_Int16)nExtractFloat;
															break;
		case BASEPROPERTY_FONTDESCRIPTORPART_WEIGHT: 		rValue >>= rFD.Weight;
															break;
		case BASEPROPERTY_FONTDESCRIPTORPART_SLANT: 		if ( rValue >>= nExtractShort )
																rFD.Slant = (::com::sun::star::awt::FontSlant)nExtractShort;
															else
																rValue >>= rFD.Slant;
															break;
		case BASEPROPERTY_FONTDESCRIPTORPART_UNDERLINE:		rValue >>= rFD.Underline;
															break;
		case BASEPROPERTY_FONTDESCRIPTORPART_STRIKEOUT:		rValue >>= rFD.Strikeout;
															break;
		case BASEPROPERTY_FONTDESCRIPTORPART_WIDTH:			rValue >>= rFD.Width;
															break;
		case BASEPROPERTY_FONTDESCRIPTORPART_PITCH:			rValue >>= rFD.Pitch;
															break;
		case BASEPROPERTY_FONTDESCRIPTORPART_CHARWIDTH:		rValue >>= rFD.CharacterWidth;
															break;
		case BASEPROPERTY_FONTDESCRIPTORPART_ORIENTATION: 	rValue >>= rFD.Orientation;
															break;
		case BASEPROPERTY_FONTDESCRIPTORPART_KERNING: 		rValue >>= rFD.Kerning;
															break;
		case BASEPROPERTY_FONTDESCRIPTORPART_WORDLINEMODE: 	rValue >>= rFD.WordLineMode;
															break;
		case BASEPROPERTY_FONTDESCRIPTORPART_TYPE:			rValue >>= rFD.Type;
															break;
		default: 											DBG_ERROR( "FontProperty?!" );
	}
}

//	----------------------------------------------------
//	class UnoControlModel
//	----------------------------------------------------
UnoControlModel::UnoControlModel()
    :UnoControlModel_Base()
    ,MutexAndBroadcastHelper()
    ,OPropertySetHelper( BrdcstHelper )
    ,maDisposeListeners( *this )
    ,maContext( ::comphelper::getProcessServiceFactory() )
{
    OSL_ENSURE( false, "UnoControlModel::UnoControlModel: not implemented. Well, not really." );
    // just implemented to let the various FooImplInheritanceHelper compile, you should use the
    // version taking a service factory
	mpData = new ImplPropertyTable;
}

UnoControlModel::UnoControlModel( const Reference< XMultiServiceFactory >& i_factory )
    :UnoControlModel_Base()
    ,MutexAndBroadcastHelper()
    ,OPropertySetHelper( BrdcstHelper )
    ,maDisposeListeners( *this )
    ,maContext( i_factory )
{
	// Die Properties muessen vom Model in die Tabelle gestopft werden,
	// nur vorhandene Properties sind gueltige Properties, auch wenn VOID.
	mpData = new ImplPropertyTable;
}

UnoControlModel::UnoControlModel( const UnoControlModel& rModel )
	: UnoControlModel_Base()
    , MutexAndBroadcastHelper()
    , OPropertySetHelper( BrdcstHelper )
    , maDisposeListeners( *this )
    , maContext( rModel.maContext )
{
	mpData = new ImplPropertyTable;

	for ( sal_uInt32 n = rModel.mpData->Count(); n; )
	{
		ImplControlProperty* pProp = rModel.mpData->GetObject( --n );
		ImplControlProperty* pNew = new ImplControlProperty( *pProp );
		mpData->Insert( pNew->GetId(), pNew );
	}
}

UnoControlModel::~UnoControlModel()
{
	for ( sal_uInt32 n = mpData->Count(); n; )
		delete mpData->GetObject( --n );
	delete mpData;
}

UnoControlModel* UnoControlModel::Clone() const
{
	DBG_ERROR( "UnoControlModel::Clone() ?!" );
	return NULL;
}

::com::sun::star::uno::Sequence<sal_Int32> UnoControlModel::ImplGetPropertyIds() const
{
	sal_uInt32 nIDs = mpData->Count();
	::com::sun::star::uno::Sequence<sal_Int32>	aIDs( nIDs );
	sal_Int32* pIDs = aIDs.getArray();
	for ( sal_uInt32 n = 0; n < nIDs; n++ )
		pIDs[n] = mpData->GetObjectKey( n );
	return aIDs;
}

sal_Bool UnoControlModel::ImplHasProperty( sal_uInt16 nPropId ) const
{
	if ( ( nPropId >= BASEPROPERTY_FONTDESCRIPTORPART_START ) && ( nPropId <= BASEPROPERTY_FONTDESCRIPTORPART_END ) )
		nPropId = BASEPROPERTY_FONTDESCRIPTOR;

	return mpData->Get( nPropId ) ? sal_True : sal_False;
}

::com::sun::star::uno::Any UnoControlModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const
{
	::com::sun::star::uno::Any aDefault;

    if (
        (nPropId == BASEPROPERTY_FONTDESCRIPTOR) ||
        (
         (nPropId >= BASEPROPERTY_FONTDESCRIPTORPART_START) &&
         (nPropId <= BASEPROPERTY_FONTDESCRIPTORPART_END)
        )
       )
	{
		EmptyFontDescriptor aFD;
		switch ( nPropId )
		{
			case BASEPROPERTY_FONTDESCRIPTOR: 					aDefault <<= aFD;					break;
			case BASEPROPERTY_FONTDESCRIPTORPART_NAME: 			aDefault <<= aFD.Name;				break;
			case BASEPROPERTY_FONTDESCRIPTORPART_STYLENAME:		aDefault <<= aFD.StyleName;			break;
			case BASEPROPERTY_FONTDESCRIPTORPART_FAMILY: 		aDefault <<= aFD.Family;			break;
			case BASEPROPERTY_FONTDESCRIPTORPART_CHARSET: 		aDefault <<= aFD.CharSet;			break;
			case BASEPROPERTY_FONTDESCRIPTORPART_HEIGHT: 		aDefault <<= (float)aFD.Height;		break;
			case BASEPROPERTY_FONTDESCRIPTORPART_WEIGHT: 		aDefault <<= aFD.Weight;			break;
			case BASEPROPERTY_FONTDESCRIPTORPART_SLANT: 		aDefault <<= (sal_Int16)aFD.Slant;	break;
			case BASEPROPERTY_FONTDESCRIPTORPART_UNDERLINE:		aDefault <<= aFD.Underline;			break;
			case BASEPROPERTY_FONTDESCRIPTORPART_STRIKEOUT:		aDefault <<= aFD.Strikeout;			break;
			case BASEPROPERTY_FONTDESCRIPTORPART_WIDTH:			aDefault <<= aFD.Width;				break;
			case BASEPROPERTY_FONTDESCRIPTORPART_PITCH:			aDefault <<= aFD.Pitch;				break;
			case BASEPROPERTY_FONTDESCRIPTORPART_CHARWIDTH:		aDefault <<= aFD.CharacterWidth;	break;
			case BASEPROPERTY_FONTDESCRIPTORPART_ORIENTATION:	aDefault <<= aFD.Orientation;		break;
			case BASEPROPERTY_FONTDESCRIPTORPART_KERNING:		aDefault <<= aFD.Kerning;			break;
			case BASEPROPERTY_FONTDESCRIPTORPART_WORDLINEMODE:	aDefault <<= aFD.WordLineMode;		break;
			case BASEPROPERTY_FONTDESCRIPTORPART_TYPE:			aDefault <<= aFD.Type;				break;
			default: DBG_ERROR( "FontProperty?!" );
		}
	}
    else
    {
        switch ( nPropId )
        {
			case BASEPROPERTY_GRAPHIC:
                aDefault <<= Reference< graphic::XGraphic >();
                break;

            case BASEPROPERTY_REFERENCE_DEVICE:
                aDefault <<= Reference< awt::XDevice >();
                break;

            case BASEPROPERTY_ITEM_SEPARATOR_POS:
            case BASEPROPERTY_VERTICALALIGN:
            case BASEPROPERTY_BORDERCOLOR:
            case BASEPROPERTY_SYMBOL_COLOR:
            case BASEPROPERTY_TABSTOP:
            case BASEPROPERTY_TEXTCOLOR:
            case BASEPROPERTY_TEXTLINECOLOR:
            case BASEPROPERTY_DATE:
            case BASEPROPERTY_DATESHOWCENTURY:
            case BASEPROPERTY_TIME:
            case BASEPROPERTY_VALUE_DOUBLE:
            case BASEPROPERTY_PROGRESSVALUE:
            case BASEPROPERTY_SCROLLVALUE:
            case BASEPROPERTY_VISIBLESIZE:
            case BASEPROPERTY_BACKGROUNDCOLOR:
            case BASEPROPERTY_FILLCOLOR:            break;  // Void

            case BASEPROPERTY_FONTRELIEF:
            case BASEPROPERTY_FONTEMPHASISMARK:
            case BASEPROPERTY_MAXTEXTLEN:
            case BASEPROPERTY_STATE:
            case BASEPROPERTY_EXTDATEFORMAT:
            case BASEPROPERTY_EXTTIMEFORMAT:
            case BASEPROPERTY_ECHOCHAR:             aDefault <<= (sal_Int16) 0; break;
            case BASEPROPERTY_BORDER:               aDefault <<= (sal_Int16) 1; break;
            case BASEPROPERTY_DECIMALACCURACY:      aDefault <<= (sal_Int16) 2; break;
            case BASEPROPERTY_LINECOUNT:            aDefault <<= (sal_Int16) 5; break;
            case BASEPROPERTY_ALIGN:                aDefault <<= (sal_Int16) PROPERTY_ALIGN_LEFT; break;
            case BASEPROPERTY_IMAGEALIGN:           aDefault <<= (sal_Int16) 1 /*ImageAlign::TOP*/; break;
            case BASEPROPERTY_IMAGEPOSITION:        aDefault <<= (sal_Int16) 12 /*ImagePosition::Centered*/; break;
            case BASEPROPERTY_PUSHBUTTONTYPE:       aDefault <<= (sal_Int16) 0 /*PushButtonType::STANDARD*/; break;
            case BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR:aDefault <<= (sal_Int16) awt::MouseWheelBehavior::SCROLL_FOCUS_ONLY; break;

            case BASEPROPERTY_DATEMAX:              aDefault <<= (sal_Int32) Date( 31, 12, 2200 ).GetDate();    break;
            case BASEPROPERTY_DATEMIN:              aDefault <<= (sal_Int32) Date( 1, 1, 1900 ).GetDate();  break;
            case BASEPROPERTY_TIMEMAX:              aDefault <<= (sal_Int32) Time( 23, 59 ).GetTime();  break;
            case BASEPROPERTY_TIMEMIN:              aDefault <<= (sal_Int32) 0;     break;
            case BASEPROPERTY_VALUEMAX_DOUBLE:      aDefault <<= (double) 1000000;  break;
            case BASEPROPERTY_VALUEMIN_DOUBLE:      aDefault <<= (double) -1000000; break;
            case BASEPROPERTY_VALUESTEP_DOUBLE:     aDefault <<= (double ) 1;       break;
            case BASEPROPERTY_PROGRESSVALUE_MAX:    aDefault <<= (sal_Int32) 100;   break;
            case BASEPROPERTY_PROGRESSVALUE_MIN:    aDefault <<= (sal_Int32)   0;   break;
            case BASEPROPERTY_SCROLLVALUE_MAX:		aDefault <<= (sal_Int32) 100;	break;
            case BASEPROPERTY_SCROLLVALUE_MIN:		aDefault <<= (sal_Int32)   0;	break;
            case BASEPROPERTY_LINEINCREMENT:		aDefault <<= (sal_Int32)   1;	break;
            case BASEPROPERTY_BLOCKINCREMENT:		aDefault <<= (sal_Int32)  10;	break;
            case BASEPROPERTY_ORIENTATION:			aDefault <<= (sal_Int32)   0;	break;
            case BASEPROPERTY_SPINVALUE:            aDefault <<= (sal_Int32)   0;   break;
            case BASEPROPERTY_SPININCREMENT:        aDefault <<= (sal_Int32)   1;   break;
            case BASEPROPERTY_SPINVALUE_MIN:        aDefault <<= (sal_Int32)   0;   break;
            case BASEPROPERTY_SPINVALUE_MAX:        aDefault <<= (sal_Int32) 100;   break;
            case BASEPROPERTY_REPEAT_DELAY:         aDefault <<= (sal_Int32)  50;   break;    // 50 milliseconds
            case BASEPROPERTY_DEFAULTCONTROL:       aDefault <<= ((UnoControlModel*)this)->getServiceName();    break;

            case BASEPROPERTY_AUTOHSCROLL:
            case BASEPROPERTY_AUTOVSCROLL:
            case BASEPROPERTY_MOVEABLE:
            case BASEPROPERTY_CLOSEABLE:
            case BASEPROPERTY_SIZEABLE:
            case BASEPROPERTY_HSCROLL:
            case BASEPROPERTY_DEFAULTBUTTON:
            case BASEPROPERTY_MULTILINE:
            case BASEPROPERTY_MULTISELECTION:
            case BASEPROPERTY_TRISTATE:
            case BASEPROPERTY_DROPDOWN:
            case BASEPROPERTY_SPIN:
            case BASEPROPERTY_READONLY:
            case BASEPROPERTY_VSCROLL:
            case BASEPROPERTY_NUMSHOWTHOUSANDSEP:
            case BASEPROPERTY_STRICTFORMAT:
            case BASEPROPERTY_REPEAT:
            case BASEPROPERTY_PAINTTRANSPARENT:
            case BASEPROPERTY_DESKTOP_AS_PARENT:
            case BASEPROPERTY_HARDLINEBREAKS:
            case BASEPROPERTY_NOLABEL:              aDefault <<= (sal_Bool) sal_False; break;

            case BASEPROPERTY_MULTISELECTION_SIMPLEMODE:
            case BASEPROPERTY_HIDEINACTIVESELECTION:
			case BASEPROPERTY_ENFORCE_FORMAT:
            case BASEPROPERTY_AUTOCOMPLETE:
            case BASEPROPERTY_SCALEIMAGE:
            case BASEPROPERTY_ENABLED:
            case BASEPROPERTY_PRINTABLE:
            case BASEPROPERTY_ENABLEVISIBLE:
            case BASEPROPERTY_DECORATION:           aDefault <<= (sal_Bool) sal_True; break;

            case BASEPROPERTY_HELPTEXT:
            case BASEPROPERTY_HELPURL:
	        case BASEPROPERTY_IMAGEURL:
	        case BASEPROPERTY_DIALOGSOURCEURL:
            case BASEPROPERTY_EDITMASK:
            case BASEPROPERTY_LITERALMASK:
            case BASEPROPERTY_LABEL:
            case BASEPROPERTY_TITLE:
            case BASEPROPERTY_TEXT:                 aDefault <<= ::rtl::OUString(); break;

            case BASEPROPERTY_WRITING_MODE:
            case BASEPROPERTY_CONTEXT_WRITING_MODE:
                aDefault <<= text::WritingMode2::CONTEXT;
                break;

            case BASEPROPERTY_STRINGITEMLIST:
            {
                ::com::sun::star::uno::Sequence< ::rtl::OUString> aStringSeq;
                aDefault <<= aStringSeq;

            }
            break;
            case BASEPROPERTY_SELECTEDITEMS:
            {
                ::com::sun::star::uno::Sequence<sal_Int16> aINT16Seq;
                aDefault <<= aINT16Seq;
            }
            break;
            case BASEPROPERTY_CURRENCYSYMBOL:
            {
				Any aDefaultCurrency = ::utl::ConfigManager::GetDirectConfigProperty(::utl::ConfigManager::DEFAULTCURRENCY);
				DBG_ASSERT( TypeClass_STRING == aDefaultCurrency.getValueTypeClass(), "UnoControlModel::ImplGetDefaultValue: invalid currency config value!" );

				::rtl::OUString sDefaultCurrency;
				aDefaultCurrency >>= sDefaultCurrency;

				// extract the bank symbol
				sal_Int32 nSepPos = sDefaultCurrency.indexOf( '-' );
				::rtl::OUString sBankSymbol;
				if ( nSepPos >= 0 )
				{
					sBankSymbol = sDefaultCurrency.copy( 0, nSepPos );
					sDefaultCurrency = sDefaultCurrency.copy( nSepPos + 1 );
				}

				// the remaming is the locale
				Locale aLocale;
				nSepPos = sDefaultCurrency.indexOf( '-' );
				if ( nSepPos >= 0 )
				{
					aLocale.Language = sDefaultCurrency.copy( 0, nSepPos );
					aLocale.Country = sDefaultCurrency.copy( nSepPos + 1 );
				}

				LocaleDataWrapper aLocaleInfo( maContext.getLegacyServiceFactory(), aLocale );
				if ( !sBankSymbol.getLength() )
					sBankSymbol = aLocaleInfo.getCurrBankSymbol();

				// look for the currency entry (for this language) which has the given bank symbol
				Sequence< Currency2 > aAllCurrencies = aLocaleInfo.getAllCurrencies();
				const Currency2* pAllCurrencies		=						aAllCurrencies.getConstArray();
				const Currency2* pAllCurrenciesEnd	=	pAllCurrencies	+	aAllCurrencies.getLength();

				::rtl::OUString sCurrencySymbol = aLocaleInfo.getCurrSymbol();
				if ( !sBankSymbol.getLength() )
				{
					DBG_ASSERT( pAllCurrencies != pAllCurrenciesEnd, "UnoControlModel::ImplGetDefaultValue: no currencies at all!" );
					if ( pAllCurrencies != pAllCurrenciesEnd )
					{
						sBankSymbol = pAllCurrencies->BankSymbol;
						sCurrencySymbol = pAllCurrencies->Symbol;
					}
				}

				if ( sBankSymbol.getLength() )
				{
                    bool bLegacy = false;
					for ( ;pAllCurrencies != pAllCurrenciesEnd; ++pAllCurrencies )
						if ( pAllCurrencies->BankSymbol == sBankSymbol )
						{
                            sCurrencySymbol = pAllCurrencies->Symbol;
                            if ( pAllCurrencies->LegacyOnly )
                                bLegacy = true;
                            else
                                break;
						}
					DBG_ASSERT( bLegacy || pAllCurrencies != pAllCurrenciesEnd, "UnoControlModel::ImplGetDefaultValue: did not find the given bank symbol!" );
				}

				aDefault <<= sCurrencySymbol;
            }
            break;

            default:    DBG_ERROR( "ImplGetDefaultValue - unknown Property" );
        }
    }

	return aDefault;
}

void UnoControlModel::ImplRegisterProperty( sal_uInt16 nPropId, const ::com::sun::star::uno::Any& rDefault )
{
	ImplControlProperty* pProp = new ImplControlProperty( nPropId, rDefault );
	mpData->Insert( nPropId, pProp );
}

void UnoControlModel::ImplRegisterProperty( sal_uInt16 nPropId )
{
	ImplRegisterProperty( nPropId, ImplGetDefaultValue( nPropId ) );

    if ( nPropId == BASEPROPERTY_FONTDESCRIPTOR )
    {
        // some properties are not included in the FontDescriptor, but every time
        // when we have a FontDescriptor we want to have these properties too.
        // => Easier to register the here, istead everywhere where I register the FontDescriptor...

        ImplRegisterProperty( BASEPROPERTY_TEXTCOLOR );
        ImplRegisterProperty( BASEPROPERTY_TEXTLINECOLOR );
        ImplRegisterProperty( BASEPROPERTY_FONTRELIEF );
        ImplRegisterProperty( BASEPROPERTY_FONTEMPHASISMARK );
    }
}

void UnoControlModel::ImplRegisterProperties( const std::list< sal_uInt16 > &rIds )
{
    std::list< sal_uInt16 >::const_iterator iter;
    for( iter = rIds.begin(); iter != rIds.end(); iter++) {
        if( !ImplHasProperty( *iter ) )
            ImplRegisterProperty( *iter, ImplGetDefaultValue( *iter ) );
    }
}

// ::com::sun::star::uno::XInterface
::com::sun::star::uno::Any UnoControlModel::queryAggregation( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException)
{
    Any aRet = UnoControlModel_Base::queryAggregation( rType );
    if ( !aRet.hasValue() )
        aRet = ::cppu::OPropertySetHelper::queryInterface( rType );
    return aRet;
}

// ::com::sun::star::lang::XUnoTunnel
IMPL_XUNOTUNNEL( UnoControlModel )

// XInterface
IMPLEMENT_FORWARD_REFCOUNT( UnoControlModel, UnoControlModel_Base )

// ::com::sun::star::lang::XTypeProvider
IMPLEMENT_FORWARD_XTYPEPROVIDER2( UnoControlModel, UnoControlModel_Base, ::cppu::OPropertySetHelper )


uno::Reference< util::XCloneable > UnoControlModel::createClone() throw(::com::sun::star::uno::RuntimeException)
{
	UnoControlModel* pClone = Clone();
	uno::Reference< util::XCloneable > xClone( (::cppu::OWeakObject*) pClone, uno::UNO_QUERY );
	return xClone;
}

// ::com::sun::star::lang::XComponent
void UnoControlModel::dispose(  ) throw(::com::sun::star::uno::RuntimeException)
{
	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );

	::com::sun::star::lang::EventObject aEvt;
	aEvt.Source = (::com::sun::star::uno::XAggregation*)(::cppu::OWeakAggObject*)this;
	maDisposeListeners.disposeAndClear( aEvt );

	BrdcstHelper.aLC.disposeAndClear( aEvt );

	// let the property set helper notify our property listeners
	OPropertySetHelper::disposing();
}

void UnoControlModel::addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& rxListener ) throw(::com::sun::star::uno::RuntimeException)
{
	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );

	maDisposeListeners.addInterface( rxListener );
}

void UnoControlModel::removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& rxListener ) throw(::com::sun::star::uno::RuntimeException)
{
	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );

	maDisposeListeners.removeInterface( rxListener );
}


// ::com::sun::star::beans::XPropertyState
::com::sun::star::beans::PropertyState UnoControlModel::getPropertyState( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException)
{
	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );

	sal_uInt16 nPropId = GetPropertyId( PropertyName );

	::com::sun::star::uno::Any aValue = getPropertyValue( PropertyName );
	::com::sun::star::uno::Any aDefault = ImplGetDefaultValue( nPropId );

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

::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyState > UnoControlModel::getPropertyStates( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& PropertyNames ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException)
{
	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );

	sal_uInt32 nNames = PropertyNames.getLength();
	const ::rtl::OUString* pNames = PropertyNames.getConstArray();

	::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyState > aStates( nNames );
	::com::sun::star::beans::PropertyState* pStates = aStates.getArray();

	for ( sal_uInt32 n = 0; n < nNames; n++ )
		pStates[n] = getPropertyState( pNames[n] );

	return aStates;
}

void UnoControlModel::setPropertyToDefault( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException)
{
    Any aDefaultValue;
    {
	    ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
        aDefaultValue = ImplGetDefaultValue( GetPropertyId( PropertyName ) );
    }
	setPropertyValue( PropertyName, aDefaultValue );
}

::com::sun::star::uno::Any UnoControlModel::getPropertyDefault( const ::rtl::OUString& rPropertyName ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
{
	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );

	return ImplGetDefaultValue( GetPropertyId( rPropertyName ) );
}


// ::com::sun::star::io::XPersistObjec
::rtl::OUString UnoControlModel::getServiceName(  ) throw(::com::sun::star::uno::RuntimeException)
{
	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );

	DBG_ERROR( "ServiceName von UnoControlModel ?!" );
	return ::rtl::OUString();
}

void UnoControlModel::write( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream >& OutStream ) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
{
	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );

	::com::sun::star::uno::Reference< ::com::sun::star::io::XMarkableStream > xMark( OutStream, ::com::sun::star::uno::UNO_QUERY );
	DBG_ASSERT( xMark.is(), "write: no ::com::sun::star::io::XMarkableStream!" );

	OutStream->writeShort( UNOCONTROL_STREAMVERSION );

	ImplPropertyTable aProps;
	sal_uInt32 i;
	for ( i = mpData->Count(); i; )
	{
		ImplControlProperty* pProp = mpData->GetObject( --i );
		if ( ( ( GetPropertyAttribs( pProp->GetId() ) & ::com::sun::star::beans::PropertyAttribute::TRANSIENT ) == 0 )
			&& ( getPropertyState( GetPropertyName( pProp->GetId() ) ) != ::com::sun::star::beans::PropertyState_DEFAULT_VALUE ) )
		{
			aProps.Insert( pProp->GetId(), pProp );
		}
	}

	sal_uInt32 nProps = aProps.Count();

	// FontProperty wegen fehlender Unterscheidung zwischen 5.0 / 5.1
	// immer im alten Format mitspeichern.
	OutStream->writeLong( (long) aProps.IsKeyValid( BASEPROPERTY_FONTDESCRIPTOR ) ? ( nProps + 3 ) : nProps );
	for ( i = 0; i < nProps; i++ )
	{
		sal_Int32 nPropDataBeginMark = xMark->createMark();
		OutStream->writeLong( 0L );	// DataLen

		ImplControlProperty* pProp = aProps.GetObject( i );
		OutStream->writeShort( pProp->GetId() );

		sal_Bool bVoid = pProp->GetValue().getValueType().getTypeClass() == ::com::sun::star::uno::TypeClass_VOID;

		OutStream->writeBoolean( bVoid );

		if ( !bVoid )
		{
			const ::com::sun::star::uno::Any& rValue = pProp->GetValue();
			const ::com::sun::star::uno::Type& rType = rValue.getValueType();

			if ( rType == ::getBooleanCppuType() )
			{
				sal_Bool b = false;
				rValue >>= b;
				OutStream->writeBoolean( b );
			}
			else if ( rType == ::getCppuType((const ::rtl::OUString*)0) )
			{
				::rtl::OUString aUString;
				rValue >>= aUString;
				OutStream->writeUTF( aUString );
			}
			else if ( rType == ::getCppuType((const sal_uInt16*)0) )
			{
				sal_uInt16 n = 0;
				rValue >>= n;
				OutStream->writeShort( n );
			}
			else if ( rType == ::getCppuType((const sal_Int16*)0) )
			{
				sal_Int16 n = 0;
				rValue >>= n;
				OutStream->writeShort( n );
			}
			else if ( rType == ::getCppuType((const sal_uInt32*)0) )
			{
				sal_uInt32 n = 0;
				rValue >>= n;
				OutStream->writeLong( n );
			}
			else if ( rType == ::getCppuType((const sal_Int32*)0) )
			{
				sal_Int32 n = 0;
				rValue >>= n;
				OutStream->writeLong( n );
			}
			else if ( rType == ::getCppuType((const double*)0) )
			{
				double n = 0;
				rValue >>= n;
				OutStream->writeDouble( n );
			}
			else if ( rType == ::getCppuType((const ::com::sun::star::awt::FontDescriptor*)0) )
			{
				::com::sun::star::awt::FontDescriptor aFD;
				rValue >>= aFD;
				OutStream->writeUTF( aFD.Name );
				OutStream->writeShort( aFD.Height );
				OutStream->writeShort( aFD.Width );
				OutStream->writeUTF( aFD.StyleName );
				OutStream->writeShort( aFD.Family );
				OutStream->writeShort( aFD.CharSet );
				OutStream->writeShort( aFD.Pitch );
				OutStream->writeDouble( aFD.CharacterWidth );
				OutStream->writeDouble( aFD.Weight );
				OutStream->writeShort(
                    sal::static_int_cast< sal_Int16 >(aFD.Slant) );
				OutStream->writeShort( aFD.Underline );
				OutStream->writeShort( aFD.Strikeout );
				OutStream->writeDouble( aFD.Orientation );
				OutStream->writeBoolean( aFD.Kerning );
				OutStream->writeBoolean( aFD.WordLineMode );
				OutStream->writeShort( aFD.Type );
			}
			else if ( rType == ::getCppuType((const ::com::sun::star::uno::Sequence< ::rtl::OUString>*)0 ) )
			{
				::com::sun::star::uno::Sequence< ::rtl::OUString> aSeq;
				rValue >>= aSeq;
				long nEntries = aSeq.getLength();
				OutStream->writeLong( nEntries );
				for ( long n = 0; n < nEntries; n++ )
					OutStream->writeUTF( aSeq.getConstArray()[n] );
			}
			else if ( rType == ::getCppuType((const ::com::sun::star::uno::Sequence<sal_uInt16>*)0 ) )
			{
				::com::sun::star::uno::Sequence<sal_uInt16> aSeq;
				rValue >>= aSeq;
				long nEntries = aSeq.getLength();
				OutStream->writeLong( nEntries );
				for ( long n = 0; n < nEntries; n++ )
					OutStream->writeShort( aSeq.getConstArray()[n] );
			}
			else if ( rType == ::getCppuType((const ::com::sun::star::uno::Sequence<sal_Int16>*)0 ) )
			{
				::com::sun::star::uno::Sequence<sal_Int16> aSeq;
				rValue >>= aSeq;
				long nEntries = aSeq.getLength();
				OutStream->writeLong( nEntries );
				for ( long n = 0; n < nEntries; n++ )
					OutStream->writeShort( aSeq.getConstArray()[n] );
			}
			else if ( rType.getTypeClass() == TypeClass_ENUM )
            {
                sal_Int32 nAsInt = 0;
                ::cppu::enum2int( nAsInt, rValue );
				OutStream->writeLong( nAsInt );
            }
#if OSL_DEBUG_LEVEL > 0
            else
			{
                ::rtl::OString sMessage( "UnoControlModel::write: don't know how to handle a property of type '" );
                ::rtl::OUString sTypeName( rType.getTypeName() );
                sMessage += ::rtl::OString( sTypeName.getStr(), sTypeName.getLength(), RTL_TEXTENCODING_ASCII_US );
                sMessage += "'.\n(Currently handling property '";
                ::rtl::OUString sPropertyName( GetPropertyName( pProp->GetId() ) );
                sMessage += ::rtl::OString( sPropertyName.getStr(), sPropertyName.getLength(), osl_getThreadTextEncoding() );
                sMessage += "'.)";
				DBG_ERROR( sMessage );
			}
#endif
		}

		sal_Int32 nPropDataLen = xMark->offsetToMark( nPropDataBeginMark );
		xMark->jumpToMark( nPropDataBeginMark );
		OutStream->writeLong( nPropDataLen );
		xMark->jumpToFurthest();
		xMark->deleteMark(nPropDataBeginMark);
	}

	ImplControlProperty* pProp = aProps.Get( BASEPROPERTY_FONTDESCRIPTOR );
	if ( pProp )
	{
		// Solange wir keinen 5.0-Export haben, muss das alte
		// Format mit rausgeschrieben werden...
		::com::sun::star::awt::FontDescriptor aFD;
		pProp->GetValue() >>= aFD;

		for ( sal_uInt16 n = BASEPROPERTY_FONT_TYPE; n <= BASEPROPERTY_FONT_ATTRIBS; n++ )
		{
			sal_Int32 nPropDataBeginMark = xMark->createMark();
			OutStream->writeLong( 0L );	// DataLen
			OutStream->writeShort( n );	// PropId
			OutStream->writeBoolean( sal_False );	// Void

			if ( n == BASEPROPERTY_FONT_TYPE )
			{
				OutStream->writeUTF( aFD.Name );
				OutStream->writeUTF( aFD.StyleName );
				OutStream->writeShort( aFD.Family );
				OutStream->writeShort( aFD.CharSet );
				OutStream->writeShort( aFD.Pitch );
			}
			else if ( n == BASEPROPERTY_FONT_SIZE )
			{
				OutStream->writeLong( aFD.Width );
				OutStream->writeLong( aFD.Height );
				OutStream->writeShort(
                    sal::static_int_cast< sal_Int16 >(
                        VCLUnoHelper::ConvertFontWidth( aFD.CharacterWidth )) );
			}
			else if ( n == BASEPROPERTY_FONT_ATTRIBS )
			{
				OutStream->writeShort(
                    sal::static_int_cast< sal_Int16 >(
                        VCLUnoHelper::ConvertFontWeight( aFD.Weight )) );
				OutStream->writeShort(
                    sal::static_int_cast< sal_Int16 >(aFD.Slant) );
				OutStream->writeShort( aFD.Underline );
				OutStream->writeShort( aFD.Strikeout );
				OutStream->writeShort( (short)(aFD.Orientation * 10) );
				OutStream->writeBoolean( aFD.Kerning );
				OutStream->writeBoolean( aFD.WordLineMode );
			}
			else
			{
				DBG_ERROR( "Property?!" );
			}

			sal_Int32 nPropDataLen = xMark->offsetToMark( nPropDataBeginMark );
			xMark->jumpToMark( nPropDataBeginMark );
			OutStream->writeLong( nPropDataLen );
			xMark->jumpToFurthest();
			xMark->deleteMark(nPropDataBeginMark);
		}
	}
}

void UnoControlModel::read( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream >& InStream ) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
{
	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );

	::com::sun::star::uno::Reference< ::com::sun::star::io::XMarkableStream > xMark( InStream, ::com::sun::star::uno::UNO_QUERY );
	DBG_ASSERT( xMark.is(), "read: no ::com::sun::star::io::XMarkableStream!" );

	short nVersion = InStream->readShort();
	sal_uInt32 nProps = (sal_uInt32)InStream->readLong();
	::com::sun::star::uno::Sequence< ::rtl::OUString> aProps( nProps );
	::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any> aValues( nProps );
	sal_Bool bInvalidEntries = sal_False;

	// Dummerweise kein Mark fuer den gesamten Block, es koennen also
	// nur Properties geaendert werden, es koennen aber nicht spaeter mal Daten
	// fuer das Model hinter den Properties geschrieben werden.

	// Fuer den Import der alten ::com::sun::star::awt::FontDescriptor-Teile
	::com::sun::star::awt::FontDescriptor* pFD = NULL;

	sal_uInt32 i;
	for ( i = 0; i < nProps; i++ )
	{
		sal_Int32 nPropDataBeginMark = xMark->createMark();
		sal_Int32 nPropDataLen = InStream->readLong();

		sal_uInt16 nPropId = (sal_uInt16)InStream->readShort();

		::com::sun::star::uno::Any aValue;
		sal_Bool bIsVoid = InStream->readBoolean();
		if ( !bIsVoid )
		{
			const ::com::sun::star::uno::Type* pType = mpData->Get( nPropId ) ? GetPropertyType( nPropId ) : NULL;
			if ( pType )
			{
				if ( *pType == ::getBooleanCppuType() )
				{
					sal_Bool b = InStream->readBoolean();
					aValue <<= b;
				}
				else if ( *pType == ::getCppuType((const ::rtl::OUString*)0) )
				{
					::rtl::OUString aUTF = InStream->readUTF();
					aValue <<= aUTF;
				}
				else if ( *pType == ::getCppuType((const sal_uInt16*)0) )
				{
					sal_uInt16 n = InStream->readShort();
					aValue <<= n;
				}
				else if ( *pType == ::getCppuType((const sal_Int16*)0) )
				{
					sal_Int16 n = InStream->readShort();
					aValue <<= n;
				}
				else if ( *pType == ::getCppuType((const sal_uInt32*)0) )
				{
					sal_uInt32 n = InStream->readLong();
					aValue <<= n;
				}
				else if ( *pType == ::getCppuType((const sal_Int32*)0) )
				{
					sal_Int32 n = InStream->readLong();
					aValue <<= n;
				}
				else if ( *pType == ::getCppuType((const double*)0) )
				{
					double n = InStream->readDouble();
					aValue <<= n;
				}
				else if ( *pType == ::getCppuType((const ::com::sun::star::awt::FontDescriptor*)0) )
				{
					::com::sun::star::awt::FontDescriptor aFD;
					aFD.Name = InStream->readUTF();
					aFD.Height = InStream->readShort();
					aFD.Width = InStream->readShort();
					aFD.StyleName = InStream->readUTF();
					aFD.Family = InStream->readShort();
					aFD.CharSet = InStream->readShort();
					aFD.Pitch = InStream->readShort();
					aFD.CharacterWidth = (float)InStream->readDouble();
					aFD.Weight = (float)InStream->readDouble();
					aFD.Slant =  (::com::sun::star::awt::FontSlant)InStream->readShort();
					aFD.Underline = InStream->readShort();
					aFD.Strikeout = InStream->readShort();
					aFD.Orientation = (float)InStream->readDouble();
					aFD.Kerning = InStream->readBoolean();
					aFD.WordLineMode = InStream->readBoolean();
					aFD.Type = InStream->readShort();
					aValue <<= aFD;
				}
				else if ( *pType == ::getCppuType((const ::com::sun::star::uno::Sequence< ::rtl::OUString>*)0 ) )
				{
					long nEntries = InStream->readLong();
					::com::sun::star::uno::Sequence< ::rtl::OUString> aSeq( nEntries );
					for ( long n = 0; n < nEntries; n++ )
						aSeq.getArray()[n] = InStream->readUTF();
					aValue <<= aSeq;

				}
				else if ( *pType == ::getCppuType((const ::com::sun::star::uno::Sequence<sal_uInt16>*)0 ) )

				{
					long nEntries = InStream->readLong();
					::com::sun::star::uno::Sequence<sal_uInt16> aSeq( nEntries );
					for ( long n = 0; n < nEntries; n++ )
						aSeq.getArray()[n] = (sal_uInt16)InStream->readShort();
					aValue <<= aSeq;
				}
				else if ( *pType == ::getCppuType((const ::com::sun::star::uno::Sequence<sal_Int16>*)0 ) )
				{
					long nEntries = InStream->readLong();
					::com::sun::star::uno::Sequence<sal_Int16> aSeq( nEntries );
					for ( long n = 0; n < nEntries; n++ )
						aSeq.getArray()[n] = (sal_Int16)InStream->readShort();
					aValue <<= aSeq;
				}
                else if ( pType->getTypeClass() == TypeClass_ENUM )
                {
                    sal_Int32 nAsInt = InStream->readLong();
                    aValue = ::cppu::int2enum( nAsInt, *pType );
                }
                else
                {
                    ::rtl::OString sMessage( "UnoControlModel::read: don't know how to handle a property of type '" );
                    ::rtl::OUString sTypeName( pType->getTypeName() );
                    sMessage += ::rtl::OString( sTypeName.getStr(), sTypeName.getLength(), RTL_TEXTENCODING_ASCII_US );
                    sMessage += "'.\n(Currently handling property '";
                    ::rtl::OUString sPropertyName( GetPropertyName( nPropId ) );
                    sMessage += ::rtl::OString( sPropertyName.getStr(), sPropertyName.getLength(), osl_getThreadTextEncoding() );
                    sMessage += "'.)";
				    DBG_ERROR( sMessage );
                }
			}
			else
			{
				// Altes Geraffel aus 5.0
				if ( nPropId == BASEPROPERTY_FONT_TYPE )
				{
					// Sonst ist es nur die redundante Info fuer alte Versionen
					// Daten werden durch MarkableStream geskippt.
					if ( nVersion < 2 )
					{
						if ( !pFD )
						{
							pFD = new ::com::sun::star::awt::FontDescriptor;
							ImplControlProperty* pProp = mpData->Get( BASEPROPERTY_FONTDESCRIPTOR );
							if ( pProp ) // wegen den Defaults...
								pProp->GetValue() >>= *pFD;
						}
						pFD->Name = InStream->readUTF();
						pFD->StyleName = InStream->readUTF();
						pFD->Family = InStream->readShort();
						pFD->CharSet = InStream->readShort();
						pFD->Pitch = InStream->readShort();
					}
				}
				else if ( nPropId == BASEPROPERTY_FONT_SIZE )
				{
					if ( nVersion < 2 )
					{
						if ( !pFD )
						{
							pFD = new ::com::sun::star::awt::FontDescriptor;
							ImplControlProperty* pProp = mpData->Get( BASEPROPERTY_FONTDESCRIPTOR );
							if ( pProp ) // wegen den Defaults...
								pProp->GetValue() >>= *pFD;
						}
						pFD->Width = (sal_Int16)InStream->readLong();
						pFD->Height = (sal_Int16)InStream->readLong();
						InStream->readShort();	// ::com::sun::star::awt::FontWidth ignorieren - wurde mal falsch geschrieben und wird nicht gebraucht.
						pFD->CharacterWidth = ::com::sun::star::awt::FontWidth::DONTKNOW;
					}
				}
				else if ( nPropId == BASEPROPERTY_FONT_ATTRIBS )
				{
					if ( nVersion < 2 )
					{
 						if ( !pFD )
						{
							pFD = new ::com::sun::star::awt::FontDescriptor;
							ImplControlProperty* pProp = mpData->Get( BASEPROPERTY_FONTDESCRIPTOR );
							if ( pProp ) // wegen den Defaults...
								pProp->GetValue() >>= *pFD;
						}
						pFD->Weight = VCLUnoHelper::ConvertFontWeight( (FontWeight) InStream->readShort() );
						pFD->Slant =  (::com::sun::star::awt::FontSlant)InStream->readShort();
						pFD->Underline = InStream->readShort();
						pFD->Strikeout = InStream->readShort();
						pFD->Orientation = ( (float)(double)InStream->readShort() ) / 10;
						pFD->Kerning = InStream->readBoolean();
						pFD->WordLineMode = InStream->readBoolean();
					}
				}
				else
				{
					DBG_ERROR( "read: unknown Property!" );
				}
			}
		}
		else // bVoid
		{
			if ( nPropId == BASEPROPERTY_FONTDESCRIPTOR )
			{
				EmptyFontDescriptor aFD;
				aValue <<= aFD;
			}
		}

		if ( mpData->Get( nPropId ) )
		{
			aProps.getArray()[i] = GetPropertyName( nPropId );
			aValues.getArray()[i] = aValue;
		}
		else
		{
			bInvalidEntries = sal_True;
		}

		// Falls bereits mehr drinsteht als diese Version kennt:
		xMark->jumpToMark( nPropDataBeginMark );
		InStream->skipBytes( nPropDataLen );
		xMark->deleteMark(nPropDataBeginMark);
	}
	if ( bInvalidEntries )
	{
		for ( i = 0; i < (sal_uInt32)aProps.getLength(); i++ )
		{
			if ( !aProps.getConstArray()[i].getLength() )
			{
				::comphelper::removeElementAt( aProps, i );
				::comphelper::removeElementAt( aValues, i );
				i--;
			}
		}
	}

    try
    {
        setPropertyValues( aProps, aValues );
    }
    catch ( const Exception& )
    {
        DBG_UNHANDLED_EXCEPTION();
    }

	if ( pFD )
	{
		::com::sun::star::uno::Any aValue;
		aValue <<= *pFD;
		setPropertyValue( GetPropertyName( BASEPROPERTY_FONTDESCRIPTOR ), aValue );
		delete pFD;
	}
}


// ::com::sun::star::lang::XServiceInfo
::rtl::OUString UnoControlModel::getImplementationName(  ) throw(::com::sun::star::uno::RuntimeException)
{
	DBG_ERROR( "This method should be overloaded!" );
	return ::rtl::OUString();

}

sal_Bool UnoControlModel::supportsService( const ::rtl::OUString& rServiceName ) throw(::com::sun::star::uno::RuntimeException)
{
	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );

	::com::sun::star::uno::Sequence< ::rtl::OUString > aSNL = getSupportedServiceNames();
	const ::rtl::OUString * pArray = aSNL.getConstArray();
	for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
		if( pArray[i] == rServiceName )
			return sal_True;
	return sal_False;
}

::com::sun::star::uno::Sequence< ::rtl::OUString > UnoControlModel::getSupportedServiceNames(  ) throw(::com::sun::star::uno::RuntimeException)
{
	::rtl::OUString sName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.UnoControlModel" ) );
	return Sequence< ::rtl::OUString >( &sName, 1 );
}

// ::cppu::OPropertySetHelper
::cppu::IPropertyArrayHelper& UnoControlModel::getInfoHelper()
{
	DBG_ERROR( "UnoControlModel::getInfoHelper() not possible!" );
	return *(::cppu::IPropertyArrayHelper*) NULL;
}

// ------------------------------------------------------------------
template <class TYPE>
sal_Bool convertType(Any& _rConvertedValue, const Any& _rNewValueTest, const TYPE* /* _pTypeDisambiguation */)
{
	TYPE tValue;
	if (_rNewValueTest >>= tValue)
	{
		_rConvertedValue <<= tValue;
		return sal_True;
	}
}

// ..................................................................
sal_Bool UnoControlModel::convertFastPropertyValue( Any & rConvertedValue, Any & rOldValue, sal_Int32 nPropId, const Any& rValue ) throw (IllegalArgumentException)
{
	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );

	sal_Bool bVoid = rValue.getValueType().getTypeClass() == ::com::sun::star::uno::TypeClass_VOID;
	if ( bVoid )
	{
		rConvertedValue.clear();
	}
	else
	{
		const ::com::sun::star::uno::Type* pDestType = GetPropertyType( (sal_uInt16)nPropId );
		if ( pDestType->getTypeClass() == TypeClass_ANY )
		{
			rConvertedValue = rValue;
		}
		else
		{
			if ( pDestType->equals( rValue.getValueType() ) )
            {
                rConvertedValue = rValue;
            }
			else
			{
				sal_Bool bConverted = sal_False;
				// 13.03.2001 - 84923 - frank.schoenheit@germany.sun.com

				switch (pDestType->getTypeClass())
				{
					case TypeClass_DOUBLE:
					{
						// try as double
						double nAsDouble = 0;
                        bConverted = ( rValue >>= nAsDouble );
						if ( bConverted )
							rConvertedValue <<= nAsDouble;
						else
						{	// try as integer - 96136 - 2002-10-08 - fs@openoffice.org
							sal_Int32 nAsInteger = 0;
                            bConverted = ( rValue >>= nAsInteger );
							if ( bConverted )
								rConvertedValue <<= (double)nAsInteger;
						}
					}
					break;
					case TypeClass_SHORT:
                    {
                        sal_Int16 n;
                        bConverted = ( rValue >>= n );
                        if ( bConverted )
                            rConvertedValue <<= n;
                    }
					break;
					case TypeClass_UNSIGNED_SHORT:
                    {
                        sal_uInt16 n;
                        bConverted = ( rValue >>= n );
                        if ( bConverted )
                            rConvertedValue <<= n;
                    }
					break;
					case TypeClass_LONG:
                    {
                        sal_Int32 n;
                        bConverted = ( rValue >>= n );
                        if ( bConverted )
                            rConvertedValue <<= n;
                    }
					break;
					case TypeClass_UNSIGNED_LONG:
                    {
                        sal_uInt32 n;
                        bConverted = ( rValue >>= n );
                        if ( bConverted )
                            rConvertedValue <<= n;
                    }
					break;
					case TypeClass_INTERFACE:
					{
						if ( rValue.getValueType().getTypeClass() == TypeClass_INTERFACE )
						{
							Reference< XInterface > xPure( rValue, UNO_QUERY );
							if ( xPure.is() )
								rConvertedValue = xPure->queryInterface( *pDestType );
                            else
                                rConvertedValue.setValue( NULL, *pDestType );
							bConverted = sal_True;
						}
					}
					break;
					case TypeClass_ENUM:
					{
                        sal_Int32 nValue = 0;
                        bConverted = ( rValue >>= nValue );
                        if ( bConverted )
                            rConvertedValue = ::cppu::int2enum( nValue, *pDestType );
					}
					break;
					default: ; // avoid compiler warning
				}

				if (!bConverted)
                {
                    ::rtl::OUStringBuffer aErrorMessage;
                    aErrorMessage.appendAscii( "Unable to convert the given value for the property " );
                    aErrorMessage.append     ( GetPropertyName( (sal_uInt16)nPropId ) );
                    aErrorMessage.appendAscii( ".\n" );
                    aErrorMessage.appendAscii( "Expected type: " );
                    aErrorMessage.append     ( pDestType->getTypeName() );
                    aErrorMessage.appendAscii( "\n" );
                    aErrorMessage.appendAscii( "Found type: " );
                    aErrorMessage.append     ( rValue.getValueType().getTypeName() );
					throw ::com::sun::star::lang::IllegalArgumentException(
                        aErrorMessage.makeStringAndClear(),
						static_cast< ::com::sun::star::beans::XPropertySet* >(this),
						1);
                }
			}
		}
	}

	// the current value
	getFastPropertyValue( rOldValue, nPropId );
	return !CompareProperties( rConvertedValue, rOldValue );
}

void UnoControlModel::setFastPropertyValue_NoBroadcast( sal_Int32 nPropId, const ::com::sun::star::uno::Any& rValue ) throw (::com::sun::star::uno::Exception)
{
	// Fehlt: Die gefakten Einzelproperties des FontDescriptors...

	ImplControlProperty* pProp = mpData->Get( nPropId );
    ENSURE_OR_RETURN_VOID( pProp, "UnoControlModel::setFastPropertyValue_NoBroadcast: invalid property id!" );

    DBG_ASSERT( ( rValue.getValueType().getTypeClass() != ::com::sun::star::uno::TypeClass_VOID ) || ( GetPropertyAttribs( (sal_uInt16)nPropId ) & ::com::sun::star::beans::PropertyAttribute::MAYBEVOID ), "Property darf nicht VOID sein!" );
	pProp->SetValue( rValue );
}

void UnoControlModel::getFastPropertyValue( ::com::sun::star::uno::Any& rValue, sal_Int32 nPropId ) const
{
	::osl::Guard< ::osl::Mutex > aGuard( ((UnoControlModel*)this)->GetMutex() );

	ImplControlProperty* pProp = mpData->Get( nPropId );

	if ( pProp )
		rValue = pProp->GetValue();
	else if ( ( nPropId >= BASEPROPERTY_FONTDESCRIPTORPART_START ) && ( nPropId <= BASEPROPERTY_FONTDESCRIPTORPART_END ) )
	{
		pProp = mpData->Get( BASEPROPERTY_FONTDESCRIPTOR );
		::com::sun::star::awt::FontDescriptor aFD;
		pProp->GetValue() >>= aFD;
		switch ( nPropId )
		{
			case BASEPROPERTY_FONTDESCRIPTORPART_NAME: 			rValue <<= aFD.Name;
																break;
			case BASEPROPERTY_FONTDESCRIPTORPART_STYLENAME:		rValue <<= aFD.StyleName;
																break;
			case BASEPROPERTY_FONTDESCRIPTORPART_FAMILY: 		rValue <<= aFD.Family;
																break;
			case BASEPROPERTY_FONTDESCRIPTORPART_CHARSET: 		rValue <<= aFD.CharSet;
																break;
			case BASEPROPERTY_FONTDESCRIPTORPART_HEIGHT: 		rValue <<= (float)aFD.Height;
																break;
			case BASEPROPERTY_FONTDESCRIPTORPART_WEIGHT: 		rValue <<= aFD.Weight;
																break;
			case BASEPROPERTY_FONTDESCRIPTORPART_SLANT: 		rValue <<= (sal_Int16)aFD.Slant;
																break;
			case BASEPROPERTY_FONTDESCRIPTORPART_UNDERLINE:		rValue <<= aFD.Underline;
																break;
			case BASEPROPERTY_FONTDESCRIPTORPART_STRIKEOUT:		rValue <<= aFD.Strikeout;
																break;
			case BASEPROPERTY_FONTDESCRIPTORPART_WIDTH:			rValue <<= aFD.Width;
																break;
			case BASEPROPERTY_FONTDESCRIPTORPART_PITCH:			rValue <<= aFD.Pitch;
																break;
			case BASEPROPERTY_FONTDESCRIPTORPART_CHARWIDTH:		rValue <<= aFD.CharacterWidth;
																break;
			case BASEPROPERTY_FONTDESCRIPTORPART_ORIENTATION:	rValue <<= aFD.Orientation;
																break;
			case BASEPROPERTY_FONTDESCRIPTORPART_KERNING:		rValue <<= aFD.Kerning;
																break;
			case BASEPROPERTY_FONTDESCRIPTORPART_WORDLINEMODE:	rValue <<= aFD.WordLineMode;
																break;
			case BASEPROPERTY_FONTDESCRIPTORPART_TYPE:			rValue <<= aFD.Type;
																break;
			default: DBG_ERROR( "FontProperty?!" );
		}
	}
	else
	{
		DBG_ERROR( "getFastPropertyValue - invalid Property!" );
	}
}

// ::com::sun::star::beans::XPropertySet
void UnoControlModel::setPropertyValue( const ::rtl::OUString& rPropertyName, const ::com::sun::star::uno::Any& rValue ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
{
    sal_Int32 nPropId = 0;
    {
	    ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
	    nPropId = (sal_Int32) GetPropertyId( rPropertyName );
	    DBG_ASSERT( nPropId, "Invalid ID in UnoControlModel::setPropertyValue" );
    }
	if( nPropId )
		setFastPropertyValue( nPropId, rValue );
	else
		throw ::com::sun::star::beans::UnknownPropertyException();
}

// ::com::sun::star::beans::XFastPropertySet
void UnoControlModel::setFastPropertyValue( sal_Int32 nPropId, const ::com::sun::star::uno::Any& rValue ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
{
	if ( ( nPropId >= BASEPROPERTY_FONTDESCRIPTORPART_START ) && ( nPropId <= BASEPROPERTY_FONTDESCRIPTORPART_END ) )
	{
		::osl::ClearableMutexGuard aGuard( GetMutex() );

        Any aOldSingleValue;
        getFastPropertyValue( aOldSingleValue, BASEPROPERTY_FONTDESCRIPTORPART_START );

        ImplControlProperty* pProp = mpData->Get( BASEPROPERTY_FONTDESCRIPTOR );
		FontDescriptor aOldFontDescriptor;
		pProp->GetValue() >>= aOldFontDescriptor;

        FontDescriptor aNewFontDescriptor( aOldFontDescriptor );
		lcl_ImplMergeFontProperty( aNewFontDescriptor, (sal_uInt16)nPropId, rValue );

		Any aNewValue;
		aNewValue <<= aNewFontDescriptor;
        sal_Int32 nDescriptorId( BASEPROPERTY_FONTDESCRIPTOR );
		nDescriptorId = BASEPROPERTY_FONTDESCRIPTOR;

        // also, we need  fire a propertyChange event for the single property, since with
        // the above line, only an event for the FontDescriptor property will be fired
        Any aNewSingleValue;
        getFastPropertyValue( aNewSingleValue, BASEPROPERTY_FONTDESCRIPTORPART_START );

        aGuard.clear();
		setFastPropertyValues( 1, &nDescriptorId, &aNewValue, 1 );
        fire( &nPropId, &aNewSingleValue, &aOldSingleValue, 1, sal_False );
   	}
    else
		setFastPropertyValues( 1, &nPropId, &rValue, 1 );
}

// ::com::sun::star::beans::XMultiPropertySet
::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > UnoControlModel::getPropertySetInfo(  ) throw(::com::sun::star::uno::RuntimeException)
{
	DBG_ERROR( "UnoControlModel::getPropertySetInfo() not possible!" );
	return ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo >();
}

void UnoControlModel::setPropertyValues( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rPropertyNames, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& Values ) throw(::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
{
	::osl::ClearableMutexGuard aGuard( GetMutex() );

	sal_Int32 nProps = rPropertyNames.getLength();

//	sal_Int32* pHandles = new sal_Int32[nProps];
        // don't do this - it leaks in case of an exception
    Sequence< sal_Int32 > aHandles( nProps );
	sal_Int32* pHandles = aHandles.getArray();

	// may need to change the order in the sequence, for this we need a non-const value sequence
	// 15.05.2002 - 99314 - fs@openoffice.org
	uno::Sequence< uno::Any > aValues( Values );
	uno::Any* pValues = aValues.getArray();

	sal_Int32 nValidHandles = getInfoHelper().fillHandles( pHandles, rPropertyNames );

	if ( nValidHandles )
	{
		// if somebody sets properties which are single aspects of a font descriptor,
        // remove them, and build a font descriptor instead
        ::std::auto_ptr< awt::FontDescriptor > pFD;
		for ( sal_uInt16 n = 0; n < nProps; ++n )
		{
			if ( ( pHandles[n] >= BASEPROPERTY_FONTDESCRIPTORPART_START ) && ( pHandles[n] <= BASEPROPERTY_FONTDESCRIPTORPART_END ) )
			{
				if ( !pFD.get() )
				{
					ImplControlProperty* pProp = mpData->Get( BASEPROPERTY_FONTDESCRIPTOR );
					pFD.reset( new awt::FontDescriptor );
					pProp->GetValue() >>= *pFD;
				}
				lcl_ImplMergeFontProperty( *pFD, (sal_uInt16)pHandles[n], pValues[n] );
				pHandles[n] = -1;
				nValidHandles--;
			}
		}

		if ( nValidHandles )
		{
			ImplNormalizePropertySequence( nProps, pHandles, pValues, &nValidHandles );
            aGuard.clear();
                // clear our guard before calling into setFastPropertyValues - this method
                // will implicitly call property listeners, and this should not happen with
                // our mutex locked
                // #i23451# - 2004-03-18 - fs@openoffice.org
 			setFastPropertyValues( nProps, pHandles, pValues, nValidHandles );
		}
        else
            aGuard.clear();
            // same as a few lines above

		// FD-Propertie nicht in das Array mergen, weil sortiert...
		if ( pFD.get() )
		{
			::com::sun::star::uno::Any aValue;
			aValue <<= *pFD;
			sal_Int32 nHandle = BASEPROPERTY_FONTDESCRIPTOR;
			setFastPropertyValues( 1, &nHandle, &aValue, 1 );
		}
	}
}



void UnoControlModel::ImplNormalizePropertySequence( const sal_Int32, sal_Int32*,
	uno::Any*, sal_Int32* ) const SAL_THROW(())
{
	// nothing to do here
}

void UnoControlModel::ImplEnsureHandleOrder( const sal_Int32 _nCount, sal_Int32* _pHandles,
        uno::Any* _pValues, sal_Int32 _nFirstHandle, sal_Int32 _nSecondHandle ) const
{
	for ( sal_Int32 i=0; i < _nCount; ++_pHandles, ++_pValues, ++i )
	{
		if ( _nSecondHandle  == *_pHandles )
		{
			sal_Int32* pLaterHandles = _pHandles + 1;
			uno::Any* pLaterValues = _pValues + 1;
			for ( sal_Int32 j = i + 1; j < _nCount; ++j, ++pLaterHandles, ++pLaterValues )
			{
				if ( _nFirstHandle == *pLaterHandles )
				{
					// indeed it is -> exchange the both places in the sequences
					sal_Int32 nHandle( *_pHandles );
					*_pHandles = *pLaterHandles;
					*pLaterHandles = nHandle;

					uno::Any aValue( *_pValues );
					*_pValues = *pLaterValues;
					*pLaterValues = aValue;

					break;
					// this will leave the inner loop, and continue with the outer loop.
					// Note that this means we will encounter the _nSecondHandle handle, again, once we reached
					// (in the outer loop) the place where we just put it.
				}
			}
		}
	}
}
