/**************************************************************
 * 
 * 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 <tools/debug.hxx>
#include <rtl/ustring.hxx>
#include <svl/svarray.hxx>
#include <xmloff/xmltkmap.hxx>
#include <xmloff/xmltoken.hxx>

using namespace rtl;
using namespace ::xmloff::token;

class SvXMLTokenMapEntry_Impl
{
	sal_uInt16	nPrefixKey;
	OUString	sLocalName;
	sal_uInt16	nToken;

public:

	sal_uInt16 GetToken() const { return nToken; }

	SvXMLTokenMapEntry_Impl( sal_uInt16 nPrefix, const OUString& rLName,
						     sal_uInt16 nTok=XML_TOK_UNKNOWN ) :
		nPrefixKey( nPrefix ),
		sLocalName( rLName  ),
		nToken( nTok )
	{}

	SvXMLTokenMapEntry_Impl( const SvXMLTokenMapEntry& rEntry ) :
		nPrefixKey( rEntry.nPrefixKey ),
		sLocalName( GetXMLToken( rEntry.eLocalName ) ),
		nToken( rEntry.nToken )
	{}

	sal_Bool operator==( const SvXMLTokenMapEntry_Impl& r ) const
	{
		return nPrefixKey == r.nPrefixKey &&
			   sLocalName == r.sLocalName;
	}

	sal_Bool operator<( const SvXMLTokenMapEntry_Impl& r ) const
	{
		return nPrefixKey < r.nPrefixKey ||
			   ( nPrefixKey == r.nPrefixKey &&
				 sLocalName < r.sLocalName);
	}
};

typedef SvXMLTokenMapEntry_Impl *SvXMLTokenMapEntry_ImplPtr;
SV_DECL_PTRARR_SORT_DEL( SvXMLTokenMap_Impl, SvXMLTokenMapEntry_ImplPtr, 5, 5 )
SV_IMPL_OP_PTRARR_SORT( SvXMLTokenMap_Impl, SvXMLTokenMapEntry_ImplPtr )

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

SvXMLTokenMapEntry_Impl *SvXMLTokenMap::_Find( sal_uInt16 nKeyPrefix,
									 		   const OUString& rLName ) const
{
	SvXMLTokenMapEntry_Impl *pRet = 0;
	SvXMLTokenMapEntry_Impl aTst( nKeyPrefix, rLName );

	sal_uInt16 nPos;
	if( pImpl->Seek_Entry( &aTst, &nPos ) )
	{
		pRet = (*pImpl)[nPos];
	}

	return pRet;
}

SvXMLTokenMap::SvXMLTokenMap( const SvXMLTokenMapEntry *pMap ) :
	pImpl( new SvXMLTokenMap_Impl )
{
	while( pMap->eLocalName != XML_TOKEN_INVALID )
	{
		pImpl->Insert( new SvXMLTokenMapEntry_Impl( *pMap ) );
		pMap++;
	}
}

SvXMLTokenMap::~SvXMLTokenMap()
{
	delete pImpl;
}

sal_uInt16 SvXMLTokenMap::Get( sal_uInt16 nKeyPrefix,
							   const OUString& rLName ) const
{
	SvXMLTokenMapEntry_Impl *pEntry = _Find( nKeyPrefix, rLName );
	if( pEntry )
		return pEntry->GetToken();
	else
		return XML_TOK_UNKNOWN;
}


