/////////////////////////////////////////////////////////////////////////////
// Name:        No names yet.
// Purpose:     Contrib. demo
// Author:      Aleksandras Gluchovas
// Modified by:
// Created:     3/01/99
// RCS-ID:      $Id: fltoolbarmgr.cpp,v 1.2 2001/04/03 20:10:27 aleksandras Exp $
// Copyright:   (c) Aleksandras Gluchovas
// Licence:   	wxWindows license
/////////////////////////////////////////////////////////////////////////////
 
#ifdef __GNUG__
#pragma implementation "objstore.h"
// #pragma interface
#endif

// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"

#ifdef __BORLANDC__
#pragma hdrstop
#endif

#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif

#include "fltoolbarmgr.h"

#include "wx/fl/controlbar.h"
#include "wx/fl/dyntbar.h"
#include "wx/fl/dyntbarhnd.h"

#include "wx/pmf/pm_flalg.h"

/***** Implementation for class FLToolBarInfo *****/

FLToolBarInfo::FLToolBarInfo()
{}

FLToolBarInfo::~FLToolBarInfo()
{
	WX_CLEAR_ARRAY( mTools );
}

/***** Implementation for class FLToolBarClientInfo *****/

FLToolBarClientInfo::FLToolBarClientInfo()
{}

FLToolBarClientInfo::~FLToolBarClientInfo()
{
	WX_CLEAR_ARRAY( mBars );
}

/***** Implementation for class wxFLToolBarManager *****/

IMPLEMENT_DYNAMIC_CLASS( wxFLToolBarManager, wxEvtHandler )

BEGIN_EVENT_TABLE( wxFLToolBarManager, wxEvtHandler )

END_EVENT_TABLE()

wxFLToolBarManager::wxFLToolBarManager()
{
	SetRefData( (wxObjectRefData*)(wxPMService*)this );
}

wxFLToolBarManager::~wxFLToolBarManager()
{
	SetRefData( NULL ); // part of the above hack..
}

// overriden methods of wxPMService

wxPMMergableMenuChain* wxFLToolBarManager::GetMergableMenuChain()
{
	return NULL;
}

bool wxFLToolBarManager::Start()
{
	// assert dependencies first

	/*
	wxPMService* pSvc = wxPMBootSvc().FindServiceByClass( CLASSINFO( wxPMFrameLayoutAlgorithm ) );
	
	wxASSERT_MSG( pSvc, "wxFLToolBarManager depends on wxPMFrameLayoutAlgorithm service, which is not started yet" );

	wxPMFrameLayoutAlgorithm* pFLAlg = (wxPMFrameLayoutAlgorithm*)pSvc->GetWxObject();

	// initialize

	wxPMBootSvc().AddListener( this );

	mpFl = pFLAlg->GetFrameLayout();
	*/

	return TRUE;
}

bool wxFLToolBarManager::Stop()
{
	wxPMBootSvc().RemoveListener( this );

	return TRUE;
}

wxObject* wxFLToolBarManager::GetWxObject()
{
	return (wxObject*)this;
}

// implemented interface of wxPMInf_ToolBarManager

bool wxFLToolBarManager::RegisterClient( wxClassInfo* pClass, wxObject* pInstance )
{
	if ( FindClient( pClass, pInstance ) != NULL )

		return FALSE; // already registered

	FLToolBarClientInfo* pClient = new FLToolBarClientInfo();

	pClient->mpClass = pClass;
	pClient->mpInstance = pInstance;

	mClients.Add( pClient );

	return TRUE;
}

bool wxFLToolBarManager::UnregisterClient( wxClassInfo* pClass, wxObject* pInstance )
{
	FLToolBarClientInfo* pClient = (FLToolBarClientInfo*)FindClient( pClass, pInstance );

	if ( !pClient )

		return FALSE;

	mClients.Remove( pClient );
	delete pClient;

	return TRUE;
}

bool wxFLToolBarManager::IsRegisteredClient( wxClassInfo* pClass, wxObject* pInstance )
{
	return FindClient( pClass, pInstance ) != NULL;
}

wxToolBarClientHandle wxFLToolBarManager::FindClient( wxObject* pInstance )
{
	wxClassInfo* pClass = pInstance->GetClassInfo();

	// FIXME:: may be faster alg. 

	size_t sz = mClients.Count();

	for( size_t i = 0; i != sz; ++i )
	{
		FLToolBarClientInfo& clnt = *mClients[i];

		if ( clnt.mpClass == pClass )
		{
			// if client has an instance specified,
			// check matching of instances

			if ( clnt.mpInstance )
			{
				if ( pInstance == clnt.mpInstance )

					return (wxToolBarClientHandle)&clnt;
			}
			else
				// otherwise matching of classes is sufficient

				return (wxToolBarClientHandle)&clnt;
		}
	}

	return NULL;
}

