/**************************************************************
 * 
 * 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 "XMLSectionFootnoteConfigImport.hxx"

#ifndef _RTL_USTRING
#include <rtl/ustring.hxx>
#endif
#include <com/sun/star/uno/Reference.h>
#include <com/sun/star/xml/sax/XAttributeList.hpp>
#include <com/sun/star/style/NumberingType.hpp>
#include <xmloff/xmlimp.hxx>
#include <xmloff/xmltoken.hxx>
#include <xmloff/xmluconv.hxx>
#include <xmloff/xmlprmap.hxx>
#include "xmloff/xmlnmspe.hxx"
#include <xmloff/nmspmap.hxx>
#include <xmloff/maptype.hxx>
#include <xmloff/xmlnumi.hxx>
#include <xmloff/txtprmap.hxx>
#include <tools/debug.hxx>

#include <vector>


using namespace ::xmloff::token;
using namespace ::com::sun::star::style;

using ::rtl::OUString;
using ::std::vector;
using ::com::sun::star::uno::Any;
using ::com::sun::star::uno::Reference;
using ::com::sun::star::xml::sax::XAttributeList;


TYPEINIT1(XMLSectionFootnoteConfigImport, SvXMLImportContext);


XMLSectionFootnoteConfigImport::XMLSectionFootnoteConfigImport(
	SvXMLImport& rImport, 
	sal_uInt16 nPrefix, 
	const OUString& rLocalName, 
	vector<XMLPropertyState> & rProps,
	const UniReference<XMLPropertySetMapper> & rMapperRef) :
		SvXMLImportContext(rImport, nPrefix, rLocalName),
		rProperties(rProps),
		rMapper(rMapperRef)
{
}

XMLSectionFootnoteConfigImport::~XMLSectionFootnoteConfigImport()
{
}

void XMLSectionFootnoteConfigImport::StartElement( 
	const Reference<XAttributeList> & xAttrList)
{
	sal_Bool bEnd = sal_True;	// we're inside the element, so this is true
	sal_Bool bNumOwn = sal_False;
	sal_Bool bNumRestart = sal_False;
	sal_Bool bEndnote = sal_False;
	sal_Int16 nNumRestartAt = 0;
	OUString sNumPrefix;
	OUString sNumSuffix;
	OUString sNumFormat;
	OUString sNumLetterSync;

	// iterate over xattribute list and fill values
	sal_Int16 nLength = xAttrList->getLength();
	for(sal_Int16 nAttr = 0; nAttr < nLength; nAttr++)
	{
		OUString sLocalName;
		sal_uInt16 nPrefix = GetImport().GetNamespaceMap().
			GetKeyByAttrName( xAttrList->getNameByIndex(nAttr), 
							  &sLocalName );
		OUString sAttrValue = xAttrList->getValueByIndex(nAttr);

		if (XML_NAMESPACE_TEXT == nPrefix)
		{
			if (IsXMLToken(sLocalName, XML_START_VALUE))
			{
				sal_Int32 nTmp;
				if (SvXMLUnitConverter::convertNumber(nTmp, sAttrValue))
				{
					nNumRestartAt = static_cast< sal_Int16 >( nTmp ) - 1;
					bNumRestart = sal_True;
				}
			}
			else if( IsXMLToken( sLocalName, XML_NOTE_CLASS ) )
			{
				if( IsXMLToken( sAttrValue, XML_ENDNOTE ) )
					bEndnote = sal_True;
			}
		}
		else if (XML_NAMESPACE_STYLE == nPrefix)
		{
			if (IsXMLToken(sLocalName, XML_NUM_PREFIX))
			{
				sNumPrefix = sAttrValue;
				bNumOwn = sal_True;
			}
			else if (IsXMLToken(sLocalName, XML_NUM_SUFFIX))
			{
				sNumSuffix = sAttrValue;
				bNumOwn = sal_True;
			}
			else if (IsXMLToken(sLocalName, XML_NUM_FORMAT))
			{
				sNumFormat = sAttrValue;
				bNumOwn = sal_True;
			}
			else if (IsXMLToken(sLocalName, XML_NUM_LETTER_SYNC))
			{
				sNumLetterSync = sAttrValue;
				bNumOwn = sal_True;
			}
		}
	}

	// OK, now we have all values and can fill the XMLPropertyState vector
	Any aAny;

	aAny.setValue( &bNumOwn, ::getBooleanCppuType() );
	sal_Int32 nIndex = rMapper->FindEntryIndex( bEndnote ? 
		CTF_SECTION_ENDNOTE_NUM_OWN : CTF_SECTION_FOOTNOTE_NUM_OWN );
	XMLPropertyState aNumOwn( nIndex, aAny );
	rProperties.push_back( aNumOwn );

	aAny.setValue( &bNumRestart, ::getBooleanCppuType() );
	nIndex = rMapper->FindEntryIndex( bEndnote ? 
		CTF_SECTION_ENDNOTE_NUM_RESTART : CTF_SECTION_FOOTNOTE_NUM_RESTART );
	XMLPropertyState aNumRestart( nIndex, aAny );
	rProperties.push_back( aNumRestart );

	aAny <<= nNumRestartAt;
	nIndex = rMapper->FindEntryIndex( bEndnote ? 
		CTF_SECTION_ENDNOTE_NUM_RESTART_AT : 
		CTF_SECTION_FOOTNOTE_NUM_RESTART_AT );
	XMLPropertyState aNumRestartAtState( nIndex, aAny );
	rProperties.push_back( aNumRestartAtState );

	sal_Int16 nNumType = NumberingType::ARABIC;
	GetImport().GetMM100UnitConverter().convertNumFormat( nNumType,
													sNumFormat,
													sNumLetterSync );
	aAny <<= nNumType;
	nIndex = rMapper->FindEntryIndex( bEndnote ? 
		CTF_SECTION_ENDNOTE_NUM_TYPE : CTF_SECTION_FOOTNOTE_NUM_TYPE );
	XMLPropertyState aNumFormatState( nIndex, aAny );
	rProperties.push_back( aNumFormatState );

	aAny <<= sNumPrefix;
	nIndex = rMapper->FindEntryIndex( bEndnote ? 
		CTF_SECTION_ENDNOTE_NUM_PREFIX : CTF_SECTION_FOOTNOTE_NUM_PREFIX );
	XMLPropertyState aPrefixState( nIndex, aAny );
	rProperties.push_back( aPrefixState );
		
	aAny <<= sNumSuffix;
	nIndex = rMapper->FindEntryIndex( bEndnote ? 
		CTF_SECTION_ENDNOTE_NUM_SUFFIX : CTF_SECTION_FOOTNOTE_NUM_SUFFIX );
	XMLPropertyState aSuffixState( nIndex, aAny );
	rProperties.push_back( aSuffixState );

	aAny.setValue( &bEnd, ::getBooleanCppuType() );
	nIndex = rMapper->FindEntryIndex( bEndnote ? 
		CTF_SECTION_ENDNOTE_END : CTF_SECTION_FOOTNOTE_END );
	XMLPropertyState aEndState( nIndex, aAny );
	rProperties.push_back( aEndState );
}
