/**************************************************************
 *
 * 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/table/XTableRows.hpp>
#include <com/sun/star/table/XMergeableCell.hpp>
#include <com/sun/star/table/XMergeableCellRange.hpp>
#include <com/sun/star/table/XTable.hpp>
#include <com/sun/star/text/XText.hpp>
#include <com/sun/star/container/XNameContainer.hpp>
#include <com/sun/star/lang/XSingleServiceFactory.hpp>

#include "xmloff/table/XMLTableImport.hxx"
#include "xmloff/xmltkmap.hxx"
#include "xmloff/maptype.hxx"
#include "xmloff/xmlprmap.hxx"
#include "xmloff/txtimp.hxx"
#include "xmloff/xmlimp.hxx"
#include "xmloff/nmspmap.hxx"
#include "xmloff/xmlstyle.hxx"
#include "xmloff/prstylei.hxx"
#include "xmloff/xmlimp.hxx"

#include "xmloff/xmlnmspe.hxx"
#include "table.hxx"

#include <boost/shared_ptr.hpp>

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

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

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

struct ColumnInfo
{
	OUString msStyleName;
	sal_Bool mbVisibility;
	OUString msDefaultCellStyleName;
};

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

class XMLProxyContext : public SvXMLImportContext
{
public:
	XMLProxyContext( SvXMLImport& rImport, const SvXMLImportContextRef& xParent, sal_uInt16 nPrfx, const OUString& rLName );

	virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, const OUString& rLocalName, const Reference< XAttributeList >& xAttrList );

private:
	SvXMLImportContextRef mxParent;
};

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

struct MergeInfo
{
	sal_Int32 mnStartColumn;
	sal_Int32 mnStartRow;
	sal_Int32 mnEndColumn;
	sal_Int32 mnEndRow;

	MergeInfo( sal_Int32 nStartColumn, sal_Int32 nStartRow, sal_Int32 nColumnSpan, sal_Int32 nRowSpan )
		: mnStartColumn( nStartColumn ), mnStartRow( nStartRow ), mnEndColumn( nStartColumn + nColumnSpan - 1 ), mnEndRow( nStartRow + nRowSpan - 1 ) {};
};

typedef std::vector< boost::shared_ptr< MergeInfo > > MergeInfoVector;

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

class XMLTableImportContext : public SvXMLImportContext
{
public:
	XMLTableImportContext( const rtl::Reference< XMLTableImport >& xThis, sal_uInt16 nPrfx, const OUString& rLName, Reference< XColumnRowRange >& xColumnRowRange );
	virtual ~XMLTableImportContext();

	virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, const OUString& rLocalName, const Reference< XAttributeList >& xAttrList );

	virtual void StartElement( const Reference< XAttributeList >& xAttrList );

	virtual void EndElement();

	void InitColumns();

	SvXMLImportContext * ImportColumn( sal_uInt16 nPrefix, const OUString& rLocalName, const Reference< XAttributeList >& xAttrList );
	SvXMLImportContext * ImportRow( sal_uInt16 nPrefix, const OUString& rLocalName, const Reference< XAttributeList >& xAttrList );
	SvXMLImportContext * ImportCell( sal_uInt16 nPrefix, const OUString& rLocalName, const Reference< XAttributeList >& xAttrList );

	OUString GetDefaultCellStyleName() const;

	rtl::Reference< XMLTableImport > mxTableImporter;
	::com::sun::star::uno::Reference< ::com::sun::star::table::XTable > mxTable;
	Reference< XTableColumns > mxColumns;
	Reference< XTableRows > mxRows;

	std::vector< boost::shared_ptr< ColumnInfo > > maColumnInfos;
	sal_Int32 mnCurrentRow;
	sal_Int32 mnCurrentColumn;

	// default cell style name for the current row
	OUString msDefaultCellStyleName;

	MergeInfoVector maMergeInfos;
};

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

class XMLCellImportContext : public SvXMLImportContext
{
public:
	XMLCellImportContext( SvXMLImport& rImport,
						  const Reference< XMergeableCell >& xCell,
						  const OUString& sDefaultCellStyleName,
						  sal_uInt16 nPrfx, const OUString& rLName,
						  const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList );

	virtual ~XMLCellImportContext();

	virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, const OUString& rLocalName, const Reference< XAttributeList >& xAttrList );

	virtual void EndElement();

	sal_Int32 getColumnSpan() const { return mnColSpan; }
	sal_Int32 getRowSpan() const { return mnRowSpan; }
	sal_Int32 getRepeated() const { return mnRepeated; }

	Reference< XMergeableCell >	mxCell;
	Reference< XTextCursor >	mxCursor;
	Reference< XTextCursor >	mxOldCursor;
    bool                        mbListContextPushed;

	sal_Int32 mnColSpan, mnRowSpan, mnRepeated;
};

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

class XMLTableTemplateContext : public SvXMLStyleContext
{
public:
	XMLTableTemplateContext( SvXMLImport& rImport, sal_uInt16 nPrfx, const OUString& rLName, const Reference< XAttributeList >& xAttrList );

	virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, const OUString& rLocalName, const Reference< XAttributeList >& xAttrList );

	virtual void StartElement( const Reference< XAttributeList >& xAttrList );

	virtual void EndElement();

private:
	XMLTableTemplate maTableTemplate;
	OUString msTemplateStyleName;
};

// --------------------------------------------------------------------
// class XMLProxyContext
// --------------------------------------------------------------------

XMLProxyContext::XMLProxyContext( SvXMLImport& rImport, const SvXMLImportContextRef& xParent, sal_uInt16 nPrfx, const OUString& rLName )
: SvXMLImportContext( rImport, nPrfx, rLName )
, mxParent( xParent )
{
}

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

SvXMLImportContext * XMLProxyContext::CreateChildContext( sal_uInt16 nPrefix, const OUString& rLocalName, const Reference< XAttributeList >& xAttrList )
{
	if( mxParent.Is() )
		return mxParent->CreateChildContext( nPrefix, rLocalName, xAttrList );
	else
		return SvXMLImportContext::CreateChildContext( nPrefix, rLocalName, xAttrList );
}

// --------------------------------------------------------------------
// class XMLTableImport
// --------------------------------------------------------------------

XMLTableImport::XMLTableImport( SvXMLImport& rImport, const rtl::Reference< XMLPropertySetMapper >& xCellPropertySetMapper, const rtl::Reference< XMLPropertyHandlerFactory >& xFactoryRef )
: mrImport( rImport )
{
	mxCellImportPropertySetMapper = new SvXMLImportPropertyMapper( xCellPropertySetMapper.get(), rImport );
	mxCellImportPropertySetMapper->ChainImportMapper(XMLTextImportHelper::CreateParaExtPropMapper(rImport));


	UniReference < XMLPropertySetMapper > xRowMapper( new XMLPropertySetMapper( getRowPropertiesMap(), xFactoryRef.get() ) );
	mxRowImportPropertySetMapper = new SvXMLImportPropertyMapper( xRowMapper, rImport );

	UniReference < XMLPropertySetMapper > xColMapper( new XMLPropertySetMapper( getColumnPropertiesMap(), xFactoryRef.get() ) );
	mxColumnImportPropertySetMapper = new SvXMLImportPropertyMapper( xColMapper, rImport );
}

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

XMLTableImport::~XMLTableImport()
{
}

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

SvXMLImportContext* XMLTableImport::CreateTableContext( sal_uInt16 nPrfx, const OUString& rLName, Reference< XColumnRowRange >& xColumnRowRange )
{
	rtl::Reference< XMLTableImport > xThis( this );
	return new XMLTableImportContext( xThis, nPrfx, rLName, xColumnRowRange );
}

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

SvXMLStyleContext* XMLTableImport::CreateTableTemplateContext( sal_uInt16 nPrfx, const OUString& rLName, const Reference< XAttributeList >& xAttrList )
{
	return new XMLTableTemplateContext( mrImport, nPrfx, rLName, xAttrList );
}

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

void XMLTableImport::addTableTemplate( const rtl::OUString& rsStyleName, XMLTableTemplate& xTableTemplate )
{
	boost::shared_ptr< XMLTableTemplate > xPtr( new XMLTableTemplate );
	xPtr->swap( xTableTemplate );
	maTableTemplates[rsStyleName] = xPtr;
}

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

void XMLTableImport::finishStyles()
{
	if( !maTableTemplates.empty() ) try
	{
		Reference< XStyleFamiliesSupplier > xFamiliesSupp( mrImport.GetModel(), UNO_QUERY_THROW );
		Reference< XNameAccess > xFamilies( xFamiliesSupp->getStyleFamilies() );
		const OUString sFamilyName( RTL_CONSTASCII_USTRINGPARAM("table" ) );
		const OUString sCellFamilyName( RTL_CONSTASCII_USTRINGPARAM("cell") );

		Reference< XNameContainer > xTableFamily( xFamilies->getByName( sFamilyName ), UNO_QUERY_THROW );
		Reference< XNameAccess > xCellFamily( xFamilies->getByName( sCellFamilyName ), UNO_QUERY_THROW );

		Reference< XSingleServiceFactory > xFactory( xTableFamily, UNO_QUERY_THROW );

		for( XMLTableTemplateMap::iterator aTemplateIter( maTableTemplates.begin() ); aTemplateIter != maTableTemplates.end(); aTemplateIter++ ) try
		{
			const OUString sTemplateName( (*aTemplateIter).first );
			Reference< XNameReplace > xTemplate( xFactory->createInstance(), UNO_QUERY_THROW );

			boost::shared_ptr< XMLTableTemplate > xT( (*aTemplateIter).second );

			for( XMLTableTemplate::iterator aStyleIter( xT->begin() ); aStyleIter != xT->end(); aStyleIter++ ) try
			{
				const OUString sPropName( (*aStyleIter).first );
				const OUString sStyleName( (*aStyleIter).second );
				xTemplate->replaceByName( sPropName, xCellFamily->getByName( sStyleName ) );
			}
			catch( Exception& )
			{
				DBG_ERROR("xmloff::XMLTableImport::finishStyles(), exception caught!");
			}

			if( xTemplate.is() )
			{
				if( xTableFamily->hasByName( sTemplateName ) )
					xTableFamily->replaceByName( sTemplateName, Any( xTemplate ) );
				else
					xTableFamily->insertByName( sTemplateName, Any( xTemplate ) );
			}

		}
		catch( Exception& )
		{
			DBG_ERROR("xmloff::XMLTableImport::finishStyles(), exception caught!");
		}
	}
	catch( Exception& )
	{
		DBG_ERROR("xmloff::XMLTableImport::finishStyles(), exception caught!");
	}
}

// --------------------------------------------------------------------
// class XMLTableImport
// --------------------------------------------------------------------


XMLTableImportContext::XMLTableImportContext( const rtl::Reference< XMLTableImport >& xImporter, sal_uInt16 nPrfx, const OUString& rLName,	Reference< XColumnRowRange >& xColumnRowRange )
: SvXMLImportContext( xImporter->mrImport, nPrfx, rLName )
, mxTableImporter( xImporter )
, mxTable( xColumnRowRange, UNO_QUERY )
, mxColumns( xColumnRowRange->getColumns() )
, mxRows( xColumnRowRange->getRows() )
, mnCurrentRow( -1 )
, mnCurrentColumn( -1 )
{
}

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

XMLTableImportContext::~XMLTableImportContext()
{
}

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

SvXMLImportContext * XMLTableImportContext::ImportColumn( sal_uInt16 nPrefix, const OUString& rLocalName, const Reference< XAttributeList >& xAttrList )
{
	if( mxColumns.is() && (mnCurrentRow == -1) ) try
	{
		boost::shared_ptr< ColumnInfo > xInfo ( new ColumnInfo );

		sal_Int32 nRepeated = 1;

		// read attributes for the table-column
		sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
		for(sal_Int16 i=0; i < nAttrCount; i++)
		{
			const OUString sAttrName( xAttrList->getNameByIndex( i ) );
            const OUString sValue( xAttrList->getValueByIndex( i ) );
			OUString aLocalName;

			sal_uInt16 nPrefix2 = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
			if( XML_NAMESPACE_TABLE == nPrefix2 )
			{
				if( IsXMLToken( aLocalName, XML_NUMBER_COLUMNS_REPEATED ) )
				{
					nRepeated = sValue.toInt32();
				}
				else if( IsXMLToken( aLocalName, XML_STYLE_NAME ) )
				{
					xInfo->msStyleName = sValue;
				}
				else if( IsXMLToken( aLocalName, XML_DEFAULT_CELL_STYLE_NAME ) )
				{
					xInfo->msDefaultCellStyleName = sValue;
				}
				else if( IsXMLToken( aLocalName, XML_VISIBILITY ) )
				{
					xInfo->mbVisibility = IsXMLToken( sValue, XML_VISIBLE );
				}
			}
            else if ( (XML_NAMESPACE_XML == nPrefix2) &&
                 IsXMLToken(aLocalName, XML_ID)   )
            {
                (void) sValue;
//FIXME: TODO
            }
        }

		if( nRepeated <= 1 )
		{
			maColumnInfos.push_back( xInfo );
		}
		else
		{
			maColumnInfos.insert( maColumnInfos.end(), nRepeated, xInfo );
		}
	}
	catch( Exception& )
	{
		DBG_ERROR("xmloff::XMLTableImportContext::ImportTableColumn(), exception caught!");
	}

	return SvXMLImportContext::CreateChildContext( nPrefix, rLocalName, xAttrList);
}

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

void XMLTableImportContext::InitColumns()
{
	if( mxColumns.is() ) try
	{
		const sal_Int32 nCount1 = mxColumns->getCount();
		const sal_Int32 nCount2 = sal::static_int_cast< sal_Int32 >( maColumnInfos.size() );
		if( nCount1 < nCount2 )
			mxColumns->insertByIndex( nCount1, nCount2 - nCount1 );

		SvXMLStylesContext * pAutoStyles = GetImport().GetShapeImport()->GetAutoStylesContext();

		for( sal_Int32 nCol = 0; nCol < nCount2; nCol++ )
		{
			boost::shared_ptr< ColumnInfo > xInfo( maColumnInfos[nCol] );

			if( pAutoStyles && xInfo->msStyleName.getLength() )
			{
				const XMLPropStyleContext* pStyle =
					dynamic_cast< const XMLPropStyleContext* >(
						pAutoStyles->FindStyleChildContext(XML_STYLE_FAMILY_TABLE_COLUMN, xInfo->msStyleName) );

				if( pStyle )
				{
					Reference< XPropertySet > xColProps( mxColumns->getByIndex(nCol), UNO_QUERY_THROW );
					const_cast< XMLPropStyleContext* >( pStyle )->FillPropertySet( xColProps );
				}
			}

		}
	}
	catch( Exception& )
	{
		DBG_ERROR("xmloff::XMLTableImportContext::ImportTableColumn(), exception caught!");
	}
}

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

SvXMLImportContext * XMLTableImportContext::ImportRow( sal_uInt16 nPrefix, const OUString& rLocalName, const Reference< XAttributeList >& xAttrList )
{
	if( mxRows.is() )
	{
		mnCurrentRow++;
		if( mnCurrentRow == 0 )
			InitColumns();		// first init columns

		mnCurrentColumn = -1;

		const sal_Int32 nRowCount = mxRows->getCount();
		if( ( nRowCount - 1) < mnCurrentRow )
		{
			const sal_Int32 nCount = mnCurrentRow - nRowCount + 1;
			mxRows->insertByIndex( nRowCount, nCount );
		}

		Reference< XPropertySet > xRowSet( mxRows->getByIndex(mnCurrentRow), UNO_QUERY );

		sal_Int32 nRepeated = 1;
		OUString sStyleName;
		sal_Bool bVisibility = sal_True;

		// read attributes for the table-row
		sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
		for(sal_Int16 i=0; i < nAttrCount; i++)
		{
			const OUString sAttrName( xAttrList->getNameByIndex( i ) );
            const OUString sValue( xAttrList->getValueByIndex( i ) );
			OUString aLocalName;

			sal_uInt16 nPrefix2 = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
			if( nPrefix2 == XML_NAMESPACE_TABLE )
			{
				if( IsXMLToken( aLocalName, XML_NUMBER_ROWS_REPEATED ) )
				{
					nRepeated = sValue.toInt32();
				}
				else if( IsXMLToken( aLocalName, XML_STYLE_NAME ) )
				{
					sStyleName = sValue;
				}
				else if( IsXMLToken( aLocalName, XML_DEFAULT_CELL_STYLE_NAME ) )
				{
					msDefaultCellStyleName = sValue;
				}
				else if( IsXMLToken( aLocalName, XML_VISIBILITY ) )
				{
					bVisibility = IsXMLToken( sValue, XML_VISIBLE );
				}
			}
            else if ( (XML_NAMESPACE_XML == nPrefix2) &&
                 IsXMLToken(aLocalName, XML_ID)   )
            {
                (void) sValue;
//FIXME: TODO
            }
		}

		if( sStyleName.getLength() )
		{
			SvXMLStylesContext * pAutoStyles = GetImport().GetShapeImport()->GetAutoStylesContext();
			if( pAutoStyles )
			{
				const XMLPropStyleContext* pStyle =
					dynamic_cast< const XMLPropStyleContext* >(
						pAutoStyles->FindStyleChildContext(XML_STYLE_FAMILY_TABLE_ROW, sStyleName) );

				if( pStyle )
				{
					const_cast< XMLPropStyleContext* >( pStyle )->FillPropertySet( xRowSet );
				}
			}
		}
	}

	SvXMLImportContextRef xThis( this );
	return new XMLProxyContext( GetImport(), xThis, nPrefix, rLocalName );
}

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

SvXMLImportContext * XMLTableImportContext::ImportCell( sal_uInt16 nPrefix, const OUString& rLocalName, const Reference< XAttributeList >& xAttrList )
{
	mnCurrentColumn++;
	if( mxColumns.is() ) try
	{
		if( mxColumns->getCount() <= mnCurrentColumn )
			mxColumns->insertByIndex( mxColumns->getCount(), mnCurrentColumn - mxColumns->getCount() + 1 );

		Reference< XMergeableCell > xCell( mxTable->getCellByPosition( mnCurrentColumn, mnCurrentRow ), UNO_QUERY_THROW );
		XMLCellImportContext* pCellContext = new XMLCellImportContext( GetImport(), xCell, GetDefaultCellStyleName(), nPrefix, rLocalName, xAttrList );

		const sal_Int32 nColumnSpan = pCellContext->getColumnSpan();
		const sal_Int32 nRowSpan = pCellContext->getRowSpan();
		if( (nColumnSpan > 1) || (nRowSpan > 1) )
			maMergeInfos.push_back( boost::shared_ptr< MergeInfo >( new MergeInfo( mnCurrentColumn, mnCurrentRow, nColumnSpan, nRowSpan ) ) );

		const sal_Int32 nRepeated = pCellContext->getRepeated();
		if( nRepeated > 1 )
		{
			DBG_ERROR("xmloff::XMLTableImportContext::ImportCell(), import of repeated Cells not implemented (TODO)");
			mnCurrentColumn  += nRepeated - 1;
		}

		return pCellContext;
	}
	catch( Exception& )
	{
		DBG_ERROR("xmloff::XMLTableImportContext::ImportCell(), exception caught!");
	}

	return SvXMLImportContext::CreateChildContext( nPrefix, rLocalName, xAttrList);
}

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

SvXMLImportContext *XMLTableImportContext::CreateChildContext( sal_uInt16 nPrefix, const OUString& rLocalName, const Reference< XAttributeList >& xAttrList )
{
	if( nPrefix == XML_NAMESPACE_TABLE )
	{
		if( IsXMLToken( rLocalName, XML_TABLE_COLUMN ) )
			return ImportColumn( nPrefix, rLocalName, xAttrList );
		else if( IsXMLToken( rLocalName, XML_TABLE_ROW ) )
			return ImportRow( nPrefix, rLocalName, xAttrList );
		else if( IsXMLToken( rLocalName, XML_TABLE_CELL ) || IsXMLToken( rLocalName, XML_COVERED_TABLE_CELL ) )
			return ImportCell( nPrefix, rLocalName, xAttrList );
		else if( IsXMLToken( rLocalName, XML_TABLE_COLUMNS ) || IsXMLToken( rLocalName, XML_TABLE_ROWS ) )
		{
			SvXMLImportContextRef xThis( this );
			return new XMLProxyContext( GetImport(), xThis, nPrefix, rLocalName );
		}
	}

	return SvXMLImportContext::CreateChildContext( nPrefix, rLocalName, xAttrList);
}

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

void XMLTableImportContext::StartElement( const Reference< XAttributeList >& /*xAttrList*/ )
{
}

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

