/**************************************************************
 * 
 * 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 attribuite 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
//.........................................................................


