/**************************************************************
 * 
 * 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;


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 );
}
