/**************************************************************
 *
 * 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 "MergeElemTContext.hxx"
#include "MutableAttrList.hxx"
#ifndef _XMLOFF_TRANSFORMERBASE_HXX
#include "TransformerBase.hxx"
#endif
#include "TransformerActions.hxx"
#include "AttrTransformerAction.hxx"
#include "ElemTransformerAction.hxx"
#include "IgnoreTContext.hxx"
#include "xmloff/xmlnmspe.hxx"

using ::rtl::OUString;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::xml::sax;
using namespace ::xmloff::token;

class XMLParagraphTransformerContext : public XMLTransformerContext
{
public:
	TYPEINFO();

	XMLParagraphTransformerContext( XMLTransformerBase& rTransformer,
						   const ::rtl::OUString& rQName );

	virtual ~XMLParagraphTransformerContext();

	// Create a childs element context. By default, the import's
	// CreateContext method is called to create a new default context.
	virtual XMLTransformerContext *CreateChildContext( sal_uInt16 nPrefix,
								   const ::rtl::OUString& rLocalName,
								   const ::rtl::OUString& rQName,
								   const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList );

	// StartElement is called after a context has been constructed and
	// before a elements context is parsed. It may be used for actions that
	// require virtual methods. The default is to do nothing.
	virtual void StartElement( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList );

	// EndElement is called before a context will be destructed, but
	// after a elements context has been parsed. It may be used for actions
	// that require virtual methods. The default is to do nothing.
	virtual void EndElement();

	// This method is called for all characters that are contained in the
	// current element. The default is to ignore them.
	virtual void Characters( const ::rtl::OUString& rChars );
};

TYPEINIT1( XMLParagraphTransformerContext, XMLTransformerContext );

XMLParagraphTransformerContext::XMLParagraphTransformerContext(
		XMLTransformerBase& rImp,
		const OUString& rQName ) :
	XMLTransformerContext( rImp, rQName )
{
}

XMLParagraphTransformerContext::~XMLParagraphTransformerContext()
{
}

XMLTransformerContext *XMLParagraphTransformerContext::CreateChildContext(
		sal_uInt16 /*nPrefix*/,
		const OUString& /*rLocalName*/,
		const OUString& rQName,
		const Reference< XAttributeList >& )
{
	XMLTransformerContext *pContext = 0;

    pContext = new XMLIgnoreTransformerContext( GetTransformer(),
												rQName, sal_True );

	return pContext;
}

void XMLParagraphTransformerContext::StartElement( const Reference< XAttributeList >& rAttrList )
{
    XMLTransformerContext::StartElement( rAttrList );
}

void XMLParagraphTransformerContext::EndElement()
{
    XMLTransformerContext::EndElement();
}

void XMLParagraphTransformerContext::Characters( const OUString& rChars )
{
    XMLTransformerContext::Characters( rChars );
}

class XMLPersTextContentRNGTransformTContext : public XMLPersTextContentTContext
{
public:
	TYPEINFO();

    XMLPersTextContentRNGTransformTContext(
        XMLTransformerBase& rTransformer,
        const ::rtl::OUString& rQName,
        sal_uInt16 nPrefix,
        ::xmloff::token::XMLTokenEnum eToken );
    virtual ~XMLPersTextContentRNGTransformTContext();

	virtual void Characters( const ::rtl::OUString& rChars );
};

TYPEINIT1( XMLPersTextContentRNGTransformTContext, XMLPersAttrListTContext );

XMLPersTextContentRNGTransformTContext::XMLPersTextContentRNGTransformTContext(
    XMLTransformerBase& rTransformer,
    const ::rtl::OUString& rQName,
    sal_uInt16 nPrefix,
    ::xmloff::token::XMLTokenEnum eToken ) :
        XMLPersTextContentTContext(
            rTransformer, rQName, nPrefix, eToken )
{}

XMLPersTextContentRNGTransformTContext::~XMLPersTextContentRNGTransformTContext()
{}

void XMLPersTextContentRNGTransformTContext::Characters( const ::rtl::OUString& rChars )
{
    OUString aConvChars( rChars );
    GetTransformer().ConvertRNGDateTimeToISO( aConvChars );
    XMLPersTextContentTContext::Characters( aConvChars );
}


TYPEINIT1( XMLMergeElemTransformerContext, XMLTransformerContext );

void XMLMergeElemTransformerContext::ExportStartElement()
{
	XMLPersTextContentTContextVector::iterator aIter = m_aChildContexts.begin();

	for( ; aIter != m_aChildContexts.end(); ++aIter )
	{
		XMLPersTextContentTContext *pContext = (*aIter).get();
		static_cast< XMLMutableAttributeList * >( m_xAttrList.get() )
			->AddAttribute( pContext->GetExportQName(),
							pContext->GetTextContent() );
	}
	XMLTransformerContext::StartElement( m_xAttrList );

	m_bStartElementExported = sal_True;
}

XMLMergeElemTransformerContext::XMLMergeElemTransformerContext(
		XMLTransformerBase& rImp,
		const OUString& rQName,
	   sal_uInt16 nActionMap ) :
	XMLTransformerContext( rImp, rQName ),
	m_nActionMap( nActionMap ),
	m_bStartElementExported( sal_False )
{
}

