/**************************************************************
 *
 * 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 "xmloff/dllapi.h"

#include "sal/config.h"
#include <osl/diagnose.h>

#include <rtl/ustring.hxx>
#include <rtl/ustrbuf.hxx>

#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
#include <com/sun/star/text/XText.hpp>
#include <com/sun/star/container/XNamed.hpp>
#include <com/sun/star/container/XEnumerationAccess.hpp>
#include <com/sun/star/table/XCellRange.hpp>
#include <com/sun/star/table/XColumnRowRange.hpp>
#include <com/sun/star/table/CellContentType.hpp>
#include <com/sun/star/table/XMergeableCell.hpp>
#include <com/sun/star/style/XStyle.hpp>
#include <com/sun/star/beans/XPropertySetInfo.hpp>

#include "xmloff/table/XMLTableExport.hxx"
#include "xmloff/xmlnmspe.hxx"
#include <xmloff/xmlprmap.hxx>
#include <xmloff/xmlexppr.hxx>
#include <xmloff/xmlexp.hxx>
#include "table.hxx"

using ::rtl::OUString;
using namespace ::xmloff::token;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::table;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::text;
using namespace ::com::sun::star::style;
using namespace ::xmloff::token;

// --------------------------------------------------------------------

#define _MAP(name,prefix,token,type,context)  { name, sizeof(name)-1, prefix, token, type, context, SvtSaveOptions::ODFVER_010 }
#define CMAP(name,prefix,token,type,context) _MAP(name,prefix,token,type|XML_TYPE_PROP_TABLE_COLUMN,context)
#define RMAP(name,prefix,token,type,context) _MAP(name,prefix,token,type|XML_TYPE_PROP_TABLE_ROW,context)
#define MAP_END { 0L, 0, 0, XML_EMPTY, 0, 0, SvtSaveOptions::ODFVER_010 }

// --------------------------------------------------------------------

const XMLPropertyMapEntry* getColumnPropertiesMap()
{
	static const XMLPropertyMapEntry aXMLColumnProperties[] =
	{
		CMAP( "Width",			XML_NAMESPACE_STYLE,	XML_COLUMN_WIDTH,				XML_TYPE_MEASURE,	0 ),
		CMAP( "OptimalWidth",	XML_NAMESPACE_STYLE,	XML_USE_OPTIMAL_COLUMN_WIDTH,	XML_TYPE_BOOL, 0 ),
		MAP_END
	};

	return &aXMLColumnProperties[0];
}

// --------------------------------------------------------------------

const XMLPropertyMapEntry* getRowPropertiesMap()
{
	static const XMLPropertyMapEntry aXMLRowProperties[] =
	{
		RMAP( "Height",			XML_NAMESPACE_STYLE, XML_ROW_HEIGHT,					XML_TYPE_MEASURE,	0 ),
		RMAP( "OptimalHeight",	XML_NAMESPACE_STYLE, XML_MIN_ROW_HEIGHT,				XML_TYPE_MEASURE,	0 ),
		RMAP( "OptimalWidth",	XML_NAMESPACE_STYLE, XML_USE_OPTIMAL_ROW_HEIGHT,		XML_TYPE_BOOL, 0 ),
		MAP_END
	};

	return &aXMLRowProperties[0];
}

// --------------------------------------------------------------------

class StringStatisticHelper : public std::map< OUString, sal_Int32 >
{
public:
	void add( const OUString& rStyleName );
	void clear() { std::map< OUString, sal_Int32 >::clear(); }

	sal_Int32 getModeString( /* out */ OUString& rModeString );
};

// --------------------------------------------------------------------

void StringStatisticHelper::add( const OUString& rStyleName )
{
	std::map< OUString, sal_Int32 >::iterator iter( find( rStyleName ) );
	if( iter == end() )
	{
		(*this)[rStyleName] = 1;
	}
	else
	{
		(*iter).second += 1;
	}
}

// --------------------------------------------------------------------