void XMLTableImportContext::EndElement()
{
	if( !maMergeInfos.empty() )
	{
		MergeInfoVector::iterator aIter( maMergeInfos.begin() );
		while( aIter != maMergeInfos.end() )
		{
			boost::shared_ptr< MergeInfo > xInfo( (*aIter++) );

			if( xInfo.get() ) try
			{
				Reference< XCellRange > xRange( mxTable->getCellRangeByPosition( xInfo->mnStartColumn, xInfo->mnStartRow, xInfo->mnEndColumn, xInfo->mnEndRow ) );
				Reference< XMergeableCellRange > xCursor( mxTable->createCursorByRange( xRange ), UNO_QUERY_THROW );
				xCursor->merge();
			}
			catch( Exception& )
			{
				DBG_ERROR("XMLTableImportContext::EndElement(), exception caught while merging cells!");
			}
		}
	}
}

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

OUString XMLTableImportContext::GetDefaultCellStyleName() const
{
	OUString sStyleName( msDefaultCellStyleName );

	// if there is still no style name, try default style name from column
	if( (sStyleName.getLength() == 0) && (mnCurrentColumn < sal::static_int_cast<sal_Int32>(maColumnInfos.size())) )
		sStyleName = maColumnInfos[mnCurrentColumn]->msDefaultCellStyleName;

	return sStyleName;
}

