/**************************************************************
 * 
 * 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_framework.hxx"

#include <framework/fwedllapi.h>
#include <stdio.h>

//_________________________________________________________________________________________________________________
//	my own includes
//_________________________________________________________________________________________________________________

#include <threadhelp/resetableguard.hxx>
#include <xml/eventsdocumenthandler.hxx>
#include <macros/debug.hxx>

//_________________________________________________________________________________________________________________
//	interface includes
//_________________________________________________________________________________________________________________

#ifndef __COM_SUN_STAR_XML_SAX_XEXTENDEDDOCUMENTHANDLER_HPP_
#include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
#endif

//_________________________________________________________________________________________________________________
//	other includes
//_________________________________________________________________________________________________________________

#include <sal/config.h>
#include <vcl/svapp.hxx>
#include <vcl/toolbox.hxx>

#include <comphelper/attributelist.hxx>

//_________________________________________________________________________________________________________________
//	namespace
//_________________________________________________________________________________________________________________

using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::xml::sax;


#define XMLNS_EVENT				"http://openoffice.org/2001/event"
#define XMLNS_XLINK				"http://www.w3.org/1999/xlink"
#define XMLNS_EVENT_PREFIX		"event:"
#define XMLNS_XLINK_PREFIX		"xlink:"

#define ATTRIBUTE_XMLNS_EVENT	"xmlns:event"
#define ATTRIBUTE_XMLNS_XLINK	"xmlns:xlink"

#define XMLNS_FILTER_SEPARATOR	"^"

#define ELEMENT_EVENTS			"events"
#define ELEMENT_EVENT			"event"

#define ATTRIBUTE_LANGUAGE		"language"
#define ATTRIBUTE_LIBRARY		"library"
#define ATTRIBUTE_NAME			"name"
#define ATTRIBUTE_HREF			"href"
#define ATTRIBUTE_TYPE			"type"
#define ATTRIBUTE_MACRONAME		"macro-name"

#define ELEMENT_NS_EVENTS		"event:events"
#define ELEMENT_NS_EVENT		"event:event"

#define ATTRIBUTE_TYPE_CDATA	"CDATA"

#define EVENTS_DOCTYPE			"<!DOCTYPE event:events PUBLIC \"-//OpenOffice.org//DTD OfficeDocument 1.0//EN\" \"event.dtd\">"

// Property names for events
#define	PROP_EVENT_TYPE		"EventType"
#define PROP_LIBRARY		"Library"
#define PROP_SCRIPT			"Script"
#define PROP_MACRO_NAME		"MacroName"
#define STAR_BASIC			"StarBasic"
#define JAVA_SCRIPT			"JavaScript"


namespace framework
{

struct EventEntryProperty
{
	OReadEventsDocumentHandler::Event_XML_Namespace	nNamespace;
	char											aEntryName[20];
};

static EventEntryProperty EventEntries[OReadEventsDocumentHandler::EV_XML_ENTRY_COUNT] =
{
	{ OReadEventsDocumentHandler::EV_NS_EVENT,	ELEMENT_EVENTS			},
	{ OReadEventsDocumentHandler::EV_NS_EVENT,	ELEMENT_EVENT			},
	{ OReadEventsDocumentHandler::EV_NS_EVENT,	ATTRIBUTE_LANGUAGE		},
	{ OReadEventsDocumentHandler::EV_NS_EVENT,	ATTRIBUTE_NAME			},
	{ OReadEventsDocumentHandler::EV_NS_XLINK,	ATTRIBUTE_HREF			},
	{ OReadEventsDocumentHandler::EV_NS_XLINK,	ATTRIBUTE_TYPE			},
	{ OReadEventsDocumentHandler::EV_NS_EVENT,	ATTRIBUTE_MACRONAME		},
	{ OReadEventsDocumentHandler::EV_NS_EVENT,	ATTRIBUTE_LIBRARY		}
};


OReadEventsDocumentHandler::OReadEventsDocumentHandler( EventsConfig& aItems ) :
	ThreadHelpBase( &Application::GetSolarMutex() ),
	m_aEventItems( aItems )
{
	::rtl::OUString aNamespaceEvent( RTL_CONSTASCII_USTRINGPARAM( XMLNS_EVENT ));
	::rtl::OUString aNamespaceXLink( RTL_CONSTASCII_USTRINGPARAM( XMLNS_XLINK ));
	::rtl::OUString aSeparator( RTL_CONSTASCII_USTRINGPARAM( XMLNS_FILTER_SEPARATOR ));

	// create hash map
	for ( int i = 0; i < (int)EV_XML_ENTRY_COUNT; i++ )
	{
		if ( EventEntries[i].nNamespace == EV_NS_EVENT )
		{
			::rtl::OUString temp( aNamespaceEvent );
			temp += aSeparator;
			temp += ::rtl::OUString::createFromAscii( EventEntries[i].aEntryName );
			m_aEventsMap.insert( EventsHashMap::value_type( temp, (Events_XML_Entry)i ) );
		}
		else
		{
			::rtl::OUString temp( aNamespaceXLink );
			temp += aSeparator;
			temp += ::rtl::OUString::createFromAscii( EventEntries[i].aEntryName );
			m_aEventsMap.insert( EventsHashMap::value_type( temp, (Events_XML_Entry)i ) );
		}
	}

	m_bEventsStartFound				= sal_False;
	m_bEventsEndFound				= sal_False;
	m_bEventStartFound				= sal_False;
}

OReadEventsDocumentHandler::~OReadEventsDocumentHandler()
{
}

// XDocumentHandler
void SAL_CALL OReadEventsDocumentHandler::startDocument(void)
throw (	SAXException, RuntimeException )
{
}

void SAL_CALL OReadEventsDocumentHandler::endDocument(void)
throw(	SAXException, RuntimeException )
{
	ResetableGuard aGuard( m_aLock );

	if (( m_bEventsStartFound && !m_bEventsEndFound ) ||
		( !m_bEventsStartFound && m_bEventsEndFound )		)
	{
		::rtl::OUString aErrorMessage = getErrorLineString();
		aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "No matching start or end element 'event:events' found!" ));
		throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
	}
}

void SAL_CALL OReadEventsDocumentHandler::startElement(
	const ::rtl::OUString& aName, const Reference< XAttributeList > &xAttribs )
throw(	SAXException, RuntimeException )
{
	ResetableGuard aGuard( m_aLock );

	EventsHashMap::const_iterator pEventEntry = m_aEventsMap.find( aName );
	if ( pEventEntry != m_aEventsMap.end() )
	{
		switch ( pEventEntry->second )
		{
			case EV_ELEMENT_EVENTS:
			{
				if ( m_bEventsStartFound )
				{
					::rtl::OUString aErrorMessage = getErrorLineString();
					aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'event:events' cannot be embeded into 'event:events'!" ));
					throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
				}

				m_bEventsStartFound = sal_True;
			}
			break;

			case EV_ELEMENT_EVENT:
			{
				if ( !m_bEventsStartFound )
				{
					::rtl::OUString aErrorMessage = getErrorLineString();
					aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'event:event' must be embeded into element 'event:events'!" ));
					throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
				}

				if ( m_bEventStartFound )
				{
					::rtl::OUString aErrorMessage = getErrorLineString();
					aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element event:event is not a container!" ));
					throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
				}

				::rtl::OUString aLanguage;
				::rtl::OUString aURL;
				::rtl::OUString aMacroName;
				::rtl::OUString aLibrary;
				::rtl::OUString aEventName;

				m_bEventStartFound = sal_True;

				long					  nIndex = m_aEventItems.aEventNames.getLength();
				long					  nPropCount = 2; // every event config entry needs at least 2 properties
				Sequence< PropertyValue > aEventProperties( nPropCount );

				m_aEventItems.aEventNames.realloc(  nIndex + 1 );

				for ( sal_Int16 n = 0; n < xAttribs->getLength(); n++ )
				{
					pEventEntry = m_aEventsMap.find( xAttribs->getNameByIndex( n ) );
					if ( pEventEntry != m_aEventsMap.end() )
					{
						switch ( pEventEntry->second )
						{
							case EV_ATTRIBUTE_TYPE:
							{
								aLanguage = xAttribs->getValueByIndex( n );
							}
							break;

							case EV_ATTRIBUTE_NAME:
							{
								aEventName = xAttribs->getValueByIndex( n );
							}
							break;

							case XL_ATTRIBUTE_HREF:
							{
								aURL = xAttribs->getValueByIndex( n );
							}
							break;

							case EV_ATTRIBUTE_MACRONAME:
							{
								aMacroName = xAttribs->getValueByIndex( n );
							}
							break;

							case EV_ATTRIBUTE_LIBRARY:
							{
								aLibrary = xAttribs->getValueByIndex( n );
							}
							break;

                                          default:
                                              break; // nothing to do
						}
					}
				} // for

				::rtl::OUString aRequiredAttributeName;
				if ( aLanguage.getLength() == 0 )
					aRequiredAttributeName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_TYPE ));
				else if ( aEventName.getLength() == 0 )
					aRequiredAttributeName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_NAME ));

				// check for missing attribute values
				if ( aRequiredAttributeName.getLength() > 0 )
				{
					::rtl::OUString aErrorMessage = getErrorLineString();
					aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Required attribute "));
					aErrorMessage += aRequiredAttributeName;
					aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " must have a value!" ));
					throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
				}

				Any a;

				// set properties
				a <<= aLanguage;
				aEventProperties[0].Value <<= a;
				aEventProperties[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( PROP_EVENT_TYPE ));

				a <<= aMacroName;
				aEventProperties[1].Value <<= a;
				aEventProperties[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( PROP_MACRO_NAME ));

				if ( aLibrary.getLength() > 0 )
				{
					++nPropCount;
					aEventProperties.realloc( nPropCount );
					a <<= aLibrary;
					aEventProperties[nPropCount-1].Value <<= a;
					aEventProperties[nPropCount-1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( PROP_LIBRARY ));
				}

				if ( aURL.getLength() > 0 )
				{
					++nPropCount;
					aEventProperties.realloc( nPropCount );
					a <<= aURL;
					aEventProperties[nPropCount-1].Value <<= a;
					aEventProperties[nPropCount-1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( PROP_SCRIPT ));
				}

				// set event name
				m_aEventItems.aEventNames[ nIndex ] = aEventName;

				m_aEventItems.aEventsProperties.realloc( nIndex + 1 );
				a <<= aEventProperties;
				m_aEventItems.aEventsProperties[ nIndex ] = a;
			}
			break;

                  default:
                      break;
		}
	}
}

void SAL_CALL OReadEventsDocumentHandler::endElement(const ::rtl::OUString& aName)
throw(	SAXException, RuntimeException )
{
	ResetableGuard aGuard( m_aLock );

	EventsHashMap::const_iterator pEventEntry = m_aEventsMap.find( aName );
	if ( pEventEntry != m_aEventsMap.end() )
	{
		switch ( pEventEntry->second )
		{
			case EV_ELEMENT_EVENTS:
			{
				if ( !m_bEventsStartFound )
				{
					::rtl::OUString aErrorMessage = getErrorLineString();
					aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "End element 'event:events' found, but no start element" ));
					throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
				}

				m_bEventsStartFound = sal_False;
			}
			break;

			case EV_ELEMENT_EVENT:
			{
				if ( !m_bEventStartFound )
				{
					::rtl::OUString aErrorMessage = getErrorLineString();
					aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "End element 'event:event' found, but no start element" ));
					throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
				}

				m_bEventStartFound = sal_False;
			}
			break;

                  default:
                      break; // impossible case
		}
	}
}

void SAL_CALL OReadEventsDocumentHandler::characters(const ::rtl::OUString&)
throw(	SAXException, RuntimeException )
{
}

void SAL_CALL OReadEventsDocumentHandler::ignorableWhitespace(const ::rtl::OUString&)
throw(	SAXException, RuntimeException )
{
}

void SAL_CALL OReadEventsDocumentHandler::processingInstruction(
	const ::rtl::OUString& /*aTarget*/, const ::rtl::OUString& /*aData*/ )
