/////////////////////////////////////////////////////////////////////////////
// Name:        No names yet.
// Purpose:     Contrib. demo
// Author:      Aleksandras Gluchovas
// Modified by:
// Created:     2000/02/08
// RCS-ID:      $Id: pm_gui.h,v 1.7 2001/04/03 20:10:26 aleksandras Exp $
// Copyright:   (c) Aleksandras Gluchovas
// Licence:   	GPL (version 2.0 or later)
/////////////////////////////////////////////////////////////////////////////

#ifndef __PM_GUI_G__
#define __PM_GUI_G__

/*=== Custom graphical components for PMF (TAB size=4) ===*/

#include "wx/pmf/pm.h"
#include "wx/pmf/inf/layoutalg.h"

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

#include "wx/treectrl.h"
#include "wx/listctrl.h"
#include "wx/sashwin.h"

class wxPMSimpleWorkplace;
class wxPMWorkplaceBrowserPane;

class wxPMSashLayoutAlgorithm;
class wxPMSashLayoutPreferenceTemplate;
class wxPMSashLayoutPreference;

WX_DEFINE_ARRAY( wxPMSashLayoutPreferenceTemplate*, PMSashLayoutPreferenceTemplateListT );

// TBD:: comments...

class wxPMSashLayoutPreference : public wxPMLayoutPreference
{
public:
	wxPMSashLayoutPreference();
	wxPMSashLayoutPreference( int alignment, int orderIndex );

	// overridden method of wxPMLayoutPreference
	virtual void Serialize( wxConfigBase& cfg, const wxString& key, bool isLoading );

	void SetAlignment( int alignment );
	int  GetAlignment();
	void SetOrderIndex( int index );
	int  GetOrderIndex();
	void SetWidth( int width );
	int  GetWidth();


	DECLARE_DYNAMIC_CLASS( wxPMSashLayoutPreference )

protected:
	int m_Alignment;
	int m_OrderIndex;
	int m_Width;
};

class wxPMSashLayoutPreferenceTemplate : public wxObject
{
public:
	wxPMSashLayoutPreferenceTemplate( wxClassInfo* pPaneClass,
									  wxPMSashLayoutPreference* pPreference );
	~wxPMSashLayoutPreferenceTemplate();

public:
	wxClassInfo* m_pPaneClass;
	wxPMSashLayoutPreference* m_pPrefrence;
};

// TBD:: comments...

class wxPMSashLayoutAlgorithm : public wxEvtHandler,
								public wxPMService,
								public I_PMPaneLayoutAlgorithm,
								public wxPMBootstrapServiceListener
								 
{
public:
	wxPMSashLayoutAlgorithm();
	~wxPMSashLayoutAlgorithm();

	// overridden methods of wxPMService
	virtual bool Start();
	virtual bool Stop();
	virtual wxObject* GetWxObject();

	// overridden notifications of wxPMBootstrapServiceListener
	virtual void OnPaneShown( wxPMPane& pane );
	virtual void OnPaneHidden( wxPMPane& pane );
	virtual void OnServiceStarted( wxPMService& service );
	virtual void OnServiceStopped( wxPMService& service );

	// overridden method of wxPMLayoutAlgorithm
	virtual wxPMLayoutPreference* CreateDefaultLayoutPrefs();

	// overridden method of wxPMService
	virtual void Serialize( wxConfigBase& cfg, const wxString& key, bool isLoading );

	virtual void AddPreferenceTemplate( wxPMSashLayoutPreferenceTemplate* pTempl );
	virtual void AddPreferenceTemplate( wxClassInfo* pClass, wxPMSashLayoutPreference* pPref );

	/*** event-handlers ***/

	void OnIdle( wxIdleEvent& event ); // perfroms relayouting (if needed)
	void OnSashDrag( wxSashEvent& event );
	void OnSize( wxSizeEvent& event ); // react to sizing of the main frame

	DECLARE_EVENT_TABLE()
	DECLARE_DYNAMIC_CLASS( wxPMSashLayoutAlgorithm )

protected:
	void DoRelayout();

protected:
	PMPaneListT m_TopLevelPanes;
	PMPaneListT m_ActivePanes;
	PMSashLayoutPreferenceTemplateListT m_PrefTemplates;

	bool m_RelayoutPending;
	int  m_NextWndId;
};

class wxPMBrowserTreeCtrl;
class wxPMBrowserTreeData;