// --------------------------------------------------------------------
// XMLCellImportContext
// --------------------------------------------------------------------

XMLCellImportContext::XMLCellImportContext( SvXMLImport& rImport, const Reference< XMergeableCell >& xCell, const OUString& sDefaultCellStyleName, sal_uInt16 nPrfx, const OUString& rLName, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList )
: SvXMLImportContext( rImport, nPrfx, rLName )
, mxCell( xCell )
, mbListContextPushed( false )
, mnColSpan( 1 )
, mnRowSpan( 1 )
, mnRepeated( 1 )
{
	OUString sStyleName;

	// read attributes for the table-cell
	sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
	for(sal_Int16 i=0; i < nAttrCount; i++)
	{
        const OUString sAttrName( xAttrList->getNameByIndex( i ) );
        const OUString sValue( xAttrList->getValueByIndex( i ) );
        OUString aLocalName;

        sal_uInt16 nPrefix2 = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
        if( XML_NAMESPACE_TABLE == nPrefix2 )
		{
			if( IsXMLToken( aLocalName, XML_NUMBER_COLUMNS_REPEATED ) )
			{
				mnRepeated = sValue.toInt32();
			}
			else if( IsXMLToken( aLocalName, XML_NUMBER_COLUMNS_SPANNED ) )
			{
				mnColSpan = sValue.toInt32();
			}
			else if( IsXMLToken( aLocalName, XML_NUMBER_ROWS_SPANNED ) )
			{
				mnRowSpan = sValue.toInt32();
			}
			else if( IsXMLToken( aLocalName, XML_STYLE_NAME ) )
			{
				sStyleName = sValue;
			}
		}
        else if ( (XML_NAMESPACE_XML == nPrefix2) &&
             IsXMLToken(aLocalName, XML_ID)   )
        {
            (void) sValue;
//FIXME: TODO
        }
//FIXME: RDFa (table:table-cell)
	}

	// if there is no style name at the cell, try default style name from row
	if( sStyleName.getLength() == 0 )
		sStyleName = sDefaultCellStyleName;

	if( sStyleName.getLength() )
	{
		SvXMLStylesContext * pAutoStyles = GetImport().GetShapeImport()->GetAutoStylesContext();
		if( pAutoStyles )
		{
			const XMLPropStyleContext* pStyle =
				dynamic_cast< const XMLPropStyleContext* >(
					pAutoStyles->FindStyleChildContext(XML_STYLE_FAMILY_TABLE_CELL, sStyleName) );

			if( pStyle )
			{
				Reference< XPropertySet > xCellSet( mxCell, UNO_QUERY );
				if( xCellSet.is() )
					const_cast< XMLPropStyleContext* >( pStyle )->FillPropertySet( xCellSet );
			}
		}
	}
}

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

