/////////////////////////////////////////////////////////////////////////////
// Name:        No names yet.
// Purpose:     Contrib. demo
// Author:      Aleksandras Gluchovas
// Modified by:
// Created:     2000/02/08
// RCS-ID:      $Id: treesplit.h,v 1.4 2001/03/14 13:48:11 aleksandras Exp $
// Copyright:   (c) Aleksandras Gluchovas
// Licence:   	GPL (version 2.0 or later)
/////////////////////////////////////////////////////////////////////////////

#ifndef __TREESPLIT_G__
#define __TREESPLIT_G__

#include "wx/event.h"
#include "wx/treectrl.h"
#include "wx/imaglist.h"
#include "wx/dynarray.h"
#include "wx/hash.h"

#undef GetObject

// Tree-Split is set of interfacing-classes which extend 
// event-dispatching mechanism of wxTreeCtrl to allow participation 
// of multiple handler-objects in handling tree-events. Events are
// routed depending on the tree-branch to which particular handler
// object is assigned. This way structure of the tree is 
// logically split branch-wise, by allowing each independent
// handler-object create and maintain it's own branch and subbranches.
//
// Additionally tree-split automatically maintains the 
// user-object to tree-item mapping which is useful to 
// quickly locate tree-items which correspond to given 
// application-specific object. This however, implies
// that all item-data objects are derived from wxTSItemData 
// class.


#define SPLIT_TREECTRL_ID 500

class wxTSBranchHandler;
class wxTSItemData;
class wxTSTree;

WX_DEFINE_ARRAY( wxTSBranchHandler*, TSHandlerListT );

class wxTSImageInfo : public wxObject
{
public:
	wxTSImageInfo( wxBitmap bmp, int id, const wxColour maskCol = wxColour(255,0,0) );

	void SetId( int id );
	int GetId();

public:
	int		 mImageId;
	int		 mActualId;
	wxBitmap mBitmap;
	wxColour mMaskCol;
};

WX_DEFINE_ARRAY( wxTSImageInfo*, TSImageInfoListT );

class wxTSHandlerInfo : public wxObject
{
public:
	wxTSBranchHandler* mpHandler;
	TSImageInfoListT   mImages;
};

WX_DEFINE_ARRAY( wxTSHandlerInfo*, TSHandlerInfoListT );

class wxTSItemData : public wxTreeItemData
{
public:
	wxTSItemData();
	wxTSItemData( wxObject* pObject, 
				  wxTSBranchHandler* pHandler, int type = 0 );

	// NOTE:: this virtual dtor does nothing here, but it is
	//        meant to be "overriden" in subclasses, for eg.
	//        deleting the contained mpObject if it holds
	//        data which is managed by wxTSItemData exclusively

	virtual ~wxTSItemData();

	// should be reimplemented by subclasses
	virtual wxTSItemData* Clone();

	void SetObject( wxObject* pObj );
	wxObject* GetObject();

	void SetHandler( wxTSBranchHandler* pHandler );
	wxTSBranchHandler* GetHandler();

	void SetType( int type );
	int GetType();

protected:
	wxObject* mpObject;  // object associated with this tree-node
						 // (is not released when destroying the node)

	wxTSBranchHandler* mpHandler; // handler to which this branch belongs

	int	mType; // item-specific type information, default: 0
};

// interface

class wxTSBranchHandler
{
public:
	virtual wxEvtHandler* GetEvtHandler() = 0;

	virtual void SetTree( wxTSTree* pHolder );
	virtual wxTSTree* GetTree();

	virtual void SetOwnedBranchItem( wxTreeItemId item );
	virtual wxTreeItemId GetOwnedBranchItem();

	// notifications sent by wxTSTree

	virtual void OnAddItemsToPopup( wxMenu* pMenu );
	virtual void OnBranchItemExpanding( wxTreeItemId id, wxTSItemData* pData );
	virtual void OnSelectionChanged( wxTreeItemId id, wxTSItemData* pData );

protected:
	wxTSTree*    mpTree;
	wxTreeItemId mBranchItem;
};

class wxTSTree : public wxTreeCtrl
{
public:
	wxTSTree();
	wxTSTree( wxWindow* pParent, wxWindowID id = SPLIT_TREECTRL_ID );

	~wxTSTree();

	/*** overridden methods of wxTSTree ***/

	virtual void RegisterHandler( wxTSBranchHandler* pHandler );
	virtual void RegisterIcons( TSImageInfoListT& lst, wxTSBranchHandler* pHandler );

	virtual wxTreeItemId AddTSRoot( const wxString& text,
									int image = -1, int selImage = -1, wxTSItemData* pData = NULL );

	virtual wxTreeItemId AppendTSItem( wxTreeItemId parent, const wxString& text,
									   int image = -1, int selImage = -1, wxTSItemData* pData = NULL,
									   bool localizeImageIds = TRUE, int before = -1  );

	virtual void ChangeItemImage( wxTreeItemId, int newImage );
	virtual void DeleteItem( wxTreeItemId item );
	virtual void DeleteBranch( wxTreeItemId item );
	virtual wxTSItemData* FindDataForObject( wxObject* pObj );
	virtual wxTSItemData* GetDataForObject( wxObject* pObj );
	virtual wxTreeItemId FindTreeItemForObject( wxObject* pObj );
	virtual wxObject* GetSelectedObject();
	virtual wxTreeCtrl* GetTree();

	virtual void HashObject( wxObject* pObj, wxTreeItemId itemId );
	virtual void UnHashObject( wxObject* pObj );

	void RebuildImageList();
	int GetActualImageId( int imgId, wxTSBranchHandler* pHandler );

	/*** events ***/

	void OnKeyDown( wxTreeEvent& event );

	void OnDblClick( wxMouseEvent& event );
	void OnRightClick( wxMouseEvent& event );
	void OnMiddleClick( wxMouseEvent& event );
	void OnMouseMove( wxMouseEvent& event );
	void OnLeftMouseUp( wxMouseEvent& event );

	void OnItemExpanding( wxTreeEvent& event );
	void OnSelectionChanging( wxTreeEvent& event );
	void OnSelectionChanged( wxTreeEvent& event );

	void OnBeginDrag( wxTreeEvent& event );

	void OnCommandEvent( wxCommandEvent& event );


	DECLARE_DYNAMIC_CLASS( wxTSTree )
	DECLARE_EVENT_TABLE()

protected:

protected:
	wxImageList*		  mpImgList;
	TSHandlerInfoListT	  mHandlers;
	bool				  mImgListUpdatePending;
	wxHashTable			  mHandlerHash;
	wxHashTable			  mObjectHash; // maps objects to corresponding tree-items
};

#endif // __TREESPLIT_G__