sal_Int32 StringStatisticHelper::getModeString( OUString& rStyleName )
{
	sal_Int32 nMax = 0;
	for( std::map< OUString, sal_Int32 >::iterator iter( begin() ); iter != end(); iter++ )
	{
		if( (*iter).second > nMax )
		{
			rStyleName = (*iter).first;
			nMax = (*iter).second;
		}
	}

	return nMax;
}

// --------------------------------------------------------------------
// class XMLTableExport
// --------------------------------------------------------------------

XMLTableExport::XMLTableExport(SvXMLExport& rExp, const rtl::Reference< SvXMLExportPropertyMapper  >& xExportPropertyMapper, const rtl::Reference< XMLPropertyHandlerFactory >& xFactoryRef )
: mrExport( rExp )
, mbExportTables( false )
{
	Reference< XMultiServiceFactory > xFac( rExp.GetModel(), UNO_QUERY );
	if( xFac.is() ) try
	{
		Sequence< OUString > sSNS( xFac->getAvailableServiceNames() );
		sal_Int32 n = sSNS.getLength();
		const OUString* pSNS( sSNS.getConstArray() );
		while( --n > 0 )
		{
			if( (*pSNS++).equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.drawing.TableShape") ) )
			{
				mbExportTables = true;
				break;
			}
		}
	}
    catch( Exception& e )
    {
        (void)e;
    }

	mxCellExportPropertySetMapper = xExportPropertyMapper;
	mxCellExportPropertySetMapper->ChainExportMapper(XMLTextParagraphExport::CreateParaExtPropMapper(rExp));

	mxRowExportPropertySetMapper = new SvXMLExportPropertyMapper( new XMLPropertySetMapper( getRowPropertiesMap(), xFactoryRef.get() ) );
	mxColumnExportPropertySetMapper = new SvXMLExportPropertyMapper( new XMLPropertySetMapper( getColumnPropertiesMap(), xFactoryRef.get() ) );

	mrExport.GetAutoStylePool()->AddFamily(XML_STYLE_FAMILY_TABLE_COLUMN,
		OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_COLUMN_STYLES_NAME)),
		mxColumnExportPropertySetMapper.get(),
		OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_COLUMN_STYLES_PREFIX)));
	mrExport.GetAutoStylePool()->AddFamily(XML_STYLE_FAMILY_TABLE_ROW,
		OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_ROW_STYLES_NAME)),
		mxRowExportPropertySetMapper.get(),
		OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_ROW_STYLES_PREFIX)));
//	mrExport.GetAutoStylePool()->AddFamily(XML_STYLE_FAMILY_TABLE_TABLE
//		OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_TABLE_STYLES_NAME)),
//		xTableStylesExportPropertySetMapper,
//		OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_TABLE_STYLES_PREFIX)));
	mrExport.GetAutoStylePool()->AddFamily(XML_STYLE_FAMILY_TABLE_CELL,
		OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_CELL_STYLES_NAME)),
		mxCellExportPropertySetMapper.get(),
		OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_CELL_STYLES_PREFIX)));
}

// --------------------------------------------------------------------

XMLTableExport::~XMLTableExport ()
{
}

// --------------------------------------------------------------------

static bool has_states( const std::vector< XMLPropertyState >& xPropStates )
{
	if( !xPropStates.empty() )
	{
		std::vector< XMLPropertyState >::const_iterator aIter( xPropStates.begin() );
		std::vector< XMLPropertyState >::const_iterator aEnd( xPropStates.end() );
		while( aIter != aEnd )
		{
			if( aIter->mnIndex != -1 )
				return true;
			aIter++;
		}
	}
	return false;
}

