/**************************************************************
 *
 * 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 "XMLIndexTableSourceContext.hxx"
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/container/XIndexReplace.hpp>

#ifndef _COM_SUN_STAR_TEXT_REFERENCEFIELD_PART_HPP
#include <com/sun/star/text/ReferenceFieldPart.hpp>
#endif
#include "XMLIndexTemplateContext.hxx"
#include "XMLIndexTitleTemplateContext.hxx"
#include "XMLIndexTOCStylesContext.hxx"
#include <xmloff/xmlictxt.hxx>
#include <xmloff/xmlimp.hxx>
#include <xmloff/txtimp.hxx>
#include "xmloff/xmlnmspe.hxx"
#include <xmloff/nmspmap.hxx>
#include <xmloff/xmltoken.hxx>
#include <xmloff/xmluconv.hxx>
#include <tools/debug.hxx>
#include <rtl/ustring.hxx>


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

using ::rtl::OUString;
using ::com::sun::star::beans::XPropertySet;
using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::Any;
using ::com::sun::star::xml::sax::XAttributeList;

const sal_Char sAPI_CreateFromLabels[] = "CreateFromLabels";
const sal_Char sAPI_LabelCategory[] = "LabelCategory";
const sal_Char sAPI_LabelDisplayType[] = "LabelDisplayType";


TYPEINIT1(XMLIndexTableSourceContext, XMLIndexSourceBaseContext);


XMLIndexTableSourceContext::XMLIndexTableSourceContext(
	SvXMLImport& rImport,
	sal_uInt16 nPrfx,
	const OUString& rLocalName,
	Reference<XPropertySet> & rPropSet) :
		XMLIndexSourceBaseContext(rImport, nPrfx, rLocalName,
								  rPropSet, sal_False),
		sCreateFromLabels(RTL_CONSTASCII_USTRINGPARAM(sAPI_CreateFromLabels)),
		sLabelCategory(RTL_CONSTASCII_USTRINGPARAM(sAPI_LabelCategory)),
		sLabelDisplayType(RTL_CONSTASCII_USTRINGPARAM(sAPI_LabelDisplayType)),
		bSequenceOK(sal_False),
		bDisplayFormatOK(sal_False),
		bUseCaption(sal_True)
{
}

XMLIndexTableSourceContext::~XMLIndexTableSourceContext()
{
}

static SvXMLEnumMapEntry __READONLY_DATA lcl_aReferenceTypeTokenMap[] =
{

	{ XML_TEXT,			        ReferenceFieldPart::TEXT },
	{ XML_CATEGORY_AND_VALUE,	ReferenceFieldPart::CATEGORY_AND_NUMBER },
	{ XML_CAPTION, 		        ReferenceFieldPart::ONLY_CAPTION },

	// wrong values that previous versions wrote:
	{ XML_CHAPTER, 		        ReferenceFieldPart::CATEGORY_AND_NUMBER },
	{ XML_PAGE,			        ReferenceFieldPart::ONLY_CAPTION },

	{ XML_TOKEN_INVALID, 		0 }
};

void XMLIndexTableSourceContext::ProcessAttribute(
	enum IndexSourceParamEnum eParam,
	const OUString& rValue)
{
	sal_Bool bTmp;

	switch (eParam)
	{
		case XML_TOK_INDEXSOURCE_USE_CAPTION:
			if (SvXMLUnitConverter::convertBool(bTmp, rValue))
			{
				bUseCaption = bTmp;
			}
			break;

		case XML_TOK_INDEXSOURCE_SEQUENCE_NAME:
			sSequence = rValue;
			bSequenceOK = sal_True;
			break;

		case XML_TOK_INDEXSOURCE_SEQUENCE_FORMAT:
		{
 			sal_uInt16 nTmp;
 		    if (SvXMLUnitConverter::convertEnum(nTmp, rValue,
 												lcl_aReferenceTypeTokenMap))
			{
 				nDisplayFormat = nTmp;
 				bDisplayFormatOK = sal_True;
 			}
			break;
		}

		default:
			XMLIndexSourceBaseContext::ProcessAttribute(eParam, rValue);
			break;
	}
}


void XMLIndexTableSourceContext::EndElement()
{
	Any aAny;

	aAny.setValue(&bUseCaption, ::getBooleanCppuType());
	rIndexPropertySet->setPropertyValue(sCreateFromLabels, aAny);

	if (bSequenceOK)
	{
		aAny <<= sSequence;
		rIndexPropertySet->setPropertyValue(sLabelCategory, aAny);
	}

	if (bDisplayFormatOK)
	{
		aAny <<= nDisplayFormat;
		rIndexPropertySet->setPropertyValue(sLabelDisplayType, aAny);
	}

	XMLIndexSourceBaseContext::EndElement();
}


SvXMLImportContext* XMLIndexTableSourceContext::CreateChildContext(
	sal_uInt16 nPrefix,
	const OUString& rLocalName,
	const Reference<XAttributeList> & xAttrList )
{
	if ( ( XML_NAMESPACE_TEXT == nPrefix ) &&
		 ( IsXMLToken( rLocalName, XML_TABLE_INDEX_ENTRY_TEMPLATE ) ) )
	{
		return new XMLIndexTemplateContext(GetImport(), rIndexPropertySet,
										   nPrefix, rLocalName,
										   aLevelNameTableMap,
										   XML_TOKEN_INVALID, // no outline-level attr
										   aLevelStylePropNameTableMap,
										   aAllowedTokenTypesTable);
	}
	else
	{
		return XMLIndexSourceBaseContext::CreateChildContext(nPrefix,
															 rLocalName,
															 xAttrList);
	}

}