XMLCellImportContext::~XMLCellImportContext()
{
}

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

SvXMLImportContext * XMLCellImportContext::CreateChildContext( sal_uInt16 nPrefix, const OUString& rLocalName, const Reference< XAttributeList >& xAttrList )
{
	// create text cursor on demand
	if( !mxCursor.is() )
	{
		Reference< XText > xText( mxCell, UNO_QUERY );
		if( xText.is() )
		{
			UniReference < XMLTextImportHelper > xTxtImport( GetImport().GetTextImport() );
			mxOldCursor = xTxtImport->GetCursor();
			mxCursor = xText->createTextCursor();
			if( mxCursor.is() )
				xTxtImport->SetCursor( mxCursor );

			// remember old list item and block (#91964#) and reset them
			// for the text frame
            xTxtImport->PushListContext();
            mbListContextPushed = true;
		}
	}

	SvXMLImportContext * pContext = 0;

	// if we have a text cursor, lets  try to import some text
	if( mxCursor.is() )
	{
		pContext = GetImport().GetTextImport()->CreateTextChildContext( GetImport(), nPrefix, rLocalName, xAttrList );
	}

	if( pContext )
		return pContext;
	else
		return SvXMLImportContext::CreateChildContext( nPrefix, rLocalName, xAttrList);
}

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

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

