/**************************************************************
 *
 * 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 "XMLIndexUserSourceContext.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_USER_INDEX_ENTRY_TEMPLATE;
using ::xmloff::token::XML_OUTLINE_LEVEL;


const sal_Char sAPI_CreateFromEmbeddedObjects[] = "CreateFromEmbeddedObjects";
const sal_Char sAPI_CreateFromGraphicObjects[] = "CreateFromGraphicObjects";
const sal_Char sAPI_CreateFromMarks[] = "CreateFromMarks";
const sal_Char sAPI_CreateFromTables[] = "CreateFromTables";
const sal_Char sAPI_CreateFromTextFrames[] = "CreateFromTextFrames";
const sal_Char sAPI_UseLevelFromSource[] = "UseLevelFromSource";
const sal_Char sAPI_CreateFromLevelParagraphStyles[] = "CreateFromLevelParagraphStyles";
const sal_Char sAPI_UserIndexName[] = "UserIndexName";


TYPEINIT1(XMLIndexUserSourceContext, XMLIndexSourceBaseContext);


XMLIndexUserSourceContext::XMLIndexUserSourceContext(
	SvXMLImport& rImport,
	sal_uInt16 nPrfx,
	const OUString& rLocalName,
	Reference<XPropertySet> & rPropSet) :
		XMLIndexSourceBaseContext(rImport, nPrfx, rLocalName,
								  rPropSet, sal_True),
		sCreateFromEmbeddedObjects(RTL_CONSTASCII_USTRINGPARAM(
			sAPI_CreateFromEmbeddedObjects)),
		sCreateFromGraphicObjects(RTL_CONSTASCII_USTRINGPARAM(
			sAPI_CreateFromGraphicObjects)),
		sCreateFromMarks(RTL_CONSTASCII_USTRINGPARAM(sAPI_CreateFromMarks)),
		sCreateFromTables(RTL_CONSTASCII_USTRINGPARAM(sAPI_CreateFromTables)),
		sCreateFromTextFrames(RTL_CONSTASCII_USTRINGPARAM(
			sAPI_CreateFromTextFrames)),
		sUseLevelFromSource(RTL_CONSTASCII_USTRINGPARAM(
			sAPI_UseLevelFromSource)),
		sCreateFromLevelParagraphStyles(RTL_CONSTASCII_USTRINGPARAM(
			sAPI_CreateFromLevelParagraphStyles)),
        sUserIndexName(RTL_CONSTASCII_USTRINGPARAM(sAPI_UserIndexName)),
		bUseObjects(sal_False),
		bUseGraphic(sal_False),
		bUseMarks(sal_False),
		bUseTables(sal_False),
		bUseFrames(sal_False),
		bUseLevelFromSource(sal_False),
		bUseLevelParagraphStyles(sal_False)
{
}

XMLIndexUserSourceContext::~XMLIndexUserSourceContext()
{
}

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

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

		case XML_TOK_INDEXSOURCE_USE_OBJECTS:
			if (SvXMLUnitConverter::convertBool(bTmp, rValue))
			{
				bUseObjects = bTmp;
			}
			break;

		case XML_TOK_INDEXSOURCE_USE_GRAPHICS:
			if (SvXMLUnitConverter::convertBool(bTmp, rValue))
			{
				bUseGraphic = bTmp;
			}
			break;

		case XML_TOK_INDEXSOURCE_USE_TABLES:
			if (SvXMLUnitConverter::convertBool(bTmp, rValue))
			{
				bUseTables = bTmp;
			}
			break;

		case XML_TOK_INDEXSOURCE_USE_FRAMES:
			if (SvXMLUnitConverter::convertBool(bTmp, rValue))
			{
				bUseFrames = bTmp;
			}
			break;

		case XML_TOK_INDEXSOURCE_COPY_OUTLINE_LEVELS:
			if (SvXMLUnitConverter::convertBool(bTmp, rValue))
			{
				bUseLevelFromSource = bTmp;
			}
			break;

		case XML_TOK_INDEXSOURCE_USE_INDEX_SOURCE_STYLES:
			if (SvXMLUnitConverter::convertBool(bTmp, rValue))
			{
				bUseLevelParagraphStyles = bTmp;
			}
			break;

		case XML_TOK_INDEXSOURCE_USER_INDEX_NAME:
            sIndexName = rValue;
			break;

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


void XMLIndexUserSourceContext::EndElement()
{
	Any aAny;

	aAny.setValue(&bUseObjects, ::getBooleanCppuType());
	rIndexPropertySet->setPropertyValue(sCreateFromEmbeddedObjects, aAny);

	aAny.setValue(&bUseGraphic, ::getBooleanCppuType());
	rIndexPropertySet->setPropertyValue(sCreateFromGraphicObjects, aAny);

	aAny.setValue(&bUseLevelFromSource, ::getBooleanCppuType());
	rIndexPropertySet->setPropertyValue(sUseLevelFromSource, aAny);

	aAny.setValue(&bUseMarks, ::getBooleanCppuType());
	rIndexPropertySet->setPropertyValue(sCreateFromMarks, aAny);

	aAny.setValue(&bUseTables, ::getBooleanCppuType());
	rIndexPropertySet->setPropertyValue(sCreateFromTables, aAny);

	aAny.setValue(&bUseFrames, ::getBooleanCppuType());
	rIndexPropertySet->setPropertyValue(sCreateFromTextFrames, aAny);

	aAny.setValue(&bUseLevelParagraphStyles, ::getBooleanCppuType());
	rIndexPropertySet->setPropertyValue(sCreateFromLevelParagraphStyles, aAny);

    if( sIndexName.getLength() > 0 )
    {
        aAny <<= sIndexName;
        rIndexPropertySet->setPropertyValue(sUserIndexName, aAny);
    }

	XMLIndexSourceBaseContext::EndElement();
}


SvXMLImportContext* XMLIndexUserSourceContext::CreateChildContext(
	sal_uInt16 nPrefix,
	const OUString& rLocalName,
	const Reference<XAttributeList> & xAttrList )
{
	if ( (XML_NAMESPACE_TEXT == nPrefix) &&
		 (IsXMLToken(rLocalName, XML_USER_INDEX_ENTRY_TEMPLATE)) )
	{
		return new XMLIndexTemplateContext(GetImport(), rIndexPropertySet,
										   nPrefix, rLocalName,
										   aLevelNameTOCMap,
										   XML_OUTLINE_LEVEL,
										   aLevelStylePropNameTOCMap,
										   aAllowedTokenTypesUser);
	}
	else
	{
		return XMLIndexSourceBaseContext::CreateChildContext(nPrefix,
															 rLocalName,
															 xAttrList);
	}

}
