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

#include <stdio.h>
#include "propertyexport.hxx"
#include <xmloff/xmlexp.hxx>
#include "strings.hxx"
#include "xmloff/xmlnmspe.hxx"
#include <xmloff/xmluconv.hxx>
#include <xmloff/families.hxx>
#include <osl/diagnose.h>
#include <com/sun/star/beans/PropertyAttribute.hpp>
#include <com/sun/star/util/Date.hpp>
#include <com/sun/star/util/Time.hpp>
#include <com/sun/star/util/DateTime.hpp>
#include <osl/diagnose.h>
#include <comphelper/extract.hxx>
#include <comphelper/sequence.hxx>
#include <comphelper/types.hxx>
#include "callbacks.hxx"
#include <unotools/datetime.hxx>
#include <tools/date.hxx>
#include <tools/time.hxx>
#include <tools/datetime.hxx>

//.........................................................................
namespace xmloff
{
//.........................................................................

	using namespace ::com::sun::star::uno;
	using namespace ::com::sun::star::lang;
	using namespace ::com::sun::star::beans;

	// NO using namespace ...util !!!
	// need a tools Date/Time/DateTime below, which would conflict with the uno types then

	using namespace ::comphelper;

	//=====================================================================
	//= OPropertyExport
	//=====================================================================
	//---------------------------------------------------------------------
	OPropertyExport::OPropertyExport(IFormsExportContext& _rContext, const Reference< XPropertySet >& _rxProps)
		:m_rContext(_rContext)
		,m_xProps(_rxProps)
        ,m_xPropertyInfo( m_xProps->getPropertySetInfo() )
        ,m_xPropertyState( _rxProps, UNO_QUERY )
	{
		// caching
		::rtl::OUStringBuffer aBuffer;
		m_rContext.getGlobalContext().GetMM100UnitConverter().convertBool(aBuffer, sal_True);
		m_sValueTrue = aBuffer.makeStringAndClear();
		m_rContext.getGlobalContext().GetMM100UnitConverter().convertBool(aBuffer, sal_False);
		m_sValueFalse = aBuffer.makeStringAndClear();

		OSL_ENSURE(m_xPropertyInfo.is(), "OPropertyExport::OPropertyExport: need an XPropertySetInfo!");

		// collect the properties which need to be exported
		examinePersistence();
	}

	//---------------------------------------------------------------------
    bool OPropertyExport::shouldExportProperty( const ::rtl::OUString& i_propertyName ) const
    {
		// if the property state is DEFAULT, it does not need to be written - at least
        // if it's a built-in property, and not a dynamically-added one.
        bool bIsDefaultValue =    m_xPropertyState.is()
                            &&  ( PropertyState_DEFAULT_VALUE == m_xPropertyState->getPropertyState( i_propertyName ) );
        bool bIsDynamicProperty =  m_xPropertyInfo.is()
                                && ( ( m_xPropertyInfo->getPropertyByName( i_propertyName ).Attributes & PropertyAttribute::REMOVEABLE ) != 0 );
		return ( !bIsDefaultValue || bIsDynamicProperty );
    }

