/**************************************************************
 *
 * 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 "XMLIndexObjectSourceContext.hxx"
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/container/XIndexReplace.hpp>
#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 ::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;
using ::xmloff::token::IsXMLToken;
using ::xmloff::token::XML_OBJECT_INDEX_ENTRY_TEMPLATE;
using ::xmloff::token::XML_TOKEN_INVALID;

const sal_Char sAPI_CreateFromStarCalc[] = "CreateFromStarCalc";
const sal_Char sAPI_CreateFromStarChart[] = "CreateFromStarChart";
const sal_Char sAPI_CreateFromStarDraw[] = "CreateFromStarDraw";
const sal_Char sAPI_CreateFromStarImage[] = "CreateFromStarImage";
const sal_Char sAPI_CreateFromStarMath[] = "CreateFromStarMath";
const sal_Char sAPI_CreateFromOtherEmbeddedObjects[] = "CreateFromOtherEmbeddedObjects";


TYPEINIT1( XMLIndexObjectSourceContext, XMLIndexSourceBaseContext );

XMLIndexObjectSourceContext::XMLIndexObjectSourceContext(
	SvXMLImport& rImport,
	sal_uInt16 nPrfx,
	const OUString& rLocalName,
	Reference<XPropertySet> & rPropSet) :
		XMLIndexSourceBaseContext(rImport, nPrfx, rLocalName,
								  rPropSet, sal_False),
		sCreateFromStarCalc(RTL_CONSTASCII_USTRINGPARAM(
			sAPI_CreateFromStarCalc)),
		sCreateFromStarChart(RTL_CONSTASCII_USTRINGPARAM(
			sAPI_CreateFromStarChart)),
		sCreateFromStarDraw(RTL_CONSTASCII_USTRINGPARAM(
			sAPI_CreateFromStarDraw)),
		sCreateFromStarMath(RTL_CONSTASCII_USTRINGPARAM(
			sAPI_CreateFromStarMath)),
		sCreateFromOtherEmbeddedObjects(RTL_CONSTASCII_USTRINGPARAM(
			sAPI_CreateFromOtherEmbeddedObjects)),
		bUseCalc(sal_False),
		bUseChart(sal_False),
		bUseDraw(sal_False),
		bUseMath(sal_False),
		bUseOtherObjects(sal_False)
{
}

XMLIndexObjectSourceContext::~XMLIndexObjectSourceContext()
{
}

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

		case XML_TOK_INDEXSOURCE_USE_OTHER_OBJECTS:
			if (SvXMLUnitConverter::convertBool(bTmp, rValue))
			{
				bUseOtherObjects = bTmp;
			}
			break;

		case XML_TOK_INDEXSOURCE_USE_SHEET:
			if (SvXMLUnitConverter::convertBool(bTmp, rValue))
			{
				bUseCalc = bTmp;
			}
			break;

		case XML_TOK_INDEXSOURCE_USE_CHART:
			if (SvXMLUnitConverter::convertBool(bTmp, rValue))
			{
				bUseChart = bTmp;
			}
			break;

		case XML_TOK_INDEXSOURCE_USE_DRAW:
			if (SvXMLUnitConverter::convertBool(bTmp, rValue))
			{
				bUseDraw = bTmp;
			}
			break;

		case XML_TOK_INDEXSOURCE_USE_MATH:
			if (SvXMLUnitConverter::convertBool(bTmp, rValue))
			{
				bUseMath = bTmp;
			}
			break;

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

void XMLIndexObjectSourceContext::EndElement()
{
	Any aAny;

	aAny.setValue(&bUseCalc, ::getBooleanCppuType());
	rIndexPropertySet->setPropertyValue(sCreateFromStarCalc, aAny);

	aAny.setValue(&bUseChart, ::getBooleanCppuType());
	rIndexPropertySet->setPropertyValue(sCreateFromStarChart, aAny);

	aAny.setValue(&bUseDraw, ::getBooleanCppuType());
	rIndexPropertySet->setPropertyValue(sCreateFromStarDraw, aAny);

	aAny.setValue(&bUseMath, ::getBooleanCppuType());
	rIndexPropertySet->setPropertyValue(sCreateFromStarMath, aAny);

	aAny.setValue(&bUseOtherObjects, ::getBooleanCppuType());
	rIndexPropertySet->setPropertyValue(sCreateFromOtherEmbeddedObjects, aAny);

	XMLIndexSourceBaseContext::EndElement();
}

SvXMLImportContext* XMLIndexObjectSourceContext::CreateChildContext(
	sal_uInt16 nPrefix,
	const OUString& rLocalName,
	const Reference<XAttributeList> & xAttrList )
{
	if ( (XML_NAMESPACE_TEXT == nPrefix) &&
		 (IsXMLToken(rLocalName, XML_OBJECT_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);
	}

}