/*
 * wxPMWorkplaceBrowserPane class does most of the
 * work for controlling/updating multiproject-treectrl.
 * Also, it is meant to be subclassed by concrete 
 * browsers which "hook in" their code into places,
 * where management of their specific tree-items occures
 * (eg. could be extended by class/resource/file/whatever browser)
 */

class wxPMWorkplaceBrowserPane : public wxPMPane, public wxPMWorkplaceListener
{
public:
	wxPMWorkplaceBrowserPane();

	// 2 overridden methods of wxPMService
	virtual bool Start();
	virtual bool Stop();

	// overridden method of wxPMPane
	virtual wxWindow* GetPaneWindow();
	virtual void CreatePaneWindow( wxWindow* pParent );

	virtual void RebuildTree();

	/***  appearance settings ***/

	// TRUE, if workplace-icon is always shown
	// as a root-item, otherwise it is hidden
	// when only one project is in the workplace
	// and icon of that single project is shown as root	
	
	virtual void SetAlwaysShowWorkplace( bool alwaysShown );
	virtual bool GetAlwaysShowWorkplace();

	virtual void SetWorkplaceBitmap( const wxString& name );
	virtual void SetRecentItemsBitmap( const wxString& name );
	virtual void SetProjectBitmap( const wxString& name );
	virtual void SetActiveProjectBitmap( const wxString& name );
	virtual void SetOtherFilesBitmap( const wxString& name );

	/*** utility methods for use in subclasses (not for overriding) ***/

	// use this method instead of m_pTree->Appned(...), this way the object
	// refered by pData is put to hash in order to find it's corresponding id
	// when needed later

	virtual wxTreeItemId AppendItem( wxTreeItemId parent, const wxString& text,
									 int image = -1, int selImage = -1, wxPMBrowserTreeData* pData = NULL );

	// use this method instead of m_pTree->Delete, since it keeps hashtable of
	// objects<->tree-items synhronized
	// 
	virtual void DeleteItem( wxTreeItemId item );

	// same as above, isntead of single item, all the children of
	// the given item are deleted first (recursively)

	virtual void DeleteBranch( wxTreeItemId item );

	// finds tree-data which has it's member m_pObject machting the given one

	virtual wxPMBrowserTreeData* FindDataForObject( wxObject* pObj );

	// same as above, except that it does wxASSERT_MSG() if data not found
	virtual wxPMBrowserTreeData* GetDataForObject( wxObject* pObj );

	// same as above, only returns tree-item instead of it's data
	virtual wxTreeItemId FindTreeItemForObject( wxObject* pObj );

	virtual wxPMProject* GetProjectForItem( wxTreeItemId item );
	virtual wxPMProject* GetSelectedProject();

	// returns "m_pObject" member of wxPMBrowserTreeData which corresponds to
	// currently selected tree-item (asserts against for null-pointers)

	virtual wxObject* GetSelectedObject();

	// use this if you don't like "m_pTree" with "mp" prefix
	wxTreeCtrl* GetTree();

	// overridden notifications of wxPMWorkplaceListener
	virtual void OnProjectAdded( wxPMProject& project );
	virtual void OnProjectRemoved( wxPMProject& project );
	virtual void OnProjectActivated( wxPMProject& project, wxPMProject* pPrevProject );

	/*** event-handlers for commands received from context-popup menu ***/

	void OnCmdRemoveProject( wxCommandEvent& event );
	void OnCmdInsertProject( wxCommandEvent& event );
	void OnCmdNewProject( wxCommandEvent& event );
	void OnCmdMakeProjectActive( wxCommandEvent& event );
	void OnCmdNewWorkplace( wxCommandEvent& event );
	void OnCmdSaveWorkplace( wxCommandEvent& event );
	void OnCmdCloseWorkplace( wxCommandEvent& event );

	/***  overridables for concrete subclasses ***/

	virtual void OnItemExpanding( wxTreeItemId item, wxPMBrowserTreeData* pData  );
	virtual void OnItemCollapsed( wxTreeItemId item, wxPMBrowserTreeData* pData  );
	virtual void OnItemActivated( wxTreeItemId item, wxPMBrowserTreeData* pData );
	virtual bool OnSelectionChanging( wxTreeItemId item, wxPMBrowserTreeData* pData );
	virtual void OnSelectionChanged( wxTreeItemId item, wxPMBrowserTreeData* pData );
	virtual void OnDeleteRequested( wxTreeItemId item, wxPMBrowserTreeData* pData );