// --------------------------------------------------------------------

 void XMLTableExport::collectTableAutoStyles(const Reference < XColumnRowRange >& xColumnRowRange)
 {
     if( !mbExportTables )
         return;

	boost::shared_ptr< XMLTableInfo > pTableInfo( new XMLTableInfo() );
	maTableInfoMap[xColumnRowRange] = pTableInfo;

	try
	{
		Reference< XIndexAccess > xIndexAccessCols( xColumnRowRange->getColumns(), UNO_QUERY_THROW );
		const sal_Int32 nColumnCount = xIndexAccessCols->getCount();
 		for( sal_Int32 nColumn = 0; nColumn < nColumnCount; ++nColumn ) try
		{
 			Reference< XPropertySet > xPropSet( xIndexAccessCols->getByIndex(nColumn) , UNO_QUERY_THROW );
			std::vector< XMLPropertyState > xPropStates( mxColumnExportPropertySetMapper->Filter( xPropSet ) );

			if( has_states( xPropStates ) )
			{
				const OUString sStyleName( mrExport.GetAutoStylePool()->Add(XML_STYLE_FAMILY_TABLE_COLUMN, xPropStates) );
				Reference< XInterface > xKey( xPropSet, UNO_QUERY );
				pTableInfo->maColumnStyleMap[xKey] = sStyleName;
			}
		}
		catch( Exception& )
		{
			DBG_ERROR("xmloff::XMLTableExport::collectTableAutoStyles(), exception during column style collection!");
		}

		Reference< XIndexAccess > xIndexAccessRows( xColumnRowRange->getRows(), UNO_QUERY_THROW );
		const sal_Int32 nRowCount = xIndexAccessRows->getCount();
		pTableInfo->maDefaultRowCellStyles.resize(nRowCount);

		StringStatisticHelper aStringStatistic;

 		for( sal_Int32 nRow = 0; nRow < nRowCount; ++nRow ) try
		{
 			Reference< XPropertySet > xPropSet( xIndexAccessRows->getByIndex(nRow) , UNO_QUERY_THROW );
			std::vector< XMLPropertyState > xRowPropStates( mxRowExportPropertySetMapper->Filter( xPropSet ) );

			if( has_states( xRowPropStates ) )
			{
				const OUString sStyleName( mrExport.GetAutoStylePool()->Add(XML_STYLE_FAMILY_TABLE_ROW, xRowPropStates) );
				Reference< XInterface > xKey( xPropSet, UNO_QUERY );
				pTableInfo->maRowStyleMap[xKey] = sStyleName;
			}

			// get the current row
			Reference< XCellRange > xCellRange( xPropSet, UNO_QUERY_THROW );
			for ( sal_Int32 nColumn = 0; nColumn < nColumnCount; ++nColumn )
			{
				// get current cell, remarks row index is 0, because we get the range for each row separate
				Reference< XPropertySet > xCellSet( xCellRange->getCellByPosition(nColumn, 0), UNO_QUERY_THROW );

				// get style
				OUString sParentStyleName;
				Reference< XPropertySetInfo > xPropertySetInfo( xCellSet->getPropertySetInfo() );
				if( xPropertySetInfo.is() && xPropertySetInfo->hasPropertyByName( OUString(RTL_CONSTASCII_USTRINGPARAM("Style"))) )
				{
					Reference< XStyle > xStyle( xCellSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("Style"))), UNO_QUERY );
					if( xStyle.is() )
						sParentStyleName = xStyle->getName();
				}

				// create auto style, if needed
				OUString sStyleName;
				std::vector< XMLPropertyState > xCellPropStates( mxCellExportPropertySetMapper->Filter( xCellSet ) );
				if( has_states( xCellPropStates ) )
					sStyleName = mrExport.GetAutoStylePool()->Add(XML_STYLE_FAMILY_TABLE_CELL, xCellPropStates);
				else
					sStyleName = sParentStyleName;

				if( sStyleName.getLength() )
				{
					Reference< XInterface > xKey( xCellSet, UNO_QUERY );
					pTableInfo->maCellStyleMap[xKey] = sStyleName;
				}

				// create auto style for text
				Reference< XText > xText(xCellSet, UNO_QUERY);
				if(xText.is() && xText->getString().getLength())
					GetExport().GetTextParagraphExport()->collectTextAutoStyles( xText );

				aStringStatistic.add( sStyleName );
			}

			OUString sDefaultCellStyle;
			if( aStringStatistic.getModeString( sDefaultCellStyle ) > 1 )
				pTableInfo->maDefaultRowCellStyles[nRow] = sDefaultCellStyle;

			aStringStatistic.clear();
		}
		catch( Exception& )
		{
			DBG_ERROR("xmloff::XMLTableExport::collectTableAutoStyles(), exception during column style collection!");
		}
	}
	catch( Exception& )
	{
		DBG_ERROR("xmloff::XMLTableExport::collectTableAutoStyles(), exception caught!");
	}
 }

 // --------------------------------------------------------------------

 void XMLTableExport::exportTable( const Reference < XColumnRowRange >& xColumnRowRange )
 {
     if( !mbExportTables )
         return;

 	try
	{
		boost::shared_ptr< XMLTableInfo > pTableInfo( maTableInfoMap[xColumnRowRange] );

		// get row and column count
		Reference< XIndexAccess > xIndexAccess( xColumnRowRange->getRows(), UNO_QUERY_THROW );
		Reference< XIndexAccess > xIndexAccessCols( xColumnRowRange->getColumns(), UNO_QUERY_THROW );

		const sal_Int32 rowCount = xIndexAccess->getCount();
		const sal_Int32 columnCount = xIndexAccessCols->getCount();

		SvXMLElementExport tableElement( mrExport, XML_NAMESPACE_TABLE, XML_TABLE, sal_True, sal_True );

		// export table columns
		ExportTableColumns( xIndexAccessCols, pTableInfo );

		// start iterating rows and columns
		for ( sal_Int32 rowIndex = 0; rowIndex < rowCount; rowIndex++ )
		{
			// get the current row
			Reference< XCellRange > xCellRange( xIndexAccess->getByIndex(rowIndex), UNO_QUERY_THROW );

			OUString sDefaultCellStyle;

			// table:style-name
			if( pTableInfo.get() )
			{
				Reference< XInterface > xKey( xCellRange, UNO_QUERY );
				const OUString sStyleName( pTableInfo->maRowStyleMap[xKey] );
				if( sStyleName.getLength() )
					mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_STYLE_NAME, sStyleName );

				sDefaultCellStyle = pTableInfo->maDefaultRowCellStyles[rowIndex];
				if( sDefaultCellStyle.getLength() )
					mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DEFAULT_CELL_STYLE_NAME, sDefaultCellStyle );
			}

			// write row element
			SvXMLElementExport tableRowElement( mrExport, XML_NAMESPACE_TABLE, XML_TABLE_ROW, sal_True, sal_True );

			for ( sal_Int32 columnIndex = 0; columnIndex < columnCount; columnIndex++ )
			{
				// get current cell, remarks row index is 0, because we get the range for each row separate
				Reference< XCell > xCell( xCellRange->getCellByPosition(columnIndex, 0), UNO_QUERY_THROW );

				// use XMergeableCell interface from offapi
				Reference< XMergeableCell > xMergeableCell( xCell, UNO_QUERY_THROW );

				// export cell
				ExportCell( xCell, pTableInfo, sDefaultCellStyle );
			}
		}
 	}
 	catch( Exception )
	{
 		DBG_ERROR( "XMLTableExport::exportTable(), exception caught!" );
 	}
 }