XMLMergeElemTransformerContext::~XMLMergeElemTransformerContext()
{
}

void XMLMergeElemTransformerContext::StartElement(
	const Reference< XAttributeList >& rAttrList )
{
	XMLMutableAttributeList *pMutableAttrList =
		new XMLMutableAttributeList( rAttrList, sal_True );
	m_xAttrList = pMutableAttrList;

	sal_Int16 nAttrCount = m_xAttrList.is() ? m_xAttrList->getLength() : 0;
	for( sal_Int16 i=0; i < nAttrCount; i++ )
	{
		const OUString& rAttrName = m_xAttrList->getNameByIndex( i );
		OUString aLocalName;
		sal_uInt16 nPrefix =
			GetTransformer().GetNamespaceMap().GetKeyByAttrName( rAttrName,
																&aLocalName );
        sal_Bool bRemove = sal_True;
        if( XML_NAMESPACE_OFFICE == nPrefix)
        {
            if (IsXMLToken( aLocalName, XML_DISPLAY ) )
                bRemove = sal_False;
            else if (IsXMLToken( aLocalName, XML_AUTHOR ) )
                bRemove = sal_False;
            else if (IsXMLToken( aLocalName, XML_CREATE_DATE ) )
                bRemove = sal_False;
            else if (IsXMLToken( aLocalName, XML_CREATE_DATE_STRING ) )
                bRemove = sal_False;
        }
        if (bRemove)
        {
            pMutableAttrList->RemoveAttributeByIndex( i );
            --i;
            --nAttrCount;
        }
	}
}

XMLTransformerContext *XMLMergeElemTransformerContext::CreateChildContext(
		sal_uInt16 nPrefix,
		const OUString& rLocalName,
		const OUString& rQName,
		const Reference< XAttributeList >& rAttrList )
{
	XMLTransformerContext *pContext = 0;

	if( !m_bStartElementExported )
	{
		XMLTransformerActions *pActions =
			GetTransformer().GetUserDefinedActions( m_nActionMap );
		OSL_ENSURE( pActions, "go no actions" );
		if( pActions )
		{
			XMLTransformerActions::key_type aKey( nPrefix, rLocalName );
			XMLTransformerActions::const_iterator aIter =
				pActions->find( aKey );

			if( !(aIter == pActions->end()) )
			{
				switch( (*aIter).second.m_nActionType )
				{
				case XML_ATACTION_MOVE_FROM_ELEM_RNG2ISO_DATETIME:
					{
						XMLPersTextContentTContext *pTC =
							new XMLPersTextContentRNGTransformTContext(
									GetTransformer(), rQName,
								    (*aIter).second.GetQNamePrefixFromParam1(),
									(*aIter).second.GetQNameTokenFromParam1() );
						XMLPersTextContentTContextVector::value_type aVal(pTC);
						m_aChildContexts.push_back( aVal );
						pContext = pTC;
					}
					break;
                case XML_ATACTION_MOVE_FROM_ELEM:
					{
						XMLPersTextContentTContext *pTC =
							new XMLPersTextContentTContext(
									GetTransformer(), rQName,
								    (*aIter).second.GetQNamePrefixFromParam1(),
									(*aIter).second.GetQNameTokenFromParam1() );
						XMLPersTextContentTContextVector::value_type aVal(pTC);
						m_aChildContexts.push_back( aVal );
						pContext = pTC;
					}
					break;
                case XML_ETACTION_EXTRACT_CHARACTERS:
                    {
		                if( !m_bStartElementExported )
			                ExportStartElement();
                        XMLParagraphTransformerContext* pPTC =
	                        new XMLParagraphTransformerContext( GetTransformer(),
						    rQName);
						pContext = pPTC;
                    }
                    break;
				default:
					OSL_ENSURE( sal_False, "unknown action" );
					break;
				}
			}
		}
	}
    else
	{
		XMLTransformerActions *pActions =
			GetTransformer().GetUserDefinedActions( m_nActionMap );
		OSL_ENSURE( pActions, "go no actions" );
		if( pActions )
		{
			XMLTransformerActions::key_type aKey( nPrefix, rLocalName );
			XMLTransformerActions::const_iterator aIter =
				pActions->find( aKey );

			if( !(aIter == pActions->end()) )
			{
				switch( (*aIter).second.m_nActionType )
				{
                case XML_ETACTION_EXTRACT_CHARACTERS:
                    {
		                if( !m_bStartElementExported )
			                ExportStartElement();
                        XMLParagraphTransformerContext* pPTC =
	                        new XMLParagraphTransformerContext( GetTransformer(),
						    rQName);
						pContext = pPTC;
                    }
                    break;
				default:
					OSL_ENSURE( sal_False, "unknown action" );
					break;
				}
			}
		}
	}

	// default is copying
	if( !pContext )
	{
		if( !m_bStartElementExported )
			ExportStartElement();
		pContext = XMLTransformerContext::CreateChildContext( nPrefix,
															  rLocalName,
															  rQName,
															  rAttrList );
	}

	return pContext;
}

void XMLMergeElemTransformerContext::EndElement()
{
	if( !m_bStartElementExported )
		ExportStartElement();
	XMLTransformerContext::EndElement();
}

void XMLMergeElemTransformerContext::Characters( const OUString& )
{
	// ignore
}
