/**************************************************************
 *
 * 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 "XMLSectionFootnoteConfigExport.hxx"
#include <xmloff/xmlexp.hxx>
#include <xmloff/xmlprmap.hxx>
#include <com/sun/star/style/NumberingType.hpp>
#include <xmloff/maptype.hxx>

#ifndef _XMLOFF_TXTPRMAP_HXX
#include <xmloff/txtprmap.hxx>
#endif
#include <xmloff/nmspmap.hxx>
#include "xmloff/xmlnmspe.hxx"
#include <xmloff/xmluconv.hxx>
#include <xmloff/xmltoken.hxx>
#include <xmloff/xmlnume.hxx>
#include <tools/debug.hxx>

#ifndef _RTL_USTRING
#include <rtl/ustring.hxx>
#endif
#include <rtl/ustrbuf.hxx>

#include <vector>


using namespace ::xmloff::token;

using ::std::vector;
using ::rtl::OUString;
using ::rtl::OUStringBuffer;
using ::com::sun::star::style::NumberingType::ARABIC;


void XMLSectionFootnoteConfigExport::exportXML(
	SvXMLExport& rExport,
	sal_Bool bEndnote,
	const vector<XMLPropertyState> *pProperties,
	sal_uInt32
    #ifdef DBG_UTIL
    nIdx
    #endif
    ,
	const UniReference<XMLPropertySetMapper> & rMapper)
{
	// store and initialize the values
	sal_Bool bNumOwn = sal_False;
	sal_Bool bNumRestart = sal_False;
	sal_Int16 nNumRestartAt = 0;
	sal_Int16 nNumberingType = ARABIC;
	OUString sNumPrefix;
	OUString sNumSuffix;
	sal_Bool bEnd = sal_False;

	// find entries in property states vector
	sal_uInt32 nCount = pProperties->size();
	for(sal_uInt32 i = 0; i < nCount; i++)
	{
		const XMLPropertyState& rState = (*pProperties)[i];

		sal_Int16 nContextId = rMapper->GetEntryContextId(rState.mnIndex);
		if (!bEndnote)
		{
			switch (nContextId)
			{
				case CTF_SECTION_FOOTNOTE_NUM_OWN:
					rState.maValue >>= bNumOwn;
					break;
				case CTF_SECTION_FOOTNOTE_NUM_RESTART:
					rState.maValue >>= bNumRestart;
					break;
				case CTF_SECTION_FOOTNOTE_NUM_RESTART_AT:
					rState.maValue >>= nNumRestartAt;
					break;
				case CTF_SECTION_FOOTNOTE_NUM_TYPE:
					rState.maValue >>= nNumberingType;
					break;
				case CTF_SECTION_FOOTNOTE_NUM_PREFIX:
					rState.maValue >>= sNumPrefix;
					break;
				case CTF_SECTION_FOOTNOTE_NUM_SUFFIX:
					rState.maValue >>= sNumSuffix;
					break;
				case CTF_SECTION_FOOTNOTE_END:
					DBG_ASSERT( i == nIdx,
								"received wrong property state index" );
					rState.maValue >>= bEnd;
					break;
			}
		}
		else
		{
			switch (nContextId)
			{
				case CTF_SECTION_ENDNOTE_NUM_OWN:
					rState.maValue >>= bNumOwn;
					break;
				case CTF_SECTION_ENDNOTE_NUM_RESTART:
					rState.maValue >>= bNumRestart;
					break;
				case CTF_SECTION_ENDNOTE_NUM_RESTART_AT:
					rState.maValue >>= nNumRestartAt;
					break;
				case CTF_SECTION_ENDNOTE_NUM_TYPE:
					rState.maValue >>= nNumberingType;
					break;
				case CTF_SECTION_ENDNOTE_NUM_PREFIX:
					rState.maValue >>= sNumPrefix;
					break;
				case CTF_SECTION_ENDNOTE_NUM_SUFFIX:
					rState.maValue >>= sNumSuffix;
					break;
				case CTF_SECTION_ENDNOTE_END:
					DBG_ASSERT( i == nIdx,
								"received wrong property state index" );
					rState.maValue >>= bEnd;
					break;
			}
		}
	}

	// we only make an element if we have an own footnote/endnote numbering
	if (bEnd)
	{
		rExport.AddAttribute(XML_NAMESPACE_TEXT, XML_NOTE_CLASS,
								 GetXMLToken( bEndnote ? XML_ENDNOTE
														 : XML_FOOTNOTE ) );
		// start numbering
		OUStringBuffer sBuf;
		if (bNumRestart)
		{
			// restart number is stored as 0.., but interpreted as 1..
			SvXMLUnitConverter::convertNumber(sBuf,
											  (sal_Int32)(nNumRestartAt+1));
			rExport.AddAttribute(XML_NAMESPACE_TEXT, XML_START_VALUE,
								 sBuf.makeStringAndClear());
		}

		if (bNumOwn)
		{
			// prefix and suffix
			if (sNumPrefix.getLength() > 0)
			{
					rExport.AddAttribute(XML_NAMESPACE_STYLE, XML_NUM_PREFIX,
										 sNumPrefix);
			}
			if (sNumSuffix.getLength() > 0)
			{
				rExport.AddAttribute(XML_NAMESPACE_STYLE, XML_NUM_SUFFIX,
									 sNumSuffix);
			}

			// number type: num format
			rExport.GetMM100UnitConverter().convertNumFormat( sBuf,
															  nNumberingType );
			rExport.AddAttribute(XML_NAMESPACE_STYLE, XML_NUM_FORMAT,
								 sBuf.makeStringAndClear());

			// and letter sync, if applicable
			rExport.GetMM100UnitConverter().convertNumLetterSync(
				sBuf, nNumberingType );
			if (sBuf.getLength())
			{
				rExport.AddAttribute(XML_NAMESPACE_STYLE,
									 XML_NUM_LETTER_SYNC,
									 sBuf.makeStringAndClear());
			}
		}

		// and finally, the element
		SvXMLElementExport rElem(rExport, XML_NAMESPACE_TEXT,
								 XML_NOTES_CONFIGURATION,
								 sal_True, sal_True);
	}
}