throw(	SAXException, RuntimeException )
{
}

void SAL_CALL OReadEventsDocumentHandler::setDocumentLocator(
	const Reference< XLocator > &xLocator)
throw(	SAXException, RuntimeException )
{
	ResetableGuard aGuard( m_aLock );

	m_xLocator = xLocator;
}

::rtl::OUString OReadEventsDocumentHandler::getErrorLineString()
{
	ResetableGuard aGuard( m_aLock );

	char buffer[32];

	if ( m_xLocator.is() )
	{
		snprintf( buffer, sizeof(buffer), "Line: %ld - ", static_cast<long>(m_xLocator->getLineNumber() ));
		return ::rtl::OUString::createFromAscii( buffer );
	}
	else
		return ::rtl::OUString();
}


//_________________________________________________________________________________________________________________
//	OWriteEventsDocumentHandler
//_________________________________________________________________________________________________________________

OWriteEventsDocumentHandler::OWriteEventsDocumentHandler(
	const EventsConfig& aItems,
	Reference< XDocumentHandler > rWriteDocumentHandler ) :
    ThreadHelpBase( &Application::GetSolarMutex() ),
	m_aItems( aItems ),
	m_xWriteDocumentHandler( rWriteDocumentHandler )
{
    ::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
	m_xEmptyList		= Reference< XAttributeList >( (XAttributeList *) pList, UNO_QUERY );
	m_aAttributeType	= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_TYPE_CDATA ));
	m_aXMLXlinkNS		= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_XLINK_PREFIX ));
	m_aXMLEventNS		= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_EVENT_PREFIX ));
}