	virtual void OnContextMenuRequested( wxTreeItemId item, 
										 wxPMBrowserTreeData* pData, int x, int y );

	// called when user right-click-requests popup menu for
	// an item. Override this to add menu-items specfic to the type of item
	// (than call the same method of base class)

	virtual void OnAddItemsToContextMenu( wxMenu& menu, wxPMBrowserTreeData* pData );

	// "factory method" for creating custom treectrl in derived classes
	virtual wxPMBrowserTreeCtrl* CreateTree( wxWindow* pParent );

	// the same for image list, use the indexes of below enum for
	// adding "standard" or subclass-specific images to the list

	virtual wxImageList* CreateImageList(); 

	enum IMAGE_INDEXES_ENUM
	{
		WORKPLACE_ITEM_IMAGE	  = 0,
		RECENT_ITEM_IMAGE		  = 1,
		PROJECT_ITEM_IMAGE		  = 2,
		ACTIVE_PROJECT_ITEM_IMAGE = 3,
		MISC_FILES_ITEM_IMAGE	  = 4,
	};

	enum BROWSER_COMMANDS_ENUM
	{
		// command IDs matched against those in wxPMWorkplace:: to enable
		// delegation popup-requests directly to workplace using ProcessEvent(..)

		ID_INSERT_PROJECT      = wxPMWorkplace::ID_INSERT_PROJECT,
		ID_NEW_PROJECT         = wxPMWorkplace::ID_NEW_PROJECT,

		ID_MAKE_PROJECT_ACTIVE = wxPMWorkplace::ID_MAKE_PROJECT_ACTIVE,

		ID_NEW_WORKPLACE       = wxPMWorkplace::ID_NEW_WORKPLACE,
		ID_SAVE_WORKPLACE      = wxPMWorkplace::ID_SAVE_WORKPLACE,
		ID_CLOSE_WORKPLACE     = wxPMWorkplace::ID_CLOSE_WORKPLACE,

		ID_REMOVE_PROJECT = 150, // command available only from the browser
	};

	// can be overridden to return different images for the "standard" items

	DECLARE_DYNAMIC_CLASS( wxPMWorkplaceBrowserPane )
	DECLARE_EVENT_TABLE()

protected:
	virtual void AddProjectItems();
	virtual void AddProjectItem( wxPMProject* pPrj );
	virtual void RemoveProjectItem( wxPMProject* pPrj );
	virtual void RemoveAllProjectItems();
	virtual wxTreeItemId CreateRootItem();

protected:
	wxPMBrowserTreeCtrl* m_pTree;
	wxHashTable          m_ObjectHash; // wxObject<->wxTreeItemId map
									  // for doing searches
	wxImageList*         m_pImageList;

	bool m_AwaysShowWorkplace;		   // default: TRUE

	wxString m_WorkplaceBitmapName;	   // default: "browsers/16x16_wxlogo_45_degrees"
	wxString m_RecentItemsBitmapName;   // default: "browsers/16x16_folder_blue"
	wxString m_ProjectBitmapName;	   // default: "browsers/16x16_yellow_folder"
	wxString m_ActiveProjectBitmapName; // default: "browsers/16x16_yellow_folder_open"
	wxString m_OtherFilesBitmapName;    // default: "browsers/16x16_other_files"
};

enum PM_BROWSER_TREE_ITEM_TYPES
{
	wxPM_ROOT_ITEM     = 1,
	wxPM_PROJECT_ITEM  = 2,
};

/*
 * class can be subclassed to encapsulate more info, which is
 * specific to concrete derivative of wxPMWorkplaceBrowserPane
 */

class wxPMBrowserTreeData : public wxTreeItemData
{
public:
	wxPMBrowserTreeData( wxObject* pObject, int itemType );

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

	virtual ~wxPMBrowserTreeData();

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

	void SetType( int itemType );
	int  GetType();

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

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

// controlled/aggregated in wxPMBrowserTreeData class

class wxPMBrowserTreeCtrl : public wxTreeCtrl
{
public:
	wxPMBrowserTreeCtrl( wxWindow* pParent, wxPMWorkplaceBrowserPane* pPane );

	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 );

	DECLARE_EVENT_TABLE()

protected:
	wxPMWorkplaceBrowserPane* m_pPane;
};