// --------------------------------------------------------------------
// Export the table columns
// --------------------------------------------------------------------

 void XMLTableExport::ExportTableColumns( const Reference < XIndexAccess >& xtableColumnsIndexAccess, const boost::shared_ptr< XMLTableInfo >& pTableInfo )
 {
	const sal_Int32 nColumnCount = xtableColumnsIndexAccess->getCount();
 	for( sal_Int32 nColumn = 0; nColumn < nColumnCount; ++nColumn )
	{
 		Reference< XPropertySet > xColumnProperties( xtableColumnsIndexAccess->getByIndex(nColumn) , UNO_QUERY );
 		if ( xColumnProperties.is() )
		{
			// table:style-name
			if( pTableInfo.get() )
			{
				Reference< XInterface > xKey( xColumnProperties, UNO_QUERY );
				const OUString sStyleName( pTableInfo->maColumnStyleMap[xKey] );
				if( sStyleName.getLength() )
					mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_STYLE_NAME, sStyleName );
			}

 			// TODO: All columns first have to be checked if some ones
 			// have identical properties. If yes, attr table:number-columns-repeated
 			// has to be written.
 			SvXMLElementExport tableColumnElement( mrExport, XML_NAMESPACE_TABLE, XML_TABLE_COLUMN, sal_True, sal_True );
 		}
 	}
 }