	//---------------------------------------------------------------------
	void OPropertyExport::exportRemainingProperties()
	{
		// the properties tag (will be created if we have at least one no-default property)
		SvXMLElementExport* pPropertiesTag = NULL;

		try
		{
			Any aValue;
			::rtl::OUString sValue;

			// loop through all the properties which are yet to be exported
			for	(	ConstStringSetIterator	aProperty = m_aRemainingProps.begin();
					aProperty != m_aRemainingProps.end();
					++aProperty
				)
			{
				DBG_CHECK_PROPERTY_NO_TYPE(*aProperty);

	#if OSL_DEBUG_LEVEL > 0
				const ::rtl::OUString sPropertyName = *aProperty; (void)sPropertyName;
	#endif
                if ( !shouldExportProperty( *aProperty ) )
                    continue;

				// now that we have the first sub-tag we need the form:properties element
				if (!pPropertiesTag)
					pPropertiesTag = new SvXMLElementExport(m_rContext.getGlobalContext(), XML_NAMESPACE_FORM, token::XML_PROPERTIES, sal_True, sal_True);

				// add the name attribute
				AddAttribute(XML_NAMESPACE_FORM, token::XML_PROPERTY_NAME, *aProperty);

				// get the value
				aValue = m_xProps->getPropertyValue(*aProperty);

                // the type to export
                Type aExportType;

                // is it a sequence
				sal_Bool bIsSequence = TypeClass_SEQUENCE == aValue.getValueTypeClass();
				// the type of the property, maybe reduced to the element type of a sequence
				if (bIsSequence)
					aExportType = getSequenceElementType( aValue.getValueType() );
				else
					aExportType = aValue.getValueType();

				// the type attribute
				// modified by BerryJia for Bug102407
                bool bIsEmptyValue = TypeClass_VOID == aValue.getValueType().getTypeClass();
                if ( bIsEmptyValue )
                {
                    com::sun::star::beans::Property aPropDesc;
				    aPropDesc = m_xPropertyInfo->getPropertyByName( *aProperty );
                    aExportType = aPropDesc.Type;
                }
				token::XMLTokenEnum eValueType = implGetPropertyXMLType( aExportType );

				if ( bIsEmptyValue )
					AddAttribute( XML_NAMESPACE_OFFICE, token::XML_VALUE_TYPE, token::XML_VOID );
				else
					AddAttribute( XML_NAMESPACE_OFFICE, token::XML_VALUE_TYPE, eValueType );

                token::XMLTokenEnum eValueAttName( token::XML_VALUE );
                switch ( eValueType )
                {
                case token::XML_BOOLEAN:    eValueAttName = token::XML_BOOLEAN_VALUE; break;
                case token::XML_STRING:     eValueAttName = token::XML_STRING_VALUE;  break;
                default:    break;
                }

				if( !bIsSequence && !bIsEmptyValue )
				{	// the simple case
					//add by BerryJia for Bug102407
					sValue = implConvertAny(aValue);
					AddAttribute(XML_NAMESPACE_OFFICE, eValueAttName, sValue );
				}


				// start the property tag
				SvXMLElementExport aValueTag1(m_rContext.getGlobalContext(),
						XML_NAMESPACE_FORM,
						bIsSequence ? token::XML_LIST_PROPERTY
									: token::XML_PROPERTY, sal_True, sal_True);

				if (!bIsSequence)
					continue;

				// the not-that-simple case, we need to iterate through the sequence elements
				IIterator* pSequenceIterator = NULL;

				switch ( aExportType.getTypeClass() )
				{
					case TypeClass_STRING:
						pSequenceIterator = new OSequenceIterator< ::rtl::OUString >(aValue);
						break;
					case TypeClass_DOUBLE:
						pSequenceIterator = new OSequenceIterator< double >(aValue);
						break;
					case TypeClass_BOOLEAN:
						pSequenceIterator = new OSequenceIterator< sal_Bool >(aValue);
						break;
					case TypeClass_BYTE:
						pSequenceIterator = new OSequenceIterator< sal_Int8 >(aValue);
						break;
					case TypeClass_SHORT:
						pSequenceIterator = new OSequenceIterator< sal_Int16 >(aValue);
						break;
					case TypeClass_LONG:
						pSequenceIterator = new OSequenceIterator< sal_Int32 >(aValue);
						break;
					case TypeClass_HYPER:
						pSequenceIterator = new OSequenceIterator< sal_Int64 >(aValue);
						break;
					default:
						OSL_ENSURE(sal_False, "OPropertyExport::exportRemainingProperties: unsupported sequence tyoe !");
						break;
				}
				if (pSequenceIterator)
				{
					while (pSequenceIterator->hasMoreElements())
					{
						sValue =
							implConvertAny(pSequenceIterator->nextElement());
						AddAttribute(XML_NAMESPACE_OFFICE, eValueAttName, sValue );
						SvXMLElementExport aValueTag(
								m_rContext.getGlobalContext(),
								XML_NAMESPACE_FORM, token::XML_LIST_VALUE,
								sal_True, sal_False);
					}
				}
				delete pSequenceIterator;
			}
		}
		catch(...)
		{
			delete pPropertiesTag;
			throw;
		}
		delete pPropertiesTag;
	}

