/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: sfx2_map.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: rt $ $Date: 2006/07/25 08:15:23 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
// INCLUDE ---------------------------------------------------------------
#include <stdlib.h>

#pragma hdrstop

#include "map.hxx"
#include "shell.hxx"
#include "objface.hxx"

#include "dispatch.hxx"
namespace binfilter {

// STATIC DATA -----------------------------------------------------------

DBG_NAME(SfxMap)

extern "C"
#if defined( PM2 ) && !defined( CSET ) && !defined( WTC )
int _stdcall
#else
#ifdef WNT
int _cdecl
#else
int
#endif
#endif
SfxCompareMessages_Impl( const void* pSmaller, const void* pBigger );

// -----------------------------------------------------------------------
SfxMap::SfxMap(const SfxShell &rShell, BOOL bRecursiveSearch ):
	SfxWhichMap( TRUE ),
	pInterface( rShell.GetInterface() ),
	pDispatcher( 0 ),
	bRecursive( bRecursiveSearch )
{
	DBG_CTOR(SfxMap, 0);
	DBG_ASSERT(pInterface != 0, "Interface ist NULL");
}

// -----------------------------------------------------------------------
USHORT SfxMap::GetWhich(USHORT nSlot) const
{
	DBG_CHKTHIS(SfxMap, 0);
	const SfxSlot *pSlot = 0;

	if ( !pInterface && !pDispatcher )
		return nSlot;

	const SfxInterface *pIF = pInterface;
	USHORT nShell = 0;
	if ( pDispatcher )
		 pIF = pDispatcher->GetShell(nShell)->GetInterface();

	while ( pIF )
	{
		for ( ; !pSlot && pIF; pIF = pIF->GetGenoType() )
			pSlot = (const SfxSlot *)bsearch(
								&nSlot, pInterface->pMsgs,
								pInterface->nCount, sizeof(SfxSlot),
								SfxCompareMessages_Impl );
		if ( pSlot )
			return pSlot->GetWhich()? pSlot->GetWhich(): nSlot;
		if ( pDispatcher )
		{
			const SfxShell *pSh = pDispatcher->GetShell(++nShell);
			pIF = pSh ? pSh->GetInterface() : 0;
		}
		else
			pIF = 0;
	}

//  Aus den allgemeinen TabPages kann nach Slot-/Whichwerten
//	gefragt werden, fuer die kein Eintrag in der Map existiert,
//	da sie die Applikation nicht unterstuetzt; deshalb keine
//	Assertion.
//	Der alte Wert wird zurueckgeliefert, damit die Applikation
//	bei 1:1 Mappings keine Eintraege in der Slotmap ertellen muss.
//	(EditEngine benutzt IDs 1:1)
//	DBG_ERROR("Slot nicht gefunden");
	return nSlot;
}

// -----------------------------------------------------------------------
USHORT SfxMap::GetSlot(USHORT nWhich) const
{
	DBG_CHKTHIS(SfxMap, 0);
	DBG_ASSERT(nWhich, "Which-Id ist 0");

	if ( !pInterface && !pDispatcher )
		return nWhich;

	const SfxSlot *pSlot = 0;
	const SfxInterface *pIF = pInterface;
	USHORT nShell = 0;
	if ( pDispatcher )
		 pIF = pDispatcher->GetShell(nShell)->GetInterface();

	while ( pIF )
	{
		for ( ; !pSlot && pIF; pIF = pIF->GetGenoType() )
		{
			const SfxSlot *pTempSlot = pInterface->pMsgs;
			for ( USHORT i = 0; i < pInterface->nCount && !pSlot; ++i )
				if ( (pTempSlot+i)->GetWhich() == nWhich )
					pSlot = pTempSlot;
		}

		if ( pSlot )
			return pSlot->GetId();

		if ( pDispatcher )
		{
			const SfxShell *pSh = pDispatcher->GetShell(++nShell);
			pIF = pSh ? pSh->GetInterface() : 0;
		}
		else
			pIF = 0;
	}

//	Kommenar s.o.
//    DBG_ERROR("Slot nicht gefunden");
	return nWhich;
}

// ------------------------------------------------------------------
SfxWhichMap* SfxMap::Clone() const
{
	return new SfxMap(*this);
}


}