// --------------------------------------------------------------------
// ODF export for a table cell.
// --------------------------------------------------------------------

 void XMLTableExport::ExportCell( const Reference < XCell >& xCell, const boost::shared_ptr< XMLTableInfo >& pTableInfo, const OUString& rDefaultCellStyle )
 {
	bool bIsMerged = false;
	sal_Int32 nRowSpan = 0;
	sal_Int32 nColSpan = 0;

 	try
	{
		if( pTableInfo.get() )
		{
			// table:style-name
			Reference< XInterface > xKey( xCell, UNO_QUERY );
			const OUString sStyleName( pTableInfo->maCellStyleMap[xKey] );
			if( sStyleName.getLength() && (sStyleName != rDefaultCellStyle) )
				mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_STYLE_NAME, sStyleName );
		}

		Reference< XMergeableCell > xMerge( xCell, UNO_QUERY );
		if( xMerge.is() )
		{
			bIsMerged = xMerge->isMerged();
			nRowSpan = xMerge->getRowSpan();
			nColSpan = xMerge->getColumnSpan();
		}
		DBG_ASSERT( (nRowSpan >= 1) && (nColSpan >= 1), "xmloff::XMLTableExport::ExportCell(), illegal row or col span < 1?" );
	}
	catch ( Exception )
	{
		DBG_ERROR( "exception while exporting a table cell" );
	}

	// table:number-columns-repeated
	// todo

	// table:number-columns-spanned
	if( nColSpan > 1 )
		mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_SPANNED, OUString::valueOf( nColSpan ) );

	// table:number-rows-spanned
	if( nRowSpan > 1 )
		mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_ROWS_SPANNED, OUString::valueOf( nRowSpan ) );

 	// <table:table-cell> or <table:covered-table-cell>
	SvXMLElementExport tableCellElement( mrExport, XML_NAMESPACE_TABLE, bIsMerged ? XML_COVERED_TABLE_CELL : XML_TABLE_CELL, sal_True, sal_True );

	// export cells text content
	ImpExportText( xCell );
 }

// --------------------------------------------------------------------
// ODF export of the text contents of a table cell.
// Remarks: Up to now we only export text contents!
// TODO: Check against nested tables ....
// --------------------------------------------------------------------

 void XMLTableExport::ImpExportText( const Reference< XCell >& xCell )
 {
	Reference< XText > xText( xCell, UNO_QUERY );
	if( xText.is() && xText->getString().getLength())
		mrExport.GetTextParagraphExport()->exportText( xText );
 }

// --------------------------------------------------------------------

void XMLTableExport::exportTableStyles()
{
     if( !mbExportTables )
         return;

	XMLStyleExport aStEx(mrExport, OUString(), mrExport.GetAutoStylePool().get());

	// write graphic family styles
	aStEx.exportStyleFamily("cell", OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_CELL_STYLES_NAME)), mxCellExportPropertySetMapper.get(), sal_True, XML_STYLE_FAMILY_TABLE_CELL);

	exportTableTemplates();
}

// --------------------------------------------------------------------
// Export the collected automatic styles
// --------------------------------------------------------------------

void XMLTableExport::exportAutoStyles()
{
     if( !mbExportTables )
         return;

	mrExport.GetAutoStylePool()->exportXML( XML_STYLE_FAMILY_TABLE_COLUMN, mrExport.GetDocHandler(), mrExport.GetMM100UnitConverter(), mrExport.GetNamespaceMap() );
	mrExport.GetAutoStylePool()->exportXML( XML_STYLE_FAMILY_TABLE_ROW, mrExport.GetDocHandler(), mrExport.GetMM100UnitConverter(), mrExport.GetNamespaceMap() );
	mrExport.GetAutoStylePool()->exportXML( XML_STYLE_FAMILY_TABLE_CELL, mrExport.GetDocHandler(), mrExport.GetMM100UnitConverter(), mrExport.GetNamespaceMap() );
}