wxToolBarClientHandle wxFLToolBarManager::FindClient( wxClassInfo* pClass, wxObject* pInstance )
{
	// FIXME:: may be faster alg. 

	size_t sz = mClients.Count();

	for( size_t i = 0; i != sz; ++i )
	{
		FLToolBarClientInfo& clnt = *mClients[i];

		if ( clnt.mpClass == pClass && clnt.mpInstance == pInstance )

			return (wxToolBarClientHandle)&clnt;
	}

	return NULL;
}

void wxFLToolBarManager::BeginToolBar( wxToolBarClientHandle hClient, const wxString& title, 
									   int align, int ofs, int row )
{
	FLToolBarClientInfo* pClient = (FLToolBarClientInfo*)hClient;

	FLToolBarInfo* pBar = new FLToolBarInfo();

	pBar->mAling = align;
	pBar->mOfs   = ofs;
	pBar->mRow   = row;
	pBar->mTitle = title;

	pClient->mBars.Add( pBar );
}

void wxFLToolBarManager::AddTool( wxToolBarClientHandle hClient, 
								  int cmdId, const wxBitmap& bmp, 
								  const wxString& toolTip, bool togglable )
{
	FLToolBarClientInfo* pClient = (FLToolBarClientInfo*)hClient;

	wxASSERT( pClient->mBars.Count() );

	FLToolBarInfo* pBar = pClient->mBars[ pClient->mBars.Count() - 1 ];

	FLToolBarToolInfo* pTool = new FLToolBarToolInfo();

	pTool->mBmp       = bmp;
	pTool->mCmdId     = cmdId;
	pTool->mToolTip   = toolTip;
	pTool->mTogglable = togglable;

	pBar->mTools.Add( pTool );
}

void wxFLToolBarManager::EndToolBar( wxToolBarClientHandle hClient )
{
	// nothing
}

void wxFLToolBarManager::UpdateUI( wxToolBarClientHandle hClient )
{
	// TBD::
}

// overriden notifications of wxPMBootstrapServiceListener

void wxFLToolBarManager::OnServiceStarted( wxPMService& service )
{
	wxObject* pObj = service.GetWxObject();

	FLToolBarClientInfo* pClient = (FLToolBarClientInfo*)FindClient( pObj );

	if ( pClient )
	{
		if ( BarsCreated( pClient ) )

			ActiveteToolbarsForClient( pClient, TRUE );
		else
			CreateToolbarsForClient( pClient );
	}
}

void wxFLToolBarManager::OnServiceStopped( wxPMService& service )
{
	wxObject* pObj = service.GetWxObject();

	FLToolBarClientInfo* pClient = (FLToolBarClientInfo*)FindClient( pObj );

	if ( pClient )
	{
		if ( BarsCreated( pClient ) )

			ActiveteToolbarsForClient( pClient, FALSE );
	}
}

/*** protected methods ***/

void wxFLToolBarManager::CreateToolbarsForClient( FLToolBarClientInfo* pClient )
{
	cbDynToolBarDimHandler* pSizeHandler = new cbDynToolBarDimHandler();

	for( size_t i = 0; i != pClient->mBars.Count(); ++i )
	{
		FLToolBarInfo* pBar = pClient->mBars[i];

		wxDynamicToolBar* pBarWnd = new wxDynamicToolBar( wxPMBootSvc().GetMainWindow(), -1 );

		pBar->mpBarWnd = pBarWnd;

		for( size_t k = 0; k != pBar->mTools.Count(); ++k )
		{
			FLToolBarToolInfo* pTool = pBar->mTools[k];

			pBarWnd->AddTool( pTool->mCmdId, pTool->mBmp, 
							  wxNullBitmap, pTool->mTogglable, -1,-1,NULL, pTool->mToolTip );
		}

		cbDimInfo dim( 200, 30,  // horiz.
					   30,  200, // vert.
					   200, 30,  // dimensions when floating
					   TRUE, 6,6, 
					   pSizeHandler );

		mpFl->AddBar( pBarWnd, dim, pBar->mAling, pBar->mRow, pBar->mOfs, pBar->mTitle );
	}
}

void wxFLToolBarManager::ActiveteToolbarsForClient( FLToolBarClientInfo* pClient, 
												    bool activate )
{
	for( size_t i = 0; i != pClient->mBars.Count(); ++i )
	{
		FLToolBarInfo* pBar = pClient->mBars[i];



	}
}

bool wxFLToolBarManager::BarsCreated( FLToolBarClientInfo* pForClient )
{
	return pForClient->mBars.Count() && 
		   pForClient->mBars[0]->mpBarWnd != NULL;
}