void XMLCellImportContext::EndElement()
{
	if(mxCursor.is())
	{
		// delete addition newline
		const OUString aEmpty;
		mxCursor->gotoEnd( sal_False );
		mxCursor->goLeft( 1, sal_True );
		mxCursor->setString( aEmpty );

		// reset cursor
		GetImport().GetTextImport()->ResetCursor();
	}

	if(mxOldCursor.is())
		GetImport().GetTextImport()->SetCursor( mxOldCursor );

    // reinstall old list item (if necessary) #91964#
    if (mbListContextPushed) {
        GetImport().GetTextImport()->PopListContext();
    }
}

// --------------------------------------------------------------------
// class XMLTableTemplateContext
// --------------------------------------------------------------------

XMLTableTemplateContext::XMLTableTemplateContext( SvXMLImport& rImport, sal_uInt16 nPrfx, const OUString& rLName, const Reference< XAttributeList >& xAttrList )
: SvXMLStyleContext( rImport, nPrfx, rLName, xAttrList, XML_STYLE_FAMILY_TABLE_TEMPLATE_ID, sal_False )
{
}

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

void XMLTableTemplateContext::StartElement( const Reference< XAttributeList >& xAttrList )
{
	sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
	for(sal_Int16 i=0; i < nAttrCount; i++)
	{
		OUString sAttrName;
		sal_uInt16 nAttrPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( xAttrList->getNameByIndex( i ), &sAttrName );
		if( (nAttrPrefix == XML_NAMESPACE_TEXT ) && IsXMLToken( sAttrName, XML_STYLE_NAME ) )
		{
			msTemplateStyleName = xAttrList->getValueByIndex( i );
			break;
		}
	}
}

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