OWriteEventsDocumentHandler::~OWriteEventsDocumentHandler()
{
}

void OWriteEventsDocumentHandler::WriteEventsDocument() throw
( SAXException, RuntimeException )
{
	ResetableGuard aGuard( m_aLock );

	m_xWriteDocumentHandler->startDocument();

	// write DOCTYPE line!
	Reference< XExtendedDocumentHandler > xExtendedDocHandler( m_xWriteDocumentHandler, UNO_QUERY );
	if ( xExtendedDocHandler.is() )
	{
		xExtendedDocHandler->unknown( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( EVENTS_DOCTYPE )) );
		m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
	}

	::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
	Reference< XAttributeList > xList( (XAttributeList *) pList , UNO_QUERY );

	pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_XMLNS_EVENT )),
						 m_aAttributeType,
						 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_EVENT )) );
	pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_XMLNS_XLINK )),
						 m_aAttributeType,
						 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_XLINK )) );

	m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_EVENTS )), pList );
	m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );

	Sequence< PropertyValue > aEventProperties;

	for ( int i = 0; i < m_aItems.aEventNames.getLength(); i++ )
	{
		if ( m_aItems.aEventsProperties[i] >>= aEventProperties )
			WriteEvent( m_aItems.aEventNames[i], aEventProperties );
	}

	m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
	m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_EVENTS )) );

	m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
	m_xWriteDocumentHandler->endDocument();
}

