/**************************************************************
 * 
 * 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 <xmloff/XMLEventsImportContext.hxx>

#ifndef _XMLOFF_XMLEVENTIMPORTHELPER_HXX
#include "XMLEventImportHelper.hxx"
#endif

#ifndef _COM_SUN_STAR_DOCUMENT_XEVENTSSUPPLIER_HPP
#include <com/sun/star/document/XEventsSupplier.hpp>
#endif
#include <tools/debug.hxx>
#include <xmloff/xmlimp.hxx>
#include <xmloff/nmspmap.hxx>
#include "xmloff/xmlnmspe.hxx"
#include <xmloff/xmltoken.hxx>
#include "xmloff/xmlerror.hxx"

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

using ::rtl::OUString;
using ::com::sun::star::xml::sax::XAttributeList;
using ::com::sun::star::beans::PropertyValue;
using ::com::sun::star::container::XNameReplace;
using ::com::sun::star::document::XEventsSupplier;
using ::com::sun::star::lang::IllegalArgumentException;

TYPEINIT1(XMLEventsImportContext,  SvXMLImportContext);


XMLEventsImportContext::XMLEventsImportContext(
	SvXMLImport& rImport, 
	sal_uInt16 nPrfx,
	const OUString& rLocalName) :
		SvXMLImportContext(rImport, nPrfx, rLocalName)
{
}


XMLEventsImportContext::XMLEventsImportContext(
	SvXMLImport& rImport, 
	sal_uInt16 nPrfx,
	const OUString& rLocalName,
	const Reference<XEventsSupplier> & xEventsSupplier) :
		SvXMLImportContext(rImport, nPrfx, rLocalName),
		xEvents(xEventsSupplier->getEvents())
{
}


XMLEventsImportContext::XMLEventsImportContext(
	SvXMLImport& rImport, 
	sal_uInt16 nPrfx,
	const OUString& rLocalName,
	const Reference<XNameReplace> & xNameReplace) :
		SvXMLImportContext(rImport, nPrfx, rLocalName),
		xEvents(xNameReplace)
{
}

XMLEventsImportContext::~XMLEventsImportContext()
{
// 	// if, for whatever reason, the object gets destroyed prematurely,
// 	// we need to delete the collected events
// 	EventsVector::iterator aEnd = aCollectEvents.end();
// 	for(EventsVector::iterator aIter = aCollectEvents.begin();
// 		aIter != aEnd;
// 		aIter++)
// 	{
// 		EventNameValuesPair* pPair = &(*aIter);
// 		delete pPair;
// 	}
// 	aCollectEvents.clear();
}


void XMLEventsImportContext::StartElement(
	const Reference<XAttributeList> &)
{
	// nothing to be done
}

void XMLEventsImportContext::EndElement()
{
	// nothing to be done
}

SvXMLImportContext* XMLEventsImportContext::CreateChildContext( 
	sal_uInt16 p_nPrefix,
	const OUString& rLocalName,
	const Reference<XAttributeList> & xAttrList )
{
	// a) search for script:language and script:event-name attribute
	// b) delegate to factory. The factory will:
	//    1) translate XML event name into API event name
	//    2) get proper event context factory from import
	//    3) instantiate context

	// a) search for script:language and script:event-name attribute
	OUString sLanguage;
	OUString sEventName;
	sal_Int16 nCount = xAttrList->getLength();
	for (sal_Int16 nAttr = 0; nAttr < nCount; nAttr++)
	{
		OUString sLocalName;
		sal_uInt16 nPrefix = GetImport().GetNamespaceMap().
			GetKeyByAttrName( xAttrList->getNameByIndex(nAttr), &sLocalName );

		if (XML_NAMESPACE_SCRIPT == nPrefix)
		{
			if (IsXMLToken(sLocalName, XML_EVENT_NAME))
			{
				sEventName = xAttrList->getValueByIndex(nAttr);
			}
			else if (IsXMLToken(sLocalName, XML_LANGUAGE))
			{
				sLanguage = xAttrList->getValueByIndex(nAttr);
			}
			// else: ignore -> let child context handle this
		}
		// else: ignore -> let child context handle this
	}

	// b) delegate to factory
	return GetImport().GetEventImport().CreateContext(
		GetImport(), p_nPrefix, rLocalName, xAttrList, 
		this, sEventName, sLanguage);
}

void XMLEventsImportContext::SetEvents(
	const Reference<XEventsSupplier> & xEventsSupplier)
{
	if (xEventsSupplier.is())
	{
		SetEvents(xEventsSupplier->getEvents());
	}
}

void XMLEventsImportContext::SetEvents(
	const Reference<XNameReplace> & xNameRepl)
{
	if (xNameRepl.is())
	{
		xEvents = xNameRepl;

		// now iterate over vector and a) insert b) delete all elements
		EventsVector::iterator aEnd = aCollectEvents.end();
		for(EventsVector::iterator aIter = aCollectEvents.begin();
			aIter != aEnd;
			aIter++)
		{
			AddEventValues(aIter->first, aIter->second);
// 			EventNameValuesPair* pPair = &(*aIter);
// 			delete pPair;
		}
		aCollectEvents.clear();
	}
}

sal_Bool XMLEventsImportContext::GetEventSequence(
    const OUString& rName,
    Sequence<PropertyValue> & rSequence )
{
    // search through the vector
    // (This shouldn't take a lot of time, since this method should only get
    //  called if only one (or few) events are being expected)

    // iterate over vector until end or rName is found;
    EventsVector::iterator aIter = aCollectEvents.begin();
    while( (aIter != aCollectEvents.end()) && (aIter->first != rName) )
    {
        aIter++;
    }
    
    // if we're not at the end, set the sequence
    sal_Bool bRet = (aIter != aCollectEvents.end());
    if (bRet)
        rSequence = aIter->second;

    return bRet;
}

void XMLEventsImportContext::AddEventValues( 
	const OUString& rEventName,
	const Sequence<PropertyValue> & rValues )
{
	// if we already have the events, set them; else just collect
	if (xEvents.is())
	{
		// set event (if name is known)
		if (xEvents->hasByName(rEventName))
		{
			Any aAny;
			aAny <<= rValues;
            
            try
            {
                xEvents->replaceByName(rEventName, aAny);
            } catch ( const IllegalArgumentException & rException )
            {
                Sequence<OUString> aMsgParams(1);

                aMsgParams[0] = rEventName;
                
                GetImport().SetError(XMLERROR_FLAG_ERROR | 
                                     XMLERROR_ILLEGAL_EVENT,
                                     aMsgParams, rException.Message, 0);
            }
		}
	}
	else
	{
// 		EventNameValuesPair* aPair = new EventNameValuesPair(rEventName, 
// 															rValues);
// 		aCollectEvents.push_back(*aPair);
		EventNameValuesPair aPair(rEventName, rValues);
		aCollectEvents.push_back(aPair);
	}
}
