/**************************************************************
 *
 * 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 <com/sun/star/style/XStyleFamiliesSupplier.hpp>
#include <com/sun/star/style/NumberingType.hpp>
#include <com/sun/star/style/XStyle.hpp>
#include <com/sun/star/container/XNameContainer.hpp>
#include <com/sun/star/container/XIndexReplace.hpp>
#include <com/sun/star/awt/XBitmap.hpp>
#include <com/sun/star/awt/FontDescriptor.hpp>
#include <com/sun/star/text/HoriOrientation.hpp>
#include <com/sun/star/text/VertOrientation.hpp>
#include <com/sun/star/text/XChapterNumberingSupplier.hpp>
// --> OD 2008-01-16 #newlistlevelattrs#
#include <com/sun/star/text/PositionAndSpaceMode.hpp>
#include <com/sun/star/text/LabelFollow.hpp>
// <--
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>

#include <rtl/ustrbuf.hxx>

#include <tools/debug.hxx>

#include <xmloff/nmspmap.hxx>
#include "xmloff/xmlnmspe.hxx"
#include <xmloff/xmltoken.hxx>
#include <xmloff/xmluconv.hxx>
#include "fonthdl.hxx"
#include "xmloff/XMLTextListAutoStylePool.hxx"
#include <xmloff/xmlnume.hxx>
#include <xmloff/xmlexp.hxx>
#include <tools/fontenum.hxx>


using ::rtl::OUString;
using ::rtl::OUStringBuffer;

using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::style;
using namespace ::com::sun::star::text;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::beans;
using namespace ::xmloff::token;

static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_SYMBOL_TEXT_DISTANCE[] = "SymbolTextDistance";
static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_PARENT_NUMBERING[] = "ParentNumbering";
static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_CHAR_STYLE_NAME[] = "CharStyleName";
static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_BULLET_CHAR[] = "BulletChar";
static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_BULLET_RELSIZE[] = "BulletRelSize";
static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_BULLET_COLOR[] = "BulletColor";
static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_GRAPHIC_BITMAP[] = "GraphicBitmap";
static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_GRAPHIC_SIZE[] = "GraphicSize";
static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_VERT_ORIENT[] = "VertOrient";
static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_NUMBERINGTYPE[] = "NumberingType";
static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_HEADING_STYLE_NAME[] = "HeadingStyleName";
static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_PREFIX[] = "Prefix";
static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_SUFFIX[] = "Suffix";
static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_ADJUST[] = "Adjust";
static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_LEFT_MARGIN[] = "LeftMargin";
static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_FIRST_LINE_OFFSET[] = "FirstLineOffset";
static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_BULLET_FONT[] = "BulletFont";
static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_GRAPHICURL[] = "GraphicURL";
static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_START_WITH[] = "StartWith";
// --> OD 2008-01-15 #newlistlevelattrs#
static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_POSITION_AND_SPACE_MODE[] = "PositionAndSpaceMode";
static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_LABEL_FOLLOWED_BY[] = "LabelFollowedBy";
static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_LISTTAB_STOP_POSITION[] = "ListtabStopPosition";
static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_FIRST_LINE_INDENT[] = "FirstLineIndent";
static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_INDENT_AT[] = "IndentAt";
// <--

void SvxXMLNumRuleExport::exportLevelStyles( const uno::Reference< ::com::sun::star::container::XIndexReplace > & xNumRule,
											 sal_Bool bOutline )
{
	sal_Int32 nCount = xNumRule ->getCount();
	for( sal_Int32 i=0; i<nCount; i++ )
	{
		uno::Any aEntry( xNumRule->getByIndex( i ) );
		uno::Sequence<beans::PropertyValue> aSeq;
		if( aEntry >>= aSeq )
		{
			exportLevelStyle( i, aSeq, bOutline );
		}
	}
}

void SvxXMLNumRuleExport::exportLevelStyle( sal_Int32 nLevel,
									const uno::Sequence<beans::PropertyValue>& rProps,
									sal_Bool bOutline )
{
	sal_Int16 eType = NumberingType::CHAR_SPECIAL;

	sal_Int16 eAdjust = HoriOrientation::LEFT;
	OUString sPrefix, sSuffix;
	OUString sTextStyleName;
	sal_Bool bHasColor = sal_False;
	sal_Int32 nColor = 0;
	sal_Int32 nSpaceBefore = 0, nMinLabelWidth = 0, nMinLabelDist = 0;

	sal_Int16 nStartValue = 1, nDisplayLevels = 1, nBullRelSize = 0;

	sal_Unicode cBullet = 0xf095;
	OUString sBulletFontName, sBulletFontStyleName ;
	sal_Int16 eBulletFontFamily = FAMILY_DONTKNOW;
	sal_Int16 eBulletFontPitch = PITCH_DONTKNOW;
	rtl_TextEncoding eBulletFontEncoding = RTL_TEXTENCODING_DONTKNOW;

	OUString sImageURL;
	uno::Reference< ::com::sun::star::awt::XBitmap >  xBitmap;
	sal_Int32 nImageWidth = 0, nImageHeight = 0;
	sal_Int16 eImageVertOrient = VertOrientation::LINE_CENTER;

    // --> OD 2008-01-15 #newlistlevelattrs#
    sal_Int16 ePosAndSpaceMode = PositionAndSpaceMode::LABEL_WIDTH_AND_POSITION;
    sal_Int16 eLabelFollowedBy = LabelFollow::LISTTAB;
    sal_Int32 nListtabStopPosition( 0 );
    sal_Int32 nFirstLineIndent( 0 );
    sal_Int32 nIndentAt( 0 );
    // <--

    const sal_Int32 nCount = rProps.getLength();
	const beans::PropertyValue* pPropArray = rProps.getConstArray();
	for( sal_Int32 i=0; i<nCount; i++ )
	{
		const beans::PropertyValue& rProp = pPropArray[i];

		if( rProp.Name.equalsAsciiL( XML_UNO_NAME_NRULE_NUMBERINGTYPE, sizeof(XML_UNO_NAME_NRULE_NUMBERINGTYPE)-1 ) )
		{
			rProp.Value >>= eType;
		}
		else if( rProp.Name.equalsAsciiL( XML_UNO_NAME_NRULE_PREFIX, sizeof(XML_UNO_NAME_NRULE_PREFIX)-1 ) )
		{
			rProp.Value >>= sPrefix;
		}
		else if( rProp.Name.equalsAsciiL( XML_UNO_NAME_NRULE_SUFFIX, sizeof(XML_UNO_NAME_NRULE_SUFFIX)-1 ) )
		{
			rProp.Value >>= sSuffix;
		}
		else if( rProp.Name.equalsAsciiL( XML_UNO_NAME_NRULE_BULLET_CHAR, sizeof(XML_UNO_NAME_NRULE_BULLET_CHAR)-1 ) )
		{
			OUString sValue;
			rProp.Value >>= sValue;
			if( sValue.getLength() > 0 )
			{
				cBullet = (sal_Unicode)sValue[0];
			}
		}
		else if( rProp.Name.equalsAsciiL( XML_UNO_NAME_NRULE_BULLET_RELSIZE, sizeof(XML_UNO_NAME_NRULE_BULLET_RELSIZE)-1 ) )
		{
			rProp.Value >>= nBullRelSize;
		}
		else if( rProp.Name.equalsAsciiL( XML_UNO_NAME_NRULE_ADJUST, sizeof(XML_UNO_NAME_NRULE_ADJUST)-1 ) )
		{
			sal_Int16 nValue = 0;
			rProp.Value >>= nValue;
			eAdjust = nValue;
		}
		else if( rProp.Name.equalsAsciiL( XML_UNO_NAME_NRULE_BULLET_FONT, sizeof(XML_UNO_NAME_NRULE_BULLET_FONT)-1 ) )
		{
			awt::FontDescriptor rFDesc;
			if( rProp.Value >>= rFDesc )
			{
				sBulletFontName = rFDesc.Name;
				sBulletFontStyleName = rFDesc.StyleName;
				eBulletFontFamily = (sal_Int16)rFDesc.Family;
				eBulletFontPitch = (sal_Int16)rFDesc.Pitch;
				eBulletFontEncoding = (rtl_TextEncoding)rFDesc.CharSet;
			}
		}
		else if( rProp.Name.equalsAsciiL( XML_UNO_NAME_NRULE_GRAPHICURL, sizeof(XML_UNO_NAME_NRULE_GRAPHICURL)-1 ) )
		{
			rProp.Value >>= sImageURL;
		}
		else if( rProp.Name.equalsAsciiL( XML_UNO_NAME_NRULE_GRAPHIC_BITMAP, sizeof(XML_UNO_NAME_NRULE_GRAPHIC_BITMAP)-1 ) )
		{
			rProp.Value >>= xBitmap;
		}
		else if( rProp.Name.equalsAsciiL( XML_UNO_NAME_NRULE_BULLET_COLOR, sizeof(XML_UNO_NAME_NRULE_BULLET_COLOR)-1 ) )
		{
			rProp.Value >>= nColor;
			bHasColor = sal_True;
		}
		else  if( rProp.Name.equalsAsciiL( XML_UNO_NAME_NRULE_START_WITH, sizeof(XML_UNO_NAME_NRULE_START_WITH)-1 ) )
		{
			rProp.Value >>= nStartValue;
		}
		else  if( rProp.Name.equalsAsciiL( XML_UNO_NAME_NRULE_LEFT_MARGIN, sizeof(XML_UNO_NAME_NRULE_LEFT_MARGIN)-1 ) )
		{
			rProp.Value >>= nSpaceBefore;
		}
		else  if( rProp.Name.equalsAsciiL( XML_UNO_NAME_NRULE_FIRST_LINE_OFFSET, sizeof(XML_UNO_NAME_NRULE_FIRST_LINE_OFFSET)-1 ) )
		{
			rProp.Value >>= nMinLabelWidth;
		}
		else  if( rProp.Name.equalsAsciiL( XML_UNO_NAME_NRULE_SYMBOL_TEXT_DISTANCE, sizeof(XML_UNO_NAME_NRULE_SYMBOL_TEXT_DISTANCE)-1 ) )
		{
			rProp.Value >>= nMinLabelDist;
		}
		else if( rProp.Name.equalsAsciiL( XML_UNO_NAME_NRULE_PARENT_NUMBERING, sizeof(XML_UNO_NAME_NRULE_PARENT_NUMBERING)-1 ) )
		{
			rProp.Value >>= nDisplayLevels;
			if( nDisplayLevels > nLevel+1 )
				nDisplayLevels = static_cast<sal_Int16>( nLevel )+1;
		}
		else if( rProp.Name.equalsAsciiL( XML_UNO_NAME_NRULE_CHAR_STYLE_NAME, sizeof(XML_UNO_NAME_NRULE_CHAR_STYLE_NAME)-1 ) )
		{
			rProp.Value >>= sTextStyleName;
		}
		else if( rProp.Name.equalsAsciiL( XML_UNO_NAME_NRULE_GRAPHIC_SIZE, sizeof(XML_UNO_NAME_NRULE_GRAPHIC_SIZE)-1 ) )
		{
			awt::Size aSize;
			if( rProp.Value >>= aSize )
			{
				nImageWidth = aSize.Width;
				nImageHeight = aSize.Height;
			}
		}
		else if( rProp.Name.equalsAsciiL( XML_UNO_NAME_NRULE_VERT_ORIENT, sizeof(XML_UNO_NAME_NRULE_VERT_ORIENT)-1 ) )
		{
			sal_Int16 nValue = 0;
			rProp.Value >>= nValue;
			eImageVertOrient = nValue;
		}
        // --> OD 2008-01-16 #newlistlevelattrs#
        else if( rProp.Name.equalsAsciiL( XML_UNO_NAME_NRULE_POSITION_AND_SPACE_MODE,
                                          sizeof(XML_UNO_NAME_NRULE_POSITION_AND_SPACE_MODE)-1 ) )
        {
            sal_Int16 nValue = 0;
            rProp.Value >>= nValue;
            ePosAndSpaceMode = nValue;
        }
        else if( rProp.Name.equalsAsciiL( XML_UNO_NAME_NRULE_LABEL_FOLLOWED_BY,
                                          sizeof(XML_UNO_NAME_NRULE_LABEL_FOLLOWED_BY)-1 ) )
        {
            sal_Int16 nValue = 0;
            rProp.Value >>= nValue;
            eLabelFollowedBy = nValue;
        }
        else if( rProp.Name.equalsAsciiL( XML_UNO_NAME_NRULE_LISTTAB_STOP_POSITION,
                                          sizeof(XML_UNO_NAME_NRULE_LISTTAB_STOP_POSITION)-1 ) )
        {
            rProp.Value >>= nListtabStopPosition;
        }
        else if( rProp.Name.equalsAsciiL( XML_UNO_NAME_NRULE_FIRST_LINE_INDENT,
                                          sizeof(XML_UNO_NAME_NRULE_FIRST_LINE_INDENT)-1 ) )
        {
            rProp.Value >>= nFirstLineIndent;
        }
        else if( rProp.Name.equalsAsciiL( XML_UNO_NAME_NRULE_INDENT_AT,
                                          sizeof(XML_UNO_NAME_NRULE_INDENT_AT)-1 ) )
        {
            rProp.Value >>= nIndentAt;
        }
        // <--
	}

	if( bOutline && (NumberingType::CHAR_SPECIAL == eType ||
					 NumberingType::BITMAP == eType) )
	{
		DBG_ASSERT( !bOutline,
		   "SvxXMLNumRuleExport::exportLevelStyle: invalid style for outline" );
		return;
	}

	GetExport().CheckAttrList();

	// text:level
	OUStringBuffer sTmp;
	sTmp.append( nLevel + 1 );
	GetExport().AddAttribute( XML_NAMESPACE_TEXT, XML_LEVEL, sTmp.makeStringAndClear() );
    // #i110694#: no style-name on list-level-style-image
    // #i116149#: neither prefix/suffix
    if (NumberingType::BITMAP != eType)
    {
        if (sTextStyleName.getLength() > 0)
        {
            GetExport().AddAttribute( XML_NAMESPACE_TEXT, XML_STYLE_NAME,
                    GetExport().EncodeStyleName( sTextStyleName ) );
        }
        if (sPrefix.getLength() > 0)
        {
            GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_NUM_PREFIX,
                    sPrefix );
        }
        if (sSuffix.getLength() > 0)
        {
            GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_NUM_SUFFIX,
                    sSuffix );
        }
    }

	enum XMLTokenEnum eElem = XML_LIST_LEVEL_STYLE_NUMBER;
	if( NumberingType::CHAR_SPECIAL == eType )
	{
		// <text:list-level-style-bullet>
		eElem = XML_LIST_LEVEL_STYLE_BULLET;

		if( cBullet )
		{
			if( cBullet < ' ' )
			{
				cBullet = 0xF000 + 149;
			}
			// text:bullet-char="..."
			sTmp.append( cBullet );
			GetExport().AddAttribute( XML_NAMESPACE_TEXT, XML_BULLET_CHAR,
						  sTmp.makeStringAndClear() );
		}

	}
	else if( NumberingType::BITMAP == eType )
	{
		// <text:list-level-style-image>

		eElem = XML_LIST_LEVEL_STYLE_IMAGE;


		if( sImageURL.getLength() )
		{
			OUString sURL( GetExport().AddEmbeddedGraphicObject( sImageURL ) );
			if( sURL.getLength() )
			{
				GetExport().AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, sURL );

				GetExport().AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
				GetExport().AddAttribute( XML_NAMESPACE_XLINK, XML_SHOW, XML_EMBED );
				GetExport().AddAttribute( XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONLOAD );
			}
		}
		else
		{
			DBG_ASSERT( !xBitmap.is(),
						"embedded images are not supported by now" );
		}
	}
	else
	{
		// <text:list-level-style-number> or <text:outline-level-style>
		if( bOutline )
			eElem = XML_OUTLINE_LEVEL_STYLE;
		else
			eElem = XML_LIST_LEVEL_STYLE_NUMBER;

		GetExport().GetMM100UnitConverter().convertNumFormat( sTmp, eType );
		GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_NUM_FORMAT,
						  	   	  sTmp.makeStringAndClear() );
		GetExport().GetMM100UnitConverter().convertNumLetterSync( sTmp, eType );
		if( sTmp.getLength() )
			GetExport().AddAttribute( XML_NAMESPACE_STYLE,
									  XML_NUM_LETTER_SYNC,
						  	   		  sTmp.makeStringAndClear() );

		if( nStartValue != 1 )
		{
			sTmp.append( (sal_Int32)nStartValue );
			GetExport().AddAttribute( XML_NAMESPACE_TEXT, XML_START_VALUE,
						  sTmp.makeStringAndClear() );
		}
		if( nDisplayLevels > 1 && NumberingType::NUMBER_NONE != eType )
		{
			sTmp.append( (sal_Int32)nDisplayLevels );
			GetExport().AddAttribute( XML_NAMESPACE_TEXT, XML_DISPLAY_LEVELS,
						  sTmp.makeStringAndClear() );
		}
	}

	{
		SvXMLElementExport aElem( GetExport(), XML_NAMESPACE_TEXT, eElem,
								  sal_True, sal_True );

        // --> OD 2008-01-16 #newlistlevelattrs#
        OUStringBuffer sBuffer;
        if ( ePosAndSpaceMode == PositionAndSpaceMode::LABEL_WIDTH_AND_POSITION )
        {
            // --> OD 2008-06-05 #i89178#
            // optimization of XML stream size:
            // suppress export of property list-level-position-and-space-mode,
            // if its value is "label-width-and-position" - its the default value
//            GetExport().AddAttribute( XML_NAMESPACE_TEXT,
//                                      XML_LIST_LEVEL_POSITION_AND_SPACE_MODE,
//                                      XML_LABEL_WIDTH_AND_POSITION );
            // <--

            nSpaceBefore += nMinLabelWidth;
            nMinLabelWidth = -nMinLabelWidth;
            if( nSpaceBefore != 0 )
            {
                GetExport().GetMM100UnitConverter().convertMeasure( sBuffer, nSpaceBefore );
                GetExport().AddAttribute( XML_NAMESPACE_TEXT, XML_SPACE_BEFORE,
                              sBuffer.makeStringAndClear() );
            }
            if( nMinLabelWidth != 0 )
            {
                GetExport().GetMM100UnitConverter().convertMeasure( sBuffer, nMinLabelWidth );
                GetExport().AddAttribute( XML_NAMESPACE_TEXT, XML_MIN_LABEL_WIDTH,
                              sBuffer.makeStringAndClear() );
            }
            if( nMinLabelDist > 0 )
            {
                GetExport().GetMM100UnitConverter().convertMeasure( sBuffer, nMinLabelDist );
                GetExport().AddAttribute( XML_NAMESPACE_TEXT, XML_MIN_LABEL_DISTANCE,
                              sBuffer.makeStringAndClear() );
            }
        }
        // --> OD 2008-06-06 #i89178#
        // check, if properties for position-and-space-mode LABEL_ALIGNMENT
        // are allowed to be exported.
        else if ( ePosAndSpaceMode == PositionAndSpaceMode::LABEL_ALIGNMENT &&
                  mbExportPositionAndSpaceModeLabelAlignment )
        // <--
        {
            GetExport().AddAttribute( XML_NAMESPACE_TEXT,
                                      XML_LIST_LEVEL_POSITION_AND_SPACE_MODE,
                                      XML_LABEL_ALIGNMENT );
        }
        // <--
		if( HoriOrientation::LEFT != eAdjust )
		{
            enum XMLTokenEnum eValue = XML_TOKEN_INVALID;
			switch( eAdjust )
			{
			case HoriOrientation::RIGHT:	eValue = XML_END;	break;
			case HoriOrientation::CENTER:	eValue = XML_CENTER;	break;
			}
			if( eValue != XML_TOKEN_INVALID )
				GetExport().AddAttribute( XML_NAMESPACE_FO, XML_TEXT_ALIGN, eValue );
		}

		if( NumberingType::BITMAP == eType )
		{
            enum XMLTokenEnum eValue = XML_TOKEN_INVALID;
			switch( eImageVertOrient )
			{
			case VertOrientation::BOTTOM:	// yes, its OK: BOTTOM means that the baseline
									// hits the frame at its topmost position
			case VertOrientation::LINE_TOP:
			case VertOrientation::CHAR_TOP:
				eValue = XML_TOP;
				break;
			case VertOrientation::CENTER:
			case VertOrientation::LINE_CENTER:
			case VertOrientation::CHAR_CENTER:
				eValue = XML_MIDDLE;
				break;
			case VertOrientation::TOP:		// yes, its OK: TOP means that the baseline
									// hits the frame at its bottommost position
			case VertOrientation::LINE_BOTTOM:
			case VertOrientation::CHAR_BOTTOM:
				eValue = XML_BOTTOM;
				break;
			}
			if( eValue != XML_TOKEN_INVALID )
				GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_VERTICAL_POS, eValue );

			eValue = XML_TOKEN_INVALID;
			switch( eImageVertOrient )
			{
			case VertOrientation::TOP:
			case VertOrientation::CENTER:
			case VertOrientation::BOTTOM:
				eValue = XML_BASELINE;
				break;
			case VertOrientation::LINE_TOP:
			case VertOrientation::LINE_CENTER:
			case VertOrientation::LINE_BOTTOM:
				eValue = XML_LINE;
				break;
			case VertOrientation::CHAR_TOP:
			case VertOrientation::CHAR_CENTER:
			case VertOrientation::CHAR_BOTTOM:
				eValue = XML_CHAR;
				break;
			}
			if( eValue != XML_TOKEN_INVALID )
				GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_VERTICAL_REL, eValue );

			if( nImageWidth > 0 )
			{
				GetExport().GetMM100UnitConverter().convertMeasure( sBuffer, nImageWidth );
				GetExport().AddAttribute( XML_NAMESPACE_FO, XML_WIDTH,
							  sBuffer.makeStringAndClear() );
			}

			if( nImageHeight > 0 )
			{
				GetExport().GetMM100UnitConverter().convertMeasure( sBuffer, nImageHeight );
				GetExport().AddAttribute( XML_NAMESPACE_FO, XML_HEIGHT,
							  sBuffer.makeStringAndClear() );
			}
		}

        // --> OD 2008-01-16 #newlistlevelattrs#
//        if( GetExport().GetAttrList().getLength() > 0 )
		{
			SvXMLElementExport aElement( GetExport(), XML_NAMESPACE_STYLE,
									  XML_LIST_LEVEL_PROPERTIES, sal_True, sal_True );

            // --> OD 2008-06-06 #i89178#
            // check, if properties for position-and-space-mode LABEL_ALIGNMENT
            // are allowed to be exported.
            if ( ePosAndSpaceMode == PositionAndSpaceMode::LABEL_ALIGNMENT &&
                 mbExportPositionAndSpaceModeLabelAlignment )
            // <--
            {
                enum XMLTokenEnum eValue = XML_LISTTAB;
                if ( eLabelFollowedBy == LabelFollow::SPACE )
                {
                    eValue = XML_SPACE;
                }
                else if ( eLabelFollowedBy == LabelFollow::NOTHING )
                {
                    eValue = XML_NOTHING;
                }
                GetExport().AddAttribute( XML_NAMESPACE_TEXT,
                                          XML_LABEL_FOLLOWED_BY, eValue );

                if ( eLabelFollowedBy == LabelFollow::LISTTAB &&
                     nListtabStopPosition > 0 )
                {
                    GetExport().GetMM100UnitConverter().convertMeasure( sBuffer, nListtabStopPosition );
                    GetExport().AddAttribute( XML_NAMESPACE_TEXT,
                                              XML_LIST_TAB_STOP_POSITION,
                                              sBuffer.makeStringAndClear() );
                }

                if ( nFirstLineIndent != 0 )
                {
                    GetExport().GetMM100UnitConverter().convertMeasure( sBuffer, nFirstLineIndent );
                    GetExport().AddAttribute( XML_NAMESPACE_FO,
                                              XML_TEXT_INDENT,
                                              sBuffer.makeStringAndClear() );
                }

                if ( nIndentAt != 0 )
                {
                    GetExport().GetMM100UnitConverter().convertMeasure( sBuffer, nIndentAt );
                    GetExport().AddAttribute( XML_NAMESPACE_FO,
                                              XML_MARGIN_LEFT,
                                              sBuffer.makeStringAndClear() );
                }

                SvXMLElementExport aLabelAlignmentElement( GetExport(), XML_NAMESPACE_STYLE,
                                             XML_LIST_LEVEL_LABEL_ALIGNMENT,
                                             sal_True, sal_True );
            }
        }
        // <--

		if( NumberingType::CHAR_SPECIAL == eType )
		{
			if( sBulletFontName.getLength() )
			{
				OUString sStyleName =
					GetExport().GetFontAutoStylePool()->Find(
						sBulletFontName, sBulletFontStyleName,
						eBulletFontFamily, eBulletFontPitch,
						eBulletFontEncoding );

				if( sStyleName.getLength() )
				{
						GetExport().AddAttribute( XML_NAMESPACE_STYLE,
												  XML_FONT_NAME,
												  sStyleName );
				}
				else
				{
					Any aAny;
					OUString sTemp;

					const SvXMLUnitConverter& rUnitConv =
						GetExport().GetMM100UnitConverter();
					XMLFontFamilyNamePropHdl aFamilyNameHdl;
					aAny <<= sBulletFontName;
					if( aFamilyNameHdl.exportXML( sTemp, aAny, rUnitConv ) )
						GetExport().AddAttribute( XML_NAMESPACE_FO,
												  XML_FONT_FAMILY, sTemp );

					if( sBulletFontStyleName.getLength() )
						GetExport().AddAttribute( XML_NAMESPACE_STYLE,
												  XML_FONT_STYLE_NAME,
												  sBulletFontStyleName );

					XMLFontFamilyPropHdl aFamilyHdl;
					aAny <<= (sal_Int16)eBulletFontFamily;
					if( aFamilyHdl.exportXML( sTemp, aAny, rUnitConv  ) )
						GetExport().AddAttribute( XML_NAMESPACE_STYLE,
												  XML_FONT_FAMILY_GENERIC,
												  sTemp );

					XMLFontPitchPropHdl aPitchHdl;
					aAny <<= (sal_Int16)eBulletFontPitch;
					if( aPitchHdl.exportXML( sTemp, aAny, rUnitConv  ) )
						GetExport().AddAttribute( XML_NAMESPACE_STYLE,
												  XML_FONT_PITCH, sTemp );

					XMLFontEncodingPropHdl aEncHdl;
					aAny <<= (sal_Int16)eBulletFontEncoding;
					if( aEncHdl.exportXML( sTemp, aAny, rUnitConv  ) )
						GetExport().AddAttribute( XML_NAMESPACE_STYLE,
												  XML_FONT_CHARSET, sTemp );
				}
			}
		}
		if( NumberingType::BITMAP != eType )
		{
			// fo:color = "#..."
			if( bHasColor )
			{
				const Color aColor( nColor );
				if( aColor.GetColor() == 0xffffffff )
				{
					GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_USE_WINDOW_FONT_COLOR, XML_TRUE );
				}
				else
				{
					SvXMLUnitConverter::convertColor( sBuffer, aColor );
					GetExport().AddAttribute( XML_NAMESPACE_FO, XML_COLOR,
								  sBuffer.makeStringAndClear() );
				}
			}
			// fo:height="...%"
			if( nBullRelSize )
			{
				GetExport().GetMM100UnitConverter().convertPercent( sTmp, nBullRelSize );
				GetExport().AddAttribute( XML_NAMESPACE_FO, XML_FONT_SIZE,
							  sTmp.makeStringAndClear() );
			}
		}
		if( GetExport().GetAttrList().getLength() > 0 )
		{
			SvXMLElementExport aElement( GetExport(), XML_NAMESPACE_STYLE,
									  XML_TEXT_PROPERTIES, sal_True, sal_True );
		}
		if( NumberingType::BITMAP == eType && sImageURL.getLength() )
		{
			// optional office:binary-data
			GetExport().AddEmbeddedGraphicObjectAsBase64( sImageURL );
		}
	}
}


uno::Reference< ::com::sun::star::container::XIndexReplace >  SvxXMLNumRuleExport::GetUNONumRule() const
{
	return uno::Reference< ::com::sun::star::container::XIndexReplace > ();
}

void SvxXMLNumRuleExport::AddListStyleAttributes()
{
}


SvxXMLNumRuleExport::SvxXMLNumRuleExport( SvXMLExport& rExp ) :
	rExport( rExp ),
	sNumberingRules( RTL_CONSTASCII_USTRINGPARAM( "NumberingRules" ) ),
	sIsPhysical( RTL_CONSTASCII_USTRINGPARAM( "IsPhysical" ) ),
    sIsContinuousNumbering( RTL_CONSTASCII_USTRINGPARAM( "IsContinuousNumbering" ) ),
    // --> OD 2008-06-06 #i89178#
    mbExportPositionAndSpaceModeLabelAlignment( true )
    // <--
{
    switch ( GetExport().getDefaultVersion() )
    {
        case SvtSaveOptions::ODFVER_010:
        case SvtSaveOptions::ODFVER_011:
        {
            mbExportPositionAndSpaceModeLabelAlignment = false;
        }
        break;
        default: // ODFVER_UNKNOWN or ODFVER_012
        {
            mbExportPositionAndSpaceModeLabelAlignment = true;
        }
    }
}

SvxXMLNumRuleExport::~SvxXMLNumRuleExport()
{
}

// --> OD 2008-06-17 #i90780#
// refactoring: removing unused methods
//void SvxXMLNumRuleExport::Export( const OUString& rName,
//                                sal_Bool bContNumbering )
//{
//  GetExport().CheckAttrList();

//  // style:name="..."
//  if( rName.getLength() )
//  {
//      sal_Bool bEncoded = sal_False;
//      GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_NAME,
//                        GetExport().EncodeStyleName( rName, &bEncoded ) );
//      if( bEncoded )
//          GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_DISPLAY_NAME,
//                                   rName);
//  }

//  // text:consecutive-numbering="..."
//  if( bContNumbering )
//      GetExport().AddAttribute( XML_NAMESPACE_TEXT, XML_CONSECUTIVE_NUMBERING,
//                         XML_TRUE );

//  // other application specific attributes
//  AddListStyleAttributes();

//  OUString sElem = GetExport().GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TEXT,
//                                 GetXMLToken(XML_LIST_STYLE) );
//  GetExport().IgnorableWhitespace();
//  GetExport().StartElement( XML_NAMESPACE_TEXT, XML_LIST_STYLE, sal_False );

//  uno::Reference< ::com::sun::star::container::XIndexReplace >  xNumRule = GetUNONumRule();
//  if( xNumRule.is() )
//      exportLevelStyles( xNumRule );

//  GetExport().EndElement( XML_NAMESPACE_TEXT, XML_LIST_STYLE, sal_True );
//}

//void SvxXMLNumRuleExport::ExportOutline()
//{
//  GetExport().IgnorableWhitespace( );
//  GetExport().StartElement( XML_NAMESPACE_TEXT, XML_OUTLINE_STYLE, sal_False );

//  uno::Reference< ::com::sun::star::container::XIndexReplace >  xNumRule = GetUNONumRule();
//  if( xNumRule.is() )
//      exportLevelStyles( xNumRule, sal_True );

//  GetExport().EndElement( XML_NAMESPACE_TEXT, XML_OUTLINE_STYLE, sal_True );
//}
// <--

void SvxXMLNumRuleExport::exportNumberingRule(
		const OUString& rName,
		const Reference< XIndexReplace >& rNumRule )
{
	Reference< XPropertySet > xPropSet( rNumRule, UNO_QUERY );
	Reference< XPropertySetInfo > xPropSetInfo;
	if( xPropSet.is() )
   		xPropSetInfo = xPropSet->getPropertySetInfo();

	GetExport().CheckAttrList();

	// style:name="..."
	if( rName.getLength() )
	{
		sal_Bool bEncoded = sal_False;
		GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_NAME,
						  GetExport().EncodeStyleName( rName, &bEncoded ) );
		if( bEncoded )
			GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_DISPLAY_NAME,
								 rName);
	}

	// text:consecutive-numbering="..."
	sal_Bool bContNumbering = sal_False;
	if( xPropSetInfo.is() &&
		xPropSetInfo->hasPropertyByName( sIsContinuousNumbering ) )
	{
		Any aAny( xPropSet->getPropertyValue( sIsContinuousNumbering ) );
		bContNumbering = *(sal_Bool *)aAny.getValue();
	}
	if( bContNumbering )
		GetExport().AddAttribute( XML_NAMESPACE_TEXT,
                                  XML_CONSECUTIVE_NUMBERING, XML_TRUE );

	// other application specific attributes
	AddListStyleAttributes();

	{
		SvXMLElementExport aElem( GetExport(), XML_NAMESPACE_TEXT, XML_LIST_STYLE ,
								  sal_True, sal_True );
		exportLevelStyles( rNumRule );
	}
}

sal_Bool SvxXMLNumRuleExport::exportStyle( const Reference< XStyle >& rStyle )
{
	Reference< XPropertySet > xPropSet( rStyle, UNO_QUERY );
	Reference< XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();

	Any aAny;

	// Don't export styles that aren't existing really. This may be the
	// case for StarOffice Writer's pool styles.
	if( xPropSetInfo->hasPropertyByName( sIsPhysical ) )
	{
		aAny = xPropSet->getPropertyValue( sIsPhysical );
		if( !*(sal_Bool *)aAny.getValue() )
			return sal_False;
	}

	aAny = xPropSet->getPropertyValue( sNumberingRules );
	Reference<XIndexReplace> xNumRule;
	aAny >>= xNumRule;

	OUString sName = rStyle->getName();

	exportNumberingRule( sName, xNumRule );

	return sal_True;
}

void SvxXMLNumRuleExport::exportOutline()
{
	Reference< XChapterNumberingSupplier > xCNSupplier( GetExport().GetModel(),
														UNO_QUERY );
	DBG_ASSERT( xCNSupplier.is(), "no chapter numbering supplier" );

	if( xCNSupplier.is() )
	{
		Reference< XIndexReplace > xNumRule( xCNSupplier->getChapterNumberingRules() );
		DBG_ASSERT( xNumRule.is(), "no chapter numbering rules" );

		if( xNumRule.is() )
		{
            // --> OD 2008-06-17 #i90780#
            // Outline style has property style:name since ODF 1.2
            // Thus, export this property and adjust fix for issue #i69627#
            OUString sOutlineStyleName;
            {
                Reference<XPropertySet> xNumRulePropSet(
                    xCNSupplier->getChapterNumberingRules(), UNO_QUERY );
                if (xNumRulePropSet.is())
                {
                    const OUString sName( RTL_CONSTASCII_USTRINGPARAM("Name") );
                    xNumRulePropSet->getPropertyValue( sName ) >>= sOutlineStyleName;
                }
            }
            const SvtSaveOptions::ODFDefaultVersion nODFVersion =
                                                GetExport().getDefaultVersion();
            if ( ( nODFVersion == SvtSaveOptions::ODFVER_010 ||
                   nODFVersion == SvtSaveOptions::ODFVER_011 ) &&
                 GetExport().writeOutlineStyleAsNormalListStyle() )
            {
                exportNumberingRule( sOutlineStyleName, xNumRule );
            }
            else
            {
                if ( nODFVersion != SvtSaveOptions::ODFVER_010 &&
                     nODFVersion != SvtSaveOptions::ODFVER_011 )
                {
                    // style:name="..."
                    GetExport().CheckAttrList();
                    if ( sOutlineStyleName.getLength() > 0 )
                     {
                        sal_Bool bEncoded = sal_False;
                        GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_NAME,
                                        GetExport().EncodeStyleName( sOutlineStyleName,
                                                                     &bEncoded ) );
                        if( bEncoded )
                            GetExport().AddAttribute( XML_NAMESPACE_STYLE,
                                                      XML_DISPLAY_NAME,
                                                      sOutlineStyleName );
                    }
                }
                SvXMLElementExport aElem( GetExport(), XML_NAMESPACE_TEXT,
                                          XML_OUTLINE_STYLE, sal_True, sal_True );
                exportLevelStyles( xNumRule, sal_True );
            }
		}
	}
}

void SvxXMLNumRuleExport::exportStyles( sal_Bool bUsed,
									 	XMLTextListAutoStylePool *pPool,
									 	sal_Bool bExportChapterNumbering )
{
	if( bExportChapterNumbering )
		exportOutline();

	Reference< XStyleFamiliesSupplier > xFamiliesSupp( GetExport().GetModel(), UNO_QUERY );
	DBG_ASSERT( xFamiliesSupp.is(), "No XStyleFamiliesSupplier from XModel for export!" );
	if( xFamiliesSupp.is() )
	{
		Reference< XNameAccess > xFamilies( xFamiliesSupp->getStyleFamilies() );
		DBG_ASSERT( xFamiliesSupp.is(), "getStyleFamilies() from XModel failed for export!" );

		if( xFamilies.is() )
		{
			const OUString aNumberStyleName( RTL_CONSTASCII_USTRINGPARAM( "NumberingStyles" ));

			Reference< XIndexAccess > xStyles;
			if( xFamilies->hasByName( aNumberStyleName ) )
			{
				xFamilies->getByName( aNumberStyleName ) >>= xStyles;

				DBG_ASSERT( xStyles.is(), "Style not found for export!" );

				if( xStyles.is() )
				{
					const sal_Int32 nStyles = xStyles->getCount();

					for( sal_Int32 i=0; i < nStyles; i++ )
					{
						Reference< XStyle > xStyle;
						xStyles->getByIndex( i ) >>= xStyle;

						if( !bUsed || xStyle->isInUse() )
						{
							exportStyle( xStyle );
							if( pPool )
								pPool->RegisterName( xStyle->getName() );
						}
					}
				}
			}
		}
	}
}

sal_Bool SvxXMLNumRuleExport::GetOutlineStyles( XMLStringVector& rStyleNames,
   const ::com::sun::star::uno::Reference<
   				::com::sun::star::frame::XModel > & rModel	)
{
	Reference< XChapterNumberingSupplier > xCNSupplier( rModel,
														UNO_QUERY );
	sal_Int32 nLevels = 0;
	Reference< XIndexReplace > xNumRule;
	if( xCNSupplier.is() )
	{
		xNumRule = xCNSupplier->getChapterNumberingRules();
		if( xNumRule.is() )
			nLevels = xNumRule->getCount();
	}

	rStyleNames.resize( nLevels );
	for( sal_Int32 i=0; i<nLevels; i++ )
	{
		uno::Any aEntry( xNumRule->getByIndex( i ) );
		uno::Sequence<beans::PropertyValue> aSeq;
		if( aEntry >>= aSeq )
		{
            const sal_Int32 nCount = aSeq.getLength();
			const beans::PropertyValue* pPropArray = aSeq.getConstArray();
			for( sal_Int32 j=0; j<nCount; j++ )
			{
				const beans::PropertyValue& rProp = pPropArray[j];

				if( rProp.Name.equalsAsciiL(
							XML_UNO_NAME_NRULE_HEADING_STYLE_NAME,
							sizeof(XML_UNO_NAME_NRULE_HEADING_STYLE_NAME)-1 ) )
				{
					rProp.Value >>= rStyleNames[i];
					break;
				}
			}
		}
	}

	return nLevels != 0;
}
