/**************************************************************
 *
 * 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 "EventOASISTContext.hxx"
#include "EventMap.hxx"
#include "MutableAttrList.hxx"
#include "xmloff/xmlnmspe.hxx"
#include "ActionMapTypesOASIS.hxx"
#include "AttrTransformerAction.hxx"
#include "TransformerActions.hxx"
#ifndef _XMLOFF_TRANSFORMERBASE_HXX
#include "TransformerBase.hxx"
#endif

#ifndef OASIS_FILTER_OOO_1X
// Used to parse Scripting Framework URLs
#include <com/sun/star/uri/XUriReferenceFactory.hpp>
#include <com/sun/star/uri/XVndSunStarScriptUrl.hpp>
#include <comphelper/processfactory.hxx>
#endif

#include <hash_map>

using ::rtl::OUString;

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

class XMLTransformerOASISEventMap_Impl:
	public ::std::hash_map< NameKey_Impl, ::rtl::OUString,
						    NameHash_Impl, NameHash_Impl >
{
public:
	XMLTransformerOASISEventMap_Impl( XMLTransformerEventMapEntry *pInit );
	~XMLTransformerOASISEventMap_Impl();
};

XMLTransformerOASISEventMap_Impl::XMLTransformerOASISEventMap_Impl( XMLTransformerEventMapEntry *pInit )
{
	if( pInit )
	{
		XMLTransformerOASISEventMap_Impl::key_type aKey;
		XMLTransformerOASISEventMap_Impl::mapped_type aData;
		while( pInit->m_pOASISName )
		{
			aKey.m_nPrefix = pInit->m_nOASISPrefix;
			aKey.m_aLocalName = OUString::createFromAscii(pInit->m_pOASISName);

			OSL_ENSURE( find( aKey ) == end(), "duplicate event map entry" );

			aData = OUString::createFromAscii(pInit->m_pOOoName);

			XMLTransformerOASISEventMap_Impl::value_type aVal( aKey, aData );

			insert( aVal );
			++pInit;
		}
	}
}

XMLTransformerOASISEventMap_Impl::~XMLTransformerOASISEventMap_Impl()
{
}

// -----------------------------------------------------------------------------

TYPEINIT1( XMLEventOASISTransformerContext, XMLRenameElemTransformerContext);

XMLEventOASISTransformerContext::XMLEventOASISTransformerContext(
		XMLTransformerBase& rImp,
		const OUString& rQName ) :
	XMLRenameElemTransformerContext( rImp, rQName,
		 rImp.GetNamespaceMap().GetKeyByAttrName( rQName ), XML_EVENT )
{
}

XMLEventOASISTransformerContext::~XMLEventOASISTransformerContext()
{
}

XMLTransformerOASISEventMap_Impl
	*XMLEventOASISTransformerContext::CreateEventMap()
{
	return new XMLTransformerOASISEventMap_Impl( aTransformerEventMap );
}

XMLTransformerOASISEventMap_Impl
	*XMLEventOASISTransformerContext::CreateFormEventMap()
{
	return new XMLTransformerOASISEventMap_Impl( aFormTransformerEventMap );
}

void XMLEventOASISTransformerContext::FlushEventMap(
		XMLTransformerOASISEventMap_Impl *p )
{
	delete p;
}

OUString XMLEventOASISTransformerContext::GetEventName(
		sal_uInt16 nPrefix,
		const OUString& rName,
	   	XMLTransformerOASISEventMap_Impl& rMap,
	   	XMLTransformerOASISEventMap_Impl *pMap2)
{
	XMLTransformerOASISEventMap_Impl::key_type aKey( nPrefix, rName );
	if( pMap2 )
	{
		XMLTransformerOASISEventMap_Impl::const_iterator aIter =
			pMap2->find( aKey );
		if( !(aIter == pMap2->end()) )
			return (*aIter).second;
	}

	XMLTransformerOASISEventMap_Impl::const_iterator aIter = rMap.find( aKey );
	if( aIter == rMap.end() )
		return rName;
	else
		return (*aIter).second;
}

bool ParseURLAsString(
	const OUString& rAttrValue,
	OUString* pName, OUString* pLocation )
{
	OUString SCHEME( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.script:" ) );

	sal_Int32 params = rAttrValue.indexOf( '?' );
	if ( rAttrValue.indexOf( SCHEME ) != 0 || params < 0 )
	{
		return sal_False;
	}

	sal_Int32 start = SCHEME.getLength();
	*pName = rAttrValue.copy( start, params - start );

	OUString aToken;
	OUString aLanguage;
	params++;
	do
	{
		aToken = rAttrValue.getToken( 0, '&', params );
		sal_Int32 dummy = 0;

		if ( aToken.match( GetXMLToken( XML_LANGUAGE ) ) )
		{
			aLanguage = aToken.getToken( 1, '=', dummy );
		}
		else if ( aToken.match( GetXMLToken( XML_LOCATION ) ) )
		{
			OUString tmp = aToken.getToken( 1, '=', dummy );
			if ( tmp.equalsIgnoreAsciiCase( GetXMLToken( XML_DOCUMENT ) ) )
			{
				*pLocation = GetXMLToken( XML_DOCUMENT );
			}
			else
			{
				*pLocation = GetXMLToken( XML_APPLICATION );
			}
		}
	} while ( params >= 0 );

	if ( aLanguage.equalsIgnoreAsciiCaseAscii( "basic" ) )
	{
		return sal_True;
	}
	return sal_False;
}

bool ParseURL(
	const OUString& rAttrValue,
	OUString* pName, OUString* pLocation )
{
#ifdef OASIS_FILTER_OOO_1X
	return ParseURLAsString( rAttrValue, pName, pLocation );
#else
	Reference< com::sun::star::lang::XMultiServiceFactory >
		xSMgr = ::comphelper::getProcessServiceFactory();

	Reference< com::sun::star::uri::XUriReferenceFactory >
		xFactory( xSMgr->createInstance( OUString::createFromAscii(
			"com.sun.star.uri.UriReferenceFactory" ) ), UNO_QUERY );

	if ( xFactory.is() )
	{
		Reference< com::sun::star::uri::XVndSunStarScriptUrl > xUrl (
			xFactory->parse( rAttrValue ), UNO_QUERY );

		if ( xUrl.is() )
		{
			OUString aLanguageKey = GetXMLToken( XML_LANGUAGE );
			if ( xUrl.is() && xUrl->hasParameter( aLanguageKey ) )
			{
				OUString aLanguage = xUrl->getParameter( aLanguageKey );

				if ( aLanguage.equalsIgnoreAsciiCaseAscii( "basic" ) )
				{
					*pName = xUrl->getName();

					OUString tmp =
						xUrl->getParameter( GetXMLToken( XML_LOCATION ) );

					OUString doc = GetXMLToken( XML_DOCUMENT );

					if ( tmp.equalsIgnoreAsciiCase( doc ) )
					{
						*pLocation = doc;
					}
					else
					{
						*pLocation = GetXMLToken( XML_APPLICATION );
					}
					return sal_True;
				}
			}
		}
		return sal_False;
	}
	else
	{
		return ParseURLAsString( rAttrValue, pName, pLocation );
	}
#endif
}

void XMLEventOASISTransformerContext::StartElement(
	const Reference< XAttributeList >& rAttrList )
{
	OSL_TRACE("XMLEventOASISTransformerContext::StartElement");

	XMLTransformerActions *pActions =
		GetTransformer().GetUserDefinedActions( OASIS_EVENT_ACTIONS );
	OSL_ENSURE( pActions, "go no actions" );

	Reference< XAttributeList > xAttrList( rAttrList );
	XMLMutableAttributeList *pMutableAttrList = 0;
	sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
	for( sal_Int16 i=0; i < nAttrCount; i++ )
	{
		const OUString& rAttrName = xAttrList->getNameByIndex( i );
		OUString aLocalName;
		sal_uInt16 nPrefix =
			GetTransformer().GetNamespaceMap().GetKeyByAttrName( rAttrName,
																 &aLocalName );
		XMLTransformerActions::key_type aKey( nPrefix, aLocalName );
		XMLTransformerActions::const_iterator aIter =
			pActions->find( aKey );
		if( !(aIter == pActions->end() ) )
		{
			if( !pMutableAttrList )
			{
				pMutableAttrList =
						new XMLMutableAttributeList( xAttrList );
				xAttrList = pMutableAttrList;
			}
			const OUString& rAttrValue = xAttrList->getValueByIndex( i );
			switch( (*aIter).second.m_nActionType )
			{
			case XML_ATACTION_HREF:
				{
					OUString aAttrValue( rAttrValue );
					OUString aName, aLocation;

					bool bNeedsTransform =
						ParseURL( rAttrValue, &aName, &aLocation );

					if ( bNeedsTransform )
					{
						pMutableAttrList->RemoveAttributeByIndex( i );

						OUString aAttrQName(
							GetTransformer().GetNamespaceMap().GetQNameByKey(
								XML_NAMESPACE_SCRIPT,
							::xmloff::token::GetXMLToken( XML_MACRO_NAME ) ) );

						pMutableAttrList->AddAttribute( aAttrQName, aName );

						sal_Int16 idx = pMutableAttrList->GetIndexByName(
							GetTransformer().GetNamespaceMap().GetQNameByKey(
								XML_NAMESPACE_SCRIPT,
							GetXMLToken( XML_LANGUAGE ) ) );

						pMutableAttrList->SetValueByIndex( idx,
							OUString::createFromAscii("StarBasic") );

						OUString aLocQName(
							GetTransformer().GetNamespaceMap().GetQNameByKey(
								XML_NAMESPACE_SCRIPT,
								GetXMLToken( XML_LOCATION ) ) );

						pMutableAttrList->AddAttribute( aLocQName, aLocation );
					}
				}
				break;
			case XML_ATACTION_EVENT_NAME:
				{
					// Check if the event belongs to a form or control by
					// checking the 2nd ancestor element, f.i.:
					// <form:button><form:event-listeners><form:event-listener>
					const XMLTransformerContext *pObjContext =
						GetTransformer().GetAncestorContext( 1 );
					sal_Bool bForm = pObjContext &&

						pObjContext->HasNamespace(XML_NAMESPACE_FORM );
					pMutableAttrList->SetValueByIndex( i,
								   GetTransformer().GetEventName( rAttrValue,
									  							  bForm ) );
				}
				break;
			case XML_ATACTION_REMOVE_NAMESPACE_PREFIX:
				{
					OUString aAttrValue( rAttrValue );
					sal_uInt16 nValPrefix =
						static_cast<sal_uInt16>((*aIter).second.m_nParam1);
					if( GetTransformer().RemoveNamespacePrefix(
								aAttrValue, nValPrefix ) )
						pMutableAttrList->SetValueByIndex( i, aAttrValue );
				}
				break;
			case XML_ATACTION_MACRO_NAME:
            {
                OUString aName, aLocation;
                bool bNeedsTransform =
                ParseURL( rAttrValue, &aName, &aLocation );

                if ( bNeedsTransform )
                {
                    pMutableAttrList->SetValueByIndex( i, aName );

                    sal_Int16 idx = pMutableAttrList->GetIndexByName(
                    GetTransformer().GetNamespaceMap().GetQNameByKey(
                    XML_NAMESPACE_SCRIPT,
                    GetXMLToken( XML_LANGUAGE ) ) );

                    pMutableAttrList->SetValueByIndex( idx,
                    OUString::createFromAscii("StarBasic") );

                    OUString aLocQName(
                    GetTransformer().GetNamespaceMap().GetQNameByKey(
                    XML_NAMESPACE_SCRIPT,
                    GetXMLToken( XML_LOCATION ) ) );

                    pMutableAttrList->AddAttribute( aLocQName, aLocation );
                }
                else
                {
                    const OUString& rApp = GetXMLToken( XML_APPLICATION );
                    const OUString& rDoc = GetXMLToken( XML_DOCUMENT );
                    OUString aAttrValue;
                    if( rAttrValue.getLength() > rApp.getLength()+1 &&
                        rAttrValue.copy(0,rApp.getLength()).
                            equalsIgnoreAsciiCase( rApp ) &&
                        ':' == rAttrValue[rApp.getLength()] )
                    {
                        aLocation = rApp;
                        aAttrValue = rAttrValue.copy( rApp.getLength()+1 );
                    }
                    else if( rAttrValue.getLength() > rDoc.getLength()+1 &&
                             rAttrValue.copy(0,rDoc.getLength()).
                                equalsIgnoreAsciiCase( rDoc ) &&
                             ':' == rAttrValue[rDoc.getLength()] )
                    {
                        aLocation= rDoc;
                        aAttrValue = rAttrValue.copy( rDoc.getLength()+1 );
                    }
                    if( aAttrValue.getLength() )
                        pMutableAttrList->SetValueByIndex( i,
                    aAttrValue );
                    if( aLocation.getLength() )
                    {
                        OUString aAttrQName( GetTransformer().GetNamespaceMap().
                        GetQNameByKey( XML_NAMESPACE_SCRIPT,
                        ::xmloff::token::GetXMLToken( XML_LOCATION ) ) );
                        pMutableAttrList->AddAttribute( aAttrQName, aLocation );
                        // draw bug
                        aAttrQName = GetTransformer().GetNamespaceMap().
                        GetQNameByKey( XML_NAMESPACE_SCRIPT,
                        ::xmloff::token::GetXMLToken( XML_LIBRARY ) );
                        pMutableAttrList->AddAttribute( aAttrQName, aLocation );
                    }
                }
            }
            break;
			case XML_ATACTION_COPY:
				break;
			default:
				OSL_ENSURE( sal_False, "unknown action" );
				break;
			}
		}
	}

	XMLRenameElemTransformerContext::StartElement( xAttrList );
}