void XMLTableTemplateContext::EndElement()
{
	rtl::Reference< XMLTableImport > xTableImport( GetImport().GetShapeImport()->GetShapeTableImport() );
	if( xTableImport.is() )
		xTableImport->addTableTemplate( msTemplateStyleName, maTableTemplate );
}

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

SvXMLImportContext * XMLTableTemplateContext::CreateChildContext( sal_uInt16 nPrefix, const OUString& rLocalName, const Reference< XAttributeList >& xAttrList )
{
	if( nPrefix == XML_NAMESPACE_TABLE )
	{
		const TableStyleElement* pElements = getTableStyleMap();
		while( (pElements->meElement != XML_TOKEN_END) && !IsXMLToken( rLocalName, pElements->meElement ) )
			pElements++;

		if( pElements->meElement != XML_TOKEN_END )
		{
			sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
			for(sal_Int16 i=0; i < nAttrCount; i++)
			{
				OUString sAttrName;
				sal_uInt16 nAttrPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( xAttrList->getNameByIndex( i ), &sAttrName );
				if( (nAttrPrefix == XML_NAMESPACE_TEXT) && IsXMLToken( sAttrName, XML_STYLE_NAME ) )
				{
					maTableTemplate[pElements->msStyleName] = xAttrList->getValueByIndex( i );
					break;
				}
			}
		}
	}

	return SvXMLImportContext::CreateChildContext( nPrefix, rLocalName, xAttrList );
}

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