//_________________________________________________________________________________________________________________
//	protected member functions
//_________________________________________________________________________________________________________________

void OWriteEventsDocumentHandler::WriteEvent( const ::rtl::OUString& aEventName, const Sequence< PropertyValue >& aPropertyValues ) throw
( SAXException, RuntimeException )
{
	if ( aPropertyValues.getLength() > 0 )
	{
		::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
		Reference< XAttributeList > xList( (XAttributeList *) pList , UNO_QUERY );

		if ( m_aAttributeURL.getLength() == 0 )
		{
			m_aAttributeURL = m_aXMLXlinkNS;
			m_aAttributeURL += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_HREF ));
			m_aAttributeLinkType = m_aXMLXlinkNS;
			m_aAttributeLinkType += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_TYPE ));
			m_aAttributeLanguage = m_aXMLEventNS;
			m_aAttributeLanguage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_LANGUAGE ));
			m_aAttributeMacroName = m_aXMLEventNS;
			m_aAttributeMacroName += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_MACRONAME ));
			m_aAttributeLibrary = m_aXMLEventNS;
			m_aAttributeLibrary += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_LIBRARY ));
			m_aAttributeName = m_aXMLEventNS;
			m_aAttributeName += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_NAME ));
		}

		pList->AddAttribute( m_aAttributeName, m_aAttributeType, aEventName );

		sal_Bool	bURLSet = sal_False;
		::rtl::OUString	aValue;
		::rtl::OUString	aName;

		// save attributes
		for ( int i = 0; i < aPropertyValues.getLength(); i++ )
		{
			aPropertyValues[i].Value >>= aValue;
			if ( aPropertyValues[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( PROP_EVENT_TYPE )))
				pList->AddAttribute( m_aAttributeLanguage, m_aAttributeType, aValue );
			else if ( aPropertyValues[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( PROP_MACRO_NAME )) &&
					  aValue.getLength() > 0 )
				pList->AddAttribute( m_aAttributeMacroName, m_aAttributeType, aValue );
			else if ( aPropertyValues[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( PROP_LIBRARY )) &&
					  aValue.getLength() > 0 )
				pList->AddAttribute( m_aAttributeLibrary, m_aAttributeType, aValue );
			else if ( aPropertyValues[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( PROP_SCRIPT )))
			{
				pList->AddAttribute( m_aAttributeURL, m_aAttributeType, aValue );
				bURLSet = sal_True;
			}
		}

		if ( bURLSet )
			pList->AddAttribute( m_aAttributeLinkType, m_aAttributeType, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "simple" )) );

		m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_EVENT )), xList );
		m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );

		m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_EVENT )) );
		m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
	}
}

} // namespace framework