// --------------------------------------------------------------------

const TableStyleElement* getTableStyleMap()
{
	static struct TableStyleElement gTableStyleElements[] =
	{
		{ XML_FIRST_ROW, OUString( RTL_CONSTASCII_USTRINGPARAM( "first-row" ) ) },
		{ XML_LAST_ROW, OUString( RTL_CONSTASCII_USTRINGPARAM( "last-row" ) ) },
		{ XML_FIRST_COLUMN, OUString( RTL_CONSTASCII_USTRINGPARAM( "first-column" ) ) },
		{ XML_LAST_COLUMN, OUString( RTL_CONSTASCII_USTRINGPARAM( "last-column" ) ) },
		{ XML_EVEN_ROWS, OUString( RTL_CONSTASCII_USTRINGPARAM( "even-rows" ) ) },
		{ XML_ODD_ROWS, OUString( RTL_CONSTASCII_USTRINGPARAM( "odd-rows" ) ) },
		{ XML_EVEN_COLUMNS, OUString( RTL_CONSTASCII_USTRINGPARAM( "even-columns" ) ) },
		{ XML_ODD_COLUMNS, OUString( RTL_CONSTASCII_USTRINGPARAM( "odd-columns" ) ) },
		{ XML_BODY, OUString( RTL_CONSTASCII_USTRINGPARAM( "body" ) ) },
		{ XML_TOKEN_END, OUString() }
	};

	return &gTableStyleElements[0];
}

// --------------------------------------------------------------------

void XMLTableExport::exportTableTemplates()
{
     if( !mbExportTables )
         return;

	try
	{
		Reference< XStyleFamiliesSupplier > xFamiliesSupp( mrExport.GetModel(), UNO_QUERY_THROW );
		Reference< XNameAccess > xFamilies( xFamiliesSupp->getStyleFamilies() );
		const OUString sFamilyName( RTL_CONSTASCII_USTRINGPARAM("table" ) );
		Reference< XIndexAccess > xTableFamily( xFamilies->getByName( sFamilyName ), UNO_QUERY_THROW );

		for( sal_Int32 nIndex = 0; nIndex < xTableFamily->getCount(); nIndex++ ) try
		{
			Reference< XStyle > xTableStyle( xTableFamily->getByIndex( nIndex ), UNO_QUERY_THROW );
			if( !xTableStyle->isInUse() )
				continue;

			Reference< XNameAccess > xStyleNames( xTableStyle, UNO_QUERY_THROW );

			mrExport.AddAttribute(XML_NAMESPACE_TEXT, XML_STYLE_NAME, GetExport().EncodeStyleName( xTableStyle->getName() ) );
 			SvXMLElementExport tableTemplate( mrExport, XML_NAMESPACE_TABLE, XML_TABLE_TEMPLATE, sal_True, sal_True );

			const TableStyleElement* pElements = getTableStyleMap();
			while( pElements->meElement != XML_TOKEN_END )
			{
				try
				{
					Reference< XStyle > xStyle( xStyleNames->getByName( pElements->msStyleName ), UNO_QUERY );
					if( xStyle.is() )
					{
						mrExport.AddAttribute(XML_NAMESPACE_TEXT, XML_STYLE_NAME, GetExport().EncodeStyleName( xStyle->getName() ) );
			 			SvXMLElementExport element( mrExport, XML_NAMESPACE_TABLE, pElements->meElement, sal_True, sal_True );
					}
				}
				catch( Exception& )
				{
					DBG_ERROR("xmloff::XMLTableExport::exportTableTemplates(), exception caught!");
				}

				pElements++;
			}
		}
		catch( Exception& )
		{
			DBG_ERROR("xmloff::XMLTableExport::exportTableDesigns(), exception caught while exporting a table design!");
		}
	}
	catch( Exception& )
	{
		DBG_ERROR("xmloff::XMLTableExport::exportTableDesigns(), exception caught!");
	}
}

// --------------------------------------------------------------------
