/**************************************************************
 *
 * 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 "XMLIndexTemplateContext.hxx"
#include "XMLIndexSimpleEntryContext.hxx"
#include "XMLIndexSpanEntryContext.hxx"
#include "XMLIndexTabStopEntryContext.hxx"
#include "XMLIndexBibliographyEntryContext.hxx"
#include "XMLIndexChapterInfoEntryContext.hxx"
#include <xmloff/xmlictxt.hxx>
#include <xmloff/xmlimp.hxx>
#include <xmloff/txtimp.hxx>
#include <xmloff/nmspmap.hxx>
#include "xmloff/xmlnmspe.hxx"
#include <xmloff/xmltoken.hxx>
#include <xmloff/xmluconv.hxx>
#include <tools/debug.hxx>
#include <rtl/ustring.hxx>
#include <rtl/ustrbuf.hxx>
#include <com/sun/star/container/XIndexReplace.hpp>


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

using ::rtl::OUString;
using ::rtl::OUStringBuffer;
using ::com::sun::star::beans::XPropertySet;
using ::com::sun::star::beans::PropertyValue;
using ::com::sun::star::beans::PropertyValues;
using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::Sequence;
using ::com::sun::star::uno::Any;
using ::com::sun::star::xml::sax::XAttributeList;
using ::com::sun::star::container::XIndexReplace;

const sal_Char sAPI_TokenEntryNumber[] = 	"TokenEntryNumber";
const sal_Char sAPI_TokenEntryText[] = 		"TokenEntryText";
const sal_Char sAPI_TokenTabStop[] = 		"TokenTabStop";
const sal_Char sAPI_TokenText[] = 			"TokenText";
const sal_Char sAPI_TokenPageNumber[] = 	"TokenPageNumber";
const sal_Char sAPI_TokenChapterInfo[] = 	"TokenChapterInfo";
const sal_Char sAPI_TokenHyperlinkStart[] =	"TokenHyperlinkStart";
const sal_Char sAPI_TokenHyperlinkEnd[] =	"TokenHyperlinkEnd";
const sal_Char sAPI_TokenBibliographyDataField[] =
											"TokenBibliographyDataField";


TYPEINIT1( XMLIndexTemplateContext, SvXMLImportContext);

XMLIndexTemplateContext::XMLIndexTemplateContext(
	SvXMLImport& rImport,
	Reference<XPropertySet> & rPropSet,
	sal_uInt16 nPrfx,
	const OUString& rLocalName,
	const SvXMLEnumMapEntry* pLevelNameMap,
    enum XMLTokenEnum eLevelAttrName,
	const sal_Char** pLevelStylePropMap,
	const sal_Bool* pAllowedTokenTypes,
	sal_Bool bT )
:	SvXMLImportContext(rImport, nPrfx, rLocalName)
,	pOutlineLevelNameMap(pLevelNameMap)
,	eOutlineLevelAttrName(eLevelAttrName)
,	pOutlineLevelStylePropMap(pLevelStylePropMap)
,	pAllowedTokenTypesMap(pAllowedTokenTypes)
,	nOutlineLevel(1)	// all indices have level 1 (0 is for header)
,	bStyleNameOK(sal_False)
,	bOutlineLevelOK(sal_False)
,	bTOC( bT )
,	rPropertySet(rPropSet)
,	sTokenEntryNumber(RTL_CONSTASCII_USTRINGPARAM(sAPI_TokenEntryNumber))
,	sTokenEntryText(RTL_CONSTASCII_USTRINGPARAM(sAPI_TokenEntryText))
,	sTokenTabStop(RTL_CONSTASCII_USTRINGPARAM(sAPI_TokenTabStop))
,	sTokenText(RTL_CONSTASCII_USTRINGPARAM(sAPI_TokenText))
,	sTokenPageNumber(RTL_CONSTASCII_USTRINGPARAM(sAPI_TokenPageNumber))
,	sTokenChapterInfo(RTL_CONSTASCII_USTRINGPARAM(sAPI_TokenChapterInfo))
,	sTokenHyperlinkStart(RTL_CONSTASCII_USTRINGPARAM(sAPI_TokenHyperlinkStart))
,	sTokenHyperlinkEnd(RTL_CONSTASCII_USTRINGPARAM(sAPI_TokenHyperlinkEnd))
,	sTokenBibliographyDataField(RTL_CONSTASCII_USTRINGPARAM(sAPI_TokenBibliographyDataField))

,	sCharacterStyleName(RTL_CONSTASCII_USTRINGPARAM("CharacterStyleName"))
,	sTokenType(RTL_CONSTASCII_USTRINGPARAM("TokenType"))
,	sText(RTL_CONSTASCII_USTRINGPARAM("Text"))
,	sTabStopRightAligned(RTL_CONSTASCII_USTRINGPARAM("TabStopRightAligned"))
,	sTabStopPosition(RTL_CONSTASCII_USTRINGPARAM("TabStopPosition"))
,	sTabStopFillCharacter(RTL_CONSTASCII_USTRINGPARAM("TabStopFillCharacter"))
,	sBibliographyDataField(RTL_CONSTASCII_USTRINGPARAM("BibliographyDataField"))
,	sChapterFormat(RTL_CONSTASCII_USTRINGPARAM("ChapterFormat"))
,   sChapterLevel(RTL_CONSTASCII_USTRINGPARAM("ChapterLevel")) //#i53420

,	sLevelFormat(RTL_CONSTASCII_USTRINGPARAM("LevelFormat"))
,	sParaStyleLevel(RTL_CONSTASCII_USTRINGPARAM("ParaStyleLevel"))
{
	DBG_ASSERT( ((XML_TOKEN_INVALID != eLevelAttrName) &&  (NULL != pLevelNameMap))
				|| ((XML_TOKEN_INVALID == eLevelAttrName) &&  (NULL == pLevelNameMap)),
				"need both, attribute name and value map, or neither" );
	DBG_ASSERT( NULL != pOutlineLevelStylePropMap, "need property name map" );
	DBG_ASSERT( NULL != pAllowedTokenTypes, "need allowed tokens map" );

	// no map for outline-level? then use 1
	if (NULL == pLevelNameMap)
	{
		nOutlineLevel = 1;
		bOutlineLevelOK = sal_True;
	}
}

XMLIndexTemplateContext::~XMLIndexTemplateContext()
{
}


void XMLIndexTemplateContext::addTemplateEntry(
	const PropertyValues& aValues)
{
	aValueVector.push_back(aValues);
}


void XMLIndexTemplateContext::StartElement(
		const Reference<XAttributeList> & xAttrList)
{
	// process two attributes: style-name, outline-level
	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 );
		if (XML_NAMESPACE_TEXT == nPrefix)
		{
			if ( IsXMLToken( sLocalName, XML_STYLE_NAME ) )
			{
				// style name
				sStyleName = xAttrList->getValueByIndex(nAttr);
				bStyleNameOK = sal_True;
			}
			else if (eOutlineLevelAttrName != XML_TOKEN_INVALID)
			{
				// we have an attr name! Then see if we have the attr, too.
				if (IsXMLToken(sLocalName, eOutlineLevelAttrName))
				{
					// outline level
					sal_uInt16 nTmp;
					if (SvXMLUnitConverter::convertEnum(
						nTmp, xAttrList->getValueByIndex(nAttr),
						pOutlineLevelNameMap))
					{
						nOutlineLevel = nTmp;
						bOutlineLevelOK = sal_True;
					}
					// else: illegal value -> ignore
				}
				// else: unknown attribute -> ignore
			}
			// else: we don't care about outline-level -> ignore
		}
		// else: attribute not in text namespace -> ignore
	}
}

void XMLIndexTemplateContext::EndElement()
{
	if (bOutlineLevelOK)
	{
		const sal_Int32 nCount = aValueVector.size();
		Sequence<PropertyValues> aValueSequence(nCount);
		for(sal_Int32 i = 0; i<nCount; i++)
		{
			aValueSequence[i] = aValueVector[i];
		}

		// get LevelFormat IndexReplace ...
		Any aAny = rPropertySet->getPropertyValue(sLevelFormat);
		Reference<XIndexReplace> xIndexReplace;
		aAny >>= xIndexReplace;

		// ... and insert
		aAny <<= aValueSequence;
		xIndexReplace->replaceByIndex(nOutlineLevel, aAny);

		if (bStyleNameOK)
		{
			const sal_Char* pStyleProperty =
				pOutlineLevelStylePropMap[nOutlineLevel];

			DBG_ASSERT(NULL != pStyleProperty, "need property name");
			if (NULL != pStyleProperty)
			{
				OUString sDisplayStyleName =
						GetImport().GetStyleDisplayName(
						XML_STYLE_FAMILY_TEXT_PARAGRAPH,
						sStyleName );
				// #i50288#: Check if style exists
				const Reference < ::com::sun::star::container::XNameContainer > & rStyles =
					GetImport().GetTextImport()->GetParaStyles();
				if( rStyles.is() &&
					rStyles->hasByName( sDisplayStyleName ) )
				{
					aAny <<= sDisplayStyleName;
					rPropertySet->setPropertyValue(
						OUString::createFromAscii(pStyleProperty), aAny);
				}
			}
		}
	}
}



/// template token types; used for aTokenTypeMap parameter
enum TemplateTokenType
{
	XML_TOK_INDEX_TYPE_ENTRY_TEXT = 0,
	XML_TOK_INDEX_TYPE_TAB_STOP,
	XML_TOK_INDEX_TYPE_TEXT,
	XML_TOK_INDEX_TYPE_PAGE_NUMBER,
	XML_TOK_INDEX_TYPE_CHAPTER,
	XML_TOK_INDEX_TYPE_LINK_START,
	XML_TOK_INDEX_TYPE_LINK_END,
	XML_TOK_INDEX_TYPE_BIBLIOGRAPHY
};


SvXMLEnumMapEntry aTemplateTokenTypeMap[] =
{
	{ XML_INDEX_ENTRY_TEXT,         XML_TOK_INDEX_TYPE_ENTRY_TEXT },
	{ XML_INDEX_ENTRY_TAB_STOP,     XML_TOK_INDEX_TYPE_TAB_STOP },
	{ XML_INDEX_ENTRY_SPAN,         XML_TOK_INDEX_TYPE_TEXT },
	{ XML_INDEX_ENTRY_PAGE_NUMBER,  XML_TOK_INDEX_TYPE_PAGE_NUMBER },
	{ XML_INDEX_ENTRY_CHAPTER,      XML_TOK_INDEX_TYPE_CHAPTER },
	{ XML_INDEX_ENTRY_LINK_START,   XML_TOK_INDEX_TYPE_LINK_START },
	{ XML_INDEX_ENTRY_LINK_END,     XML_TOK_INDEX_TYPE_LINK_END },
	{ XML_INDEX_ENTRY_BIBLIOGRAPHY, XML_TOK_INDEX_TYPE_BIBLIOGRAPHY },
	{ XML_TOKEN_INVALID, 0 }
};

SvXMLImportContext *XMLIndexTemplateContext::CreateChildContext(
	sal_uInt16 nPrefix,
	const OUString& rLocalName,
	const Reference<XAttributeList> & xAttrList )
{
	SvXMLImportContext* pContext = NULL;

	if (XML_NAMESPACE_TEXT == nPrefix)
	{
		sal_uInt16 nToken;
		if (SvXMLUnitConverter::convertEnum(nToken, rLocalName,
											aTemplateTokenTypeMap))
		{
			// can this index accept this kind of token?
			if (pAllowedTokenTypesMap[nToken])
			{
				switch ((TemplateTokenType)nToken)
				{
					case XML_TOK_INDEX_TYPE_ENTRY_TEXT:
						pContext = new XMLIndexSimpleEntryContext(
							GetImport(), sTokenEntryText, *this,
							nPrefix, rLocalName);
						break;

					case XML_TOK_INDEX_TYPE_PAGE_NUMBER:
						pContext = new XMLIndexSimpleEntryContext(
							GetImport(), sTokenPageNumber, *this,
							nPrefix, rLocalName);
						break;

					case XML_TOK_INDEX_TYPE_LINK_START:
						pContext = new XMLIndexSimpleEntryContext(
							GetImport(), sTokenHyperlinkStart, *this,
							nPrefix, rLocalName);
						break;

					case XML_TOK_INDEX_TYPE_LINK_END:
						pContext = new XMLIndexSimpleEntryContext(
							GetImport(), sTokenHyperlinkEnd, *this,
							nPrefix, rLocalName);
						break;

					case XML_TOK_INDEX_TYPE_TEXT:
						pContext = new XMLIndexSpanEntryContext(
							GetImport(), *this, nPrefix, rLocalName);
						break;

					case XML_TOK_INDEX_TYPE_TAB_STOP:
						pContext = new XMLIndexTabStopEntryContext(
							GetImport(), *this, nPrefix, rLocalName);
						break;

					case XML_TOK_INDEX_TYPE_BIBLIOGRAPHY:
						pContext = new XMLIndexBibliographyEntryContext(
							GetImport(), *this, nPrefix, rLocalName);
						break;

					case XML_TOK_INDEX_TYPE_CHAPTER:
						pContext = new XMLIndexChapterInfoEntryContext(
							GetImport(), *this, nPrefix, rLocalName, bTOC );
						break;

					default:
						// ignore!
						break;
				}
			}
		}
	}

	// ignore unknown
	if (NULL == pContext)
	{
		return SvXMLImportContext::CreateChildContext(nPrefix, rLocalName,
													  xAttrList);
	}

	return pContext;
}



//
// maps for the XMLIndexTemplateContext constructor
//


// table of content and user defined index:

const SvXMLEnumMapEntry aLevelNameTOCMap[] =
{
	{ XML_1, 1 },
	{ XML_2, 2 },
	{ XML_3, 3 },
	{ XML_4, 4 },
	{ XML_5, 5 },
	{ XML_6, 6 },
	{ XML_7, 7 },
	{ XML_8, 8 },
	{ XML_9, 9 },
	{ XML_10, 10 },
	{ XML_TOKEN_INVALID, 0 }
};

const sal_Char* aLevelStylePropNameTOCMap[] =
	{ NULL, "ParaStyleLevel1", "ParaStyleLevel2", "ParaStyleLevel3",
		  "ParaStyleLevel4", "ParaStyleLevel5", "ParaStyleLevel6",
		  "ParaStyleLevel7", "ParaStyleLevel8", "ParaStyleLevel9",
		  "ParaStyleLevel10", NULL };

const sal_Bool aAllowedTokenTypesTOC[] =
{
	sal_True, 		// XML_TOK_INDEX_TYPE_ENTRY_TEXT =
	sal_True, 		// XML_TOK_INDEX_TYPE_TAB_STOP,
	sal_True, 		// XML_TOK_INDEX_TYPE_TEXT,
	sal_True, 		// XML_TOK_INDEX_TYPE_PAGE_NUMBER,
	sal_True, 		// XML_TOK_INDEX_TYPE_CHAPTER,
	sal_True,	 	// XML_TOK_INDEX_TYPE_LINK_START,
	sal_True, 		// XML_TOK_INDEX_TYPE_LINK_END,
	sal_False		// XML_TOK_INDEX_TYPE_BIBLIOGRAPHY
};

const sal_Bool aAllowedTokenTypesUser[] =
{
	sal_True, 		// XML_TOK_INDEX_TYPE_ENTRY_TEXT =
	sal_True, 		// XML_TOK_INDEX_TYPE_TAB_STOP,
	sal_True, 		// XML_TOK_INDEX_TYPE_TEXT,
	sal_True, 		// XML_TOK_INDEX_TYPE_PAGE_NUMBER,
	sal_True, 		// XML_TOK_INDEX_TYPE_CHAPTER,
	sal_False,	 	// XML_TOK_INDEX_TYPE_LINK_START,
	sal_False, 		// XML_TOK_INDEX_TYPE_LINK_END,
	sal_False		// XML_TOK_INDEX_TYPE_BIBLIOGRAPHY
};


// alphabetical index

const SvXMLEnumMapEntry aLevelNameAlphaMap[] =
{
	{ XML_SEPARATOR, 1 },
	{ XML_1, 2 },
	{ XML_2, 3 },
	{ XML_3, 4 },
	{ XML_TOKEN_INVALID, 0 }
};

const sal_Char* aLevelStylePropNameAlphaMap[] =
	{ NULL, "ParaStyleSeparator", "ParaStyleLevel1", "ParaStyleLevel2",
		  "ParaStyleLevel3", NULL };

const sal_Bool aAllowedTokenTypesAlpha[] =
{
	sal_True, 		// XML_TOK_INDEX_TYPE_ENTRY_TEXT =
	sal_True, 		// XML_TOK_INDEX_TYPE_TAB_STOP,
	sal_True, 		// XML_TOK_INDEX_TYPE_TEXT,
	sal_True, 		// XML_TOK_INDEX_TYPE_PAGE_NUMBER,
	sal_True, 		// XML_TOK_INDEX_TYPE_CHAPTER,
	sal_False,	 	// XML_TOK_INDEX_TYPE_LINK_START,
	sal_False, 		// XML_TOK_INDEX_TYPE_LINK_END,
	sal_False		// XML_TOK_INDEX_TYPE_BIBLIOGRAPHY
};


// bibliography index:

const SvXMLEnumMapEntry aLevelNameBibliographyMap[] =
{
	{ XML_ARTICLE, 1 },
	{ XML_BOOK, 2 },
	{ XML_BOOKLET, 3 },
	{ XML_CONFERENCE, 4 },
	{ XML_CUSTOM1, 5 },
	{ XML_CUSTOM2, 6 },
	{ XML_CUSTOM3, 7 },
	{ XML_CUSTOM4, 8 },
	{ XML_CUSTOM5, 9 },
	{ XML_EMAIL, 10 },
	{ XML_INBOOK, 11 },
	{ XML_INCOLLECTION, 12 },
	{ XML_INPROCEEDINGS, 13 },
	{ XML_JOURNAL, 14 },
	{ XML_MANUAL, 15 },
	{ XML_MASTERSTHESIS, 16 },
	{ XML_MISC, 17 },
	{ XML_PHDTHESIS, 18 },
	{ XML_PROCEEDINGS, 19 },
	{ XML_TECHREPORT, 20 },
	{ XML_UNPUBLISHED, 21 },
	{ XML_WWW, 22 },
    { XML_TOKEN_INVALID, 0 }
};

// TODO: replace with real property names, when available
const sal_Char* aLevelStylePropNameBibliographyMap[] =
{
	NULL, "ParaStyleLevel1", "ParaStyleLevel1", "ParaStyleLevel1",
	"ParaStyleLevel1", "ParaStyleLevel1", "ParaStyleLevel1",
	"ParaStyleLevel1", "ParaStyleLevel1", "ParaStyleLevel1",
	"ParaStyleLevel1", "ParaStyleLevel1", "ParaStyleLevel1",
	"ParaStyleLevel1", "ParaStyleLevel1", "ParaStyleLevel1",
	"ParaStyleLevel1", "ParaStyleLevel1", "ParaStyleLevel1",
	"ParaStyleLevel1", "ParaStyleLevel1", "ParaStyleLevel1",
	"ParaStyleLevel1", NULL };

const sal_Bool aAllowedTokenTypesBibliography[] =
{
	sal_True, 		// XML_TOK_INDEX_TYPE_ENTRY_TEXT =
	sal_True, 		// XML_TOK_INDEX_TYPE_TAB_STOP,
	sal_True, 		// XML_TOK_INDEX_TYPE_TEXT,
	sal_True, 		// XML_TOK_INDEX_TYPE_PAGE_NUMBER,
	sal_False, 		// XML_TOK_INDEX_TYPE_CHAPTER,
	sal_False,	 	// XML_TOK_INDEX_TYPE_LINK_START,
	sal_False, 		// XML_TOK_INDEX_TYPE_LINK_END,
	sal_True		// XML_TOK_INDEX_TYPE_BIBLIOGRAPHY
};


// table, illustration and object index

// no name map
const SvXMLEnumMapEntry* aLevelNameTableMap = NULL;

const sal_Char* aLevelStylePropNameTableMap[] =
	{ NULL, "ParaStyleLevel1", NULL };

const sal_Bool aAllowedTokenTypesTable[] =
{
	sal_True, 		// XML_TOK_INDEX_TYPE_ENTRY_TEXT =
	sal_True, 		// XML_TOK_INDEX_TYPE_TAB_STOP,
	sal_True, 		// XML_TOK_INDEX_TYPE_TEXT,
	sal_True, 		// XML_TOK_INDEX_TYPE_PAGE_NUMBER,
	sal_True, 		// XML_TOK_INDEX_TYPE_CHAPTER,
	sal_False,	 	// XML_TOK_INDEX_TYPE_LINK_START,
	sal_False, 		// XML_TOK_INDEX_TYPE_LINK_END,
	sal_False		// XML_TOK_INDEX_TYPE_BIBLIOGRAPHY
};