	//---------------------------------------------------------------------
	void OPropertyExport::examinePersistence()
	{
		m_aRemainingProps.clear();
		Sequence< Property > aProperties = m_xPropertyInfo->getProperties();
		const Property* pProperties = aProperties.getConstArray();
		for (sal_Int32 i=0; i<aProperties.getLength(); ++i, ++pProperties)
		{
			// no transient props
            if ( pProperties->Attributes & PropertyAttribute::TRANSIENT )
                continue;
            // no read-only props
            if ( ( pProperties->Attributes & PropertyAttribute::READONLY ) != 0 )
                // except they're dynamically added
                if ( ( pProperties->Attributes & PropertyAttribute::REMOVEABLE ) == 0 )
				    continue;
			m_aRemainingProps.insert(pProperties->Name);
		}
	}

	//---------------------------------------------------------------------
	void OPropertyExport::exportStringPropertyAttribute( const sal_uInt16 _nNamespaceKey, const sal_Char* _pAttributeName,
			const ::rtl::OUString& _rPropertyName )
	{
		DBG_CHECK_PROPERTY( _rPropertyName, ::rtl::OUString );

		// no try-catch here, this would be to expensive. The outer scope has to handle exceptions (which should not
		// happen if we're used correctly :)

		// this is way simple, as we don't need to convert anything (the property already is a string)

		// get the string
		::rtl::OUString sPropValue;
		m_xProps->getPropertyValue( _rPropertyName ) >>= sPropValue;

		// add the attribute
		if ( sPropValue.getLength() )
			AddAttribute( _nNamespaceKey, _pAttributeName, sPropValue );

		// the property does not need to be handled anymore
		exportedProperty( _rPropertyName );
	}

	//---------------------------------------------------------------------
	void OPropertyExport::exportBooleanPropertyAttribute(const sal_uInt16 _nNamespaceKey, const sal_Char* _pAttributeName,
			const ::rtl::OUString& _rPropertyName, const sal_Int8 _nBooleanAttributeFlags)
	{
		DBG_CHECK_PROPERTY_NO_TYPE( _rPropertyName );
		// no check of the property value type: this method is allowed to be called with any integer properties
		// (e.g. sal_Int32, sal_uInt16 etc)

		sal_Bool bDefault = (BOOLATTR_DEFAULT_TRUE == (BOOLATTR_DEFAULT_MASK & _nBooleanAttributeFlags));
		sal_Bool bDefaultVoid = (BOOLATTR_DEFAULT_VOID == (BOOLATTR_DEFAULT_MASK & _nBooleanAttributeFlags));

		// get the value
		sal_Bool bCurrentValue = bDefault;
		Any aCurrentValue = m_xProps->getPropertyValue( _rPropertyName );
		if (aCurrentValue.hasValue())
		{
			bCurrentValue = ::cppu::any2bool(aCurrentValue);
			// this will extract a boolean value even if the Any contains a int or short or something like that ...

			if (_nBooleanAttributeFlags & BOOLATTR_INVERSE_SEMANTICS)
				bCurrentValue = !bCurrentValue;

			// we have a non-void current value
			if (bDefaultVoid || (bDefault != bCurrentValue))
				// and (the default is void, or the non-void default does not equal the current value)
				// -> write the attribute
				AddAttribute(_nNamespaceKey, _pAttributeName, bCurrentValue ? m_sValueTrue : m_sValueFalse);
		}
		else
			// we have a void current value
			if (!bDefaultVoid)
				// and we have a non-void default
				// -> write the attribute
				AddAttribute(_nNamespaceKey, _pAttributeName, bCurrentValue ? m_sValueTrue : m_sValueFalse);

		// the property does not need to be handled anymore
		exportedProperty( _rPropertyName );
	}

	//---------------------------------------------------------------------
	void OPropertyExport::exportInt16PropertyAttribute(const sal_uInt16 _nNamespaceKey, const sal_Char* _pAttributeName,
		const ::rtl::OUString& _rPropertyName, const sal_Int16 _nDefault)
	{
		DBG_CHECK_PROPERTY( _rPropertyName, sal_Int16 );

		// get the value
		sal_Int16 nCurrentValue(_nDefault);
		m_xProps->getPropertyValue( _rPropertyName ) >>= nCurrentValue;

		// add the attribute
		if (_nDefault != nCurrentValue)
		{
			// let the formatter of the export context build a string
			::rtl::OUStringBuffer sBuffer;
			m_rContext.getGlobalContext().GetMM100UnitConverter().convertNumber(sBuffer, (sal_Int32)nCurrentValue);

			AddAttribute(_nNamespaceKey, _pAttributeName, sBuffer.makeStringAndClear());
		}

		// the property does not need to be handled anymore
		exportedProperty( _rPropertyName );
	}