enum PM_FILE_BROWSER_TREE_ITEM_TYPES
{
	wxPM_FILE_ITEM_TYPE = wxPM_PROJECT_ITEM + 1,
};

#if 1

/*
 * wxPMFileBrowserPane is a kind of wxPMWorkplaceBrowserPane, which
 * extends it by adding file-management functionality into the tree
 * of the workplace. Files are managed for each project, in it's
 * separate branch. This class is still gernal enough to be extanded
 * further, eg. adding sub-items for each file or extending set of
 * commands in the context-popup menu of particular item.
 */

class wxPMFileBrowserPane : public wxPMWorkplaceBrowserPane
{
public:
	wxPMFileBrowserPane();
	~wxPMFileBrowserPane();

	virtual wxPMMergableMenuChain* GetMergableMenuChain();

	// overridden notifications of wxPMWorkplaceListener
	virtual void OnFileAdded( wxPMFileInfo& file, wxPMProject* pToProject );
	virtual void OnFileRemoved( wxPMFileInfo& file, wxPMProject* pFromProject  );

	// overridden notifications of wxPMWorkplaceBrowserPane
	virtual void OnItemExpanding( wxTreeItemId item, wxPMBrowserTreeData* pData  );
	virtual void OnDeleteRequested( wxTreeItemId item, wxPMBrowserTreeData* pData );
	virtual void OnAddItemsToContextMenu( wxMenu& menu, wxPMBrowserTreeData* pData );
	virtual void OnItemActivated( wxTreeItemId item, wxPMBrowserTreeData* pData );

	// overridden "factory-methods" of wxPMWorkplaceBrowserPane
	virtual wxImageList* CreateImageList(); 

	enum IMAGE_INDEXES_ENUM
	{
		FIRST_FILE_TYPE_IMAGE = wxPMWorkplaceBrowserPane::MISC_FILES_ITEM_IMAGE + 1
	};

	enum FILE_BROWSER_COMMANDS_ENUM
	{
		ID_ADD_FILE				 = wxPMProject::ID_ADD_FILE,
//		ID_ADD_FILES			 = wxPMProject::ID_ADD_FILES,
		ID_ADD_FILES_RECURSIVELY = wxPMProject::ID_ADD_FILES_RECURSIVELY,

		ID_NEW_FILE = wxID_NEW, // delegated to current doc-manager

		ID_OPEN_FILE = 300,
		ID_REMOVE_FILE,
		ID_REMOVE_ALL,
		ID_COPY_NAME,
		ID_COPY_FULL_NAME,
		ID_SHOW_PROPERTIES,

		ID_TOGGLE_BROWSER
	};

	// handlers for context-popup commands

	void OnCmdOpenFile( wxCommandEvent& event );
	void OnCmdAddFile( wxCommandEvent& event );
//	virtual void OnCmdAddFiles( wxCommandEvent& event );
	void OnCmdFilesRecursively( wxCommandEvent& event );
	void OnCmdRemoveFile( wxCommandEvent& event );
	void OnCmdRemoveAllFiles( wxCommandEvent& event );
	void OnCmdNewFile( wxCommandEvent& event );
	void OnCmdCopyName( wxCommandEvent& event );
	void OnCmdCopyFullName( wxCommandEvent& event );
	void OnCmdShowProperties( wxCommandEvent& event );
	void OnCmdToggleBrowser( wxCommandEvent& event );

	/*** static methods ***/

	static void RegisterBitmapForMimeType( const wxString& bmpName, const wxString& mimeType );
	static void RegisterBitmapForMimeType( const wxBitmap& bmp, const wxString& mimeType );
	static bool FindBitmapForMimeType( const wxString& mimeType, wxBitmap& bmp );
	static int  FindBitmapIndexForMimeType( const wxString& mimeType );

	// registers all default file-type icons, 
	virtual void RegisterDefaultFileTypeIcons();

	DECLARE_DYNAMIC_CLASS( wxPMFileBrowserPane )
	DECLARE_EVENT_TABLE()

protected:
	virtual void AddFileItem( wxTreeItemId parent, wxPMFileInfo& file );
	virtual void DoCopyToClipboard( const wxString& text );

protected:
	static wxStringList  msMimeTypes; // 1<->1 with msFileIcons
	static PMBitmapListT msFileIcons;
};

#endif

#endif // __PM_GUI_G__