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


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

}