	//---------------------------------------------------------------------
	void OPropertyExport::exportInt32PropertyAttribute( const sal_uInt16 _nNamespaceKey, const sal_Char* _pAttributeName,
		const ::rtl::OUString& _rPropertyName, const sal_Int32 _nDefault )
	{
		DBG_CHECK_PROPERTY( _rPropertyName, sal_Int32 );

		// get the value
		sal_Int32 nCurrentValue( _nDefault );
		m_xProps->getPropertyValue( _rPropertyName ) >>= nCurrentValue;

		// add the attribute
		if ( _nDefault != nCurrentValue )
		{
			// let the formatter of the export context build a string
			::rtl::OUStringBuffer sBuffer;
			m_rContext.getGlobalContext().GetMM100UnitConverter().convertNumber( sBuffer, nCurrentValue );

			AddAttribute( _nNamespaceKey, _pAttributeName, sBuffer.makeStringAndClear() );
		}

		// the property does not need to be handled anymore
		exportedProperty( _rPropertyName );
	}

	//---------------------------------------------------------------------
	void OPropertyExport::exportEnumPropertyAttribute(
			const sal_uInt16 _nNamespaceKey, const sal_Char* _pAttributeName,
			const sal_Char* _pPropertyName, const SvXMLEnumMapEntry* _pValueMap,
			const sal_Int32 _nDefault, const sal_Bool _bVoidDefault)
	{
		// get the value
		sal_Int32 nCurrentValue(_nDefault);
		::rtl::OUString sPropertyName(::rtl::OUString::createFromAscii(_pPropertyName));
		Any aValue = m_xProps->getPropertyValue(sPropertyName);

		if (aValue.hasValue())
		{	// we have a non-void current value
			::cppu::enum2int(nCurrentValue, aValue);

			// add the attribute
			if ((_nDefault != nCurrentValue) || _bVoidDefault)
			{	// the default does not equal the value, or the default is void and the value isn't

				// let the formatter of the export context build a string
				::rtl::OUStringBuffer sBuffer;
				m_rContext.getGlobalContext().GetMM100UnitConverter().convertEnum(sBuffer, (sal_uInt16)nCurrentValue, _pValueMap);

				AddAttribute(_nNamespaceKey, _pAttributeName, sBuffer.makeStringAndClear());
			}
		}
		else
		{
			if (!_bVoidDefault)
				AddAttributeASCII(_nNamespaceKey, _pAttributeName, "");
		}

		// the property does not need to be handled anymore
		exportedProperty(sPropertyName);
	}

	//---------------------------------------------------------------------
	void OPropertyExport::exportTargetFrameAttribute()
	{
		DBG_CHECK_PROPERTY( PROPERTY_TARGETFRAME, ::rtl::OUString );

		::rtl::OUString sTargetFrame = comphelper::getString(m_xProps->getPropertyValue(PROPERTY_TARGETFRAME));
		if (0 != sTargetFrame.compareToAscii("_blank"))
		{	// an empty string and "_blank" have the same meaning and don't have to be written
			AddAttribute(OAttributeMetaData::getCommonControlAttributeNamespace(CCA_TARGET_FRAME)
						,OAttributeMetaData::getCommonControlAttributeName(CCA_TARGET_FRAME)
						,sTargetFrame);
		}

		exportedProperty(PROPERTY_TARGETFRAME);
	}

	//---------------------------------------------------------------------
	void OPropertyExport::exportRelativeTargetLocation(const ConstAsciiString& _sPropertyName,sal_Int32 _nProperty,bool _bAddType)
	{
		DBG_CHECK_PROPERTY( _sPropertyName, ::rtl::OUString );

		::rtl::OUString sTargetLocation = comphelper::getString(m_xProps->getPropertyValue(_sPropertyName));
        if ( sTargetLocation.getLength() )
                    // If this isn't a GraphicObject then GetRelativeReference
                    // will be called anyway ( in AddEmbeddedGraphic )
		    sTargetLocation = m_rContext.getGlobalContext().AddEmbeddedGraphicObject(sTargetLocation);
		AddAttribute(OAttributeMetaData::getCommonControlAttributeNamespace(_nProperty)
					,OAttributeMetaData::getCommonControlAttributeName(_nProperty)
					, sTargetLocation);

        // #i110911# add xlink:type="simple" if required
        if (_bAddType)
            AddAttribute(XML_NAMESPACE_XLINK, token::XML_TYPE, token::XML_SIMPLE);

		exportedProperty(_sPropertyName);
	}
	//---------------------------------------------------------------------
	void OPropertyExport::flagStyleProperties()
	{
		// flag all the properties which are part of the style as "handled"
		UniReference< XMLPropertySetMapper > xStylePropertiesSupplier = m_rContext.getStylePropertyMapper()->getPropertySetMapper();
		for (sal_Int32 i=0; i<xStylePropertiesSupplier->GetEntryCount(); ++i)
			exportedProperty(xStylePropertiesSupplier->GetEntryAPIName(i));

		// the font properties are exported as single properties, but there is a FontDescriptor property which
		// collects them all-in-one, this has been exported implicitly
		exportedProperty(PROPERTY_FONT);

		// for the DateFormat and TimeFormat, there exist wrapper properties which has been exported as
		// style, too
		exportedProperty(PROPERTY_DATEFORMAT);
		exportedProperty(PROPERTY_TIMEFORMAT);

        // the following properties should have been exported at the shape already:
        exportedProperty( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "VerticalAlign" ) ) );
        exportedProperty( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "WritingMode" ) ) );
        exportedProperty( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ScaleMode" ) ) );
        // ditto the TextWritingMode
		exportedProperty( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "WritingMode" ) ) );
	}

	//---------------------------------------------------------------------
	void OPropertyExport::exportGenericPropertyAttribute(
			const sal_uInt16 _nAttributeNamespaceKey, const sal_Char* _pAttributeName, const sal_Char* _pPropertyName)
	{
		DBG_CHECK_PROPERTY_ASCII_NO_TYPE( _pPropertyName );

		::rtl::OUString sPropertyName = ::rtl::OUString::createFromAscii(_pPropertyName);
		exportedProperty(sPropertyName);

		Any aCurrentValue = m_xProps->getPropertyValue(sPropertyName);
		if (!aCurrentValue.hasValue())
			// nothing to do without a concrete value
			return;

		::rtl::OUString sValue = implConvertAny(aCurrentValue);
		if (!sValue.getLength() && (TypeClass_STRING == aCurrentValue.getValueTypeClass()))
		{
			// check whether or not the property is allowed to be VOID
			Property aProperty = m_xPropertyInfo->getPropertyByName(sPropertyName);
			if ((aProperty.Attributes & PropertyAttribute::MAYBEVOID) == 0)
				// the string is empty, and the property is not allowed to be void
				// -> don't need to write the attibute, 'cause missing it is unambiguous
				return;
		}

		// finally add the attribute to the context
		AddAttribute(_nAttributeNamespaceKey, _pAttributeName, sValue);
	}

	//---------------------------------------------------------------------
	void OPropertyExport::exportStringSequenceAttribute(const sal_uInt16 _nAttributeNamespaceKey, const sal_Char* _pAttributeName,
		const ::rtl::OUString& _rPropertyName,
		const sal_Unicode _aQuoteCharacter, const sal_Unicode _aListSeparator)
	{
		DBG_CHECK_PROPERTY( _rPropertyName, Sequence< ::rtl::OUString > );
		OSL_ENSURE(_aListSeparator != 0, "OPropertyExport::exportStringSequenceAttribute: invalid separator character!");

		Sequence< ::rtl::OUString > aItems;
		m_xProps->getPropertyValue( _rPropertyName ) >>= aItems;

		::rtl::OUString sFinalList;

		// unfortunately the OUString can't append single sal_Unicode characters ...
		const ::rtl::OUString sQuote(&_aQuoteCharacter, 1);
		const ::rtl::OUString sSeparator(&_aListSeparator, 1);
		const sal_Bool bQuote = 0 != sQuote.getLength();

		// concatenate the string items
		const ::rtl::OUString* pItems = aItems.getConstArray();
		const ::rtl::OUString* pEnd = pItems + aItems.getLength();
		const ::rtl::OUString* pLastElement = pEnd - 1;
		for	(	;
				pItems != pEnd;
				++pItems
			)
		{
			OSL_ENSURE(!_aQuoteCharacter || (-1 == pItems->indexOf(_aQuoteCharacter)),
				"OPropertyExport::exportStringSequenceAttribute: there is an item which contains the quote character!");
			OSL_ENSURE(_aQuoteCharacter || (-1 == pItems->indexOf(_aListSeparator)),
				"OPropertyExport::exportStringSequenceAttribute: no quote character, but there is an item containing the separator character!");

			if (bQuote)
				sFinalList += sQuote;
			sFinalList += *pItems;
			if (bQuote)
				sFinalList += sQuote;

			if (pItems != pLastElement)
				sFinalList += sSeparator;
		}

		if (sFinalList.getLength())
			AddAttribute(_nAttributeNamespaceKey, _pAttributeName, sFinalList);

		exportedProperty( _rPropertyName );
	}

	//---------------------------------------------------------------------
	::rtl::OUString OPropertyExport::implConvertAny(const Any& _rValue)
	{
		::rtl::OUStringBuffer aBuffer;
		switch (_rValue.getValueTypeClass())
		{
			case TypeClass_STRING:
			{	// extract the string
				::rtl::OUString sCurrentValue;
				_rValue >>= sCurrentValue;
				aBuffer.append(sCurrentValue);
			}
			break;
			case TypeClass_DOUBLE:
				// let the unit converter format is as string
				m_rContext.getGlobalContext().GetMM100UnitConverter().convertDouble(aBuffer, getDouble(_rValue));
				break;
			case TypeClass_BOOLEAN:
				aBuffer = getBOOL(_rValue) ? m_sValueTrue : m_sValueFalse;
				break;
			case TypeClass_BYTE:
			case TypeClass_SHORT:
			case TypeClass_LONG:
				// let the unit converter format is as string
				m_rContext.getGlobalContext().GetMM100UnitConverter().convertNumber(aBuffer, getINT32(_rValue));
				break;
			case TypeClass_HYPER:
				// TODO
				OSL_ENSURE(sal_False, "OPropertyExport::implConvertAny: missing implementation for sal_Int64!");
				break;
			case TypeClass_ENUM:
			{
				// convert it into an int32
				sal_Int32 nValue = 0;
				::cppu::enum2int(nValue, _rValue);
				m_rContext.getGlobalContext().GetMM100UnitConverter().convertNumber(aBuffer, nValue);
			}
			break;
			default:
			{	// hmmm .... what else do we know?
				double fValue = 0;
				::com::sun::star::util::Date aDate;
				::com::sun::star::util::Time aTime;
				::com::sun::star::util::DateTime aDateTime;
				if (_rValue >>= aDate)
				{
					Date aToolsDate;
					::utl::typeConvert(aDate, aToolsDate);
					fValue = aToolsDate.GetDate();
				}
				else if (_rValue >>= aTime)
				{
					fValue = ((aTime.Hours * 60 + aTime.Minutes) * 60 + aTime.Seconds) * 100 + aTime.HundredthSeconds;
					fValue = fValue / 8640000.0;
				}
				else if (_rValue >>= aDateTime)
				{
					DateTime aToolsDateTime;
					::utl::typeConvert(aDateTime, aToolsDateTime);
					// the time part (the digits behind the comma)
					fValue = ((aDateTime.Hours * 60 + aDateTime.Minutes) * 60 + aDateTime.Seconds) * 100 + aDateTime.HundredthSeconds;
					fValue = fValue / 8640000.0;
					// plus the data part (the digits in front of the comma)
					fValue += aToolsDateTime.GetDate();
				}
				else
				{
					// if any other types are added here, please remember to adjust implGetPropertyXMLType accordingly

					// no more options ...
					OSL_ENSURE(sal_False, "OPropertyExport::implConvertAny: unsupported value type!");
					break;
				}
				// let the unit converter format is as string
				m_rContext.getGlobalContext().GetMM100UnitConverter().convertDouble(aBuffer, fValue);
			}
			break;
		}

		return aBuffer.makeStringAndClear();
	}


	//---------------------------------------------------------------------
	token::XMLTokenEnum OPropertyExport::implGetPropertyXMLType(const ::com::sun::star::uno::Type& _rType)
	{
		// handle the type description
		switch (_rType.getTypeClass())
		{
			case TypeClass_STRING:
				return token::XML_STRING;
			case TypeClass_DOUBLE:
			case TypeClass_BYTE:
			case TypeClass_SHORT:
			case TypeClass_LONG:
			case TypeClass_HYPER:
			case TypeClass_ENUM:
				return token::XML_FLOAT;
			case TypeClass_BOOLEAN:
				return token::XML_BOOLEAN;

			default:
				return token::XML_FLOAT;
		}
	}

#ifdef DBG_UTIL
	//---------------------------------------------------------------------
	void OPropertyExport::AddAttribute(sal_uInt16 _nPrefix, const sal_Char* _pName, const ::rtl::OUString& _rValue)
	{
		OSL_ENSURE(0 == m_rContext.getGlobalContext().GetXAttrList()->getValueByName(::rtl::OUString::createFromAscii(_pName)).getLength(),
			"OPropertyExport::AddAttribute: already have such an attribute");

		m_rContext.getGlobalContext().AddAttribute(_nPrefix, _pName, _rValue);
	}

    //---------------------------------------------------------------------
    void OPropertyExport::AddAttribute( sal_uInt16 _nPrefix, const ::rtl::OUString& _rName, const ::rtl::OUString& _rValue )
    {
        OSL_ENSURE(0 == m_rContext.getGlobalContext().GetXAttrList()->getValueByName( _rName ).getLength(),
            "OPropertyExport::AddAttribute: already have such an attribute");

        m_rContext.getGlobalContext().AddAttribute( _nPrefix, _rName, _rValue );
    }

	//---------------------------------------------------------------------
	void OPropertyExport::AddAttributeASCII(sal_uInt16 _nPrefix, const sal_Char* _pName, const sal_Char *pValue)
	{
		OSL_ENSURE(0 == m_rContext.getGlobalContext().GetXAttrList()->getValueByName(::rtl::OUString::createFromAscii(_pName)).getLength(),
			"OPropertyExport::AddAttributeASCII: already have such an attribute");

		m_rContext.getGlobalContext().AddAttributeASCII(_nPrefix, _pName, pValue);
	}

	//---------------------------------------------------------------------
	void OPropertyExport::AddAttribute(sal_uInt16 _nPrefix, ::xmloff::token::XMLTokenEnum _eName, const ::rtl::OUString& _rValue)
	{
		OSL_ENSURE(0 == m_rContext.getGlobalContext().GetXAttrList()->getValueByName(::xmloff::token::GetXMLToken(_eName)).getLength(),
			"OPropertyExport::AddAttribute: already have such an attribute");

		m_rContext.getGlobalContext().AddAttribute(_nPrefix, _eName, _rValue);
	}

	//---------------------------------------------------------------------
	void OPropertyExport::AddAttribute(sal_uInt16 _nPrefix, ::xmloff::token::XMLTokenEnum _eName, ::xmloff::token::XMLTokenEnum _eValue )
	{
		OSL_ENSURE(0 == m_rContext.getGlobalContext().GetXAttrList()->getValueByName(::xmloff::token::GetXMLToken(_eName)).getLength(),
			"OPropertyExport::AddAttribute: already have such an attribute");

		m_rContext.getGlobalContext().AddAttribute(_nPrefix, _eName, _eValue);
	}

	//---------------------------------------------------------------------
	void OPropertyExport::dbg_implCheckProperty(const ::rtl::OUString& _rPropertyName, const Type* _pType)
	{
		try
		{
			// the property must exist
			if (!m_xPropertyInfo->hasPropertyByName(_rPropertyName))
			{
				OSL_ENSURE(sal_False,
					::rtl::OString("OPropertyExport::dbg_implCheckProperty: no property with the name ") +=
					::rtl::OString(_rPropertyName.getStr(), _rPropertyName.getLength(), RTL_TEXTENCODING_ASCII_US) +=
					::rtl::OString("!"));
				return;
			}

			if (_pType)
			{
				// and it must have the correct type
				Property aPropertyDescription = m_xPropertyInfo->getPropertyByName(_rPropertyName);
				OSL_ENSURE(aPropertyDescription.Type.equals(*_pType), "OPropertyExport::dbg_implCheckProperty: invalid property type!");
			}
		}
		catch(Exception&)
		{
			OSL_ENSURE(sal_False, "OPropertyExport::dbg_implCheckProperty: caught an exception, could not check the property!");
		}
	}
#endif // DBG_UTIL - dbg_implCheckProperty

//.........................................................................
}	// namespace xmloff
//.........................................................................
