/////////////////////////////////////////////////////////////////////////////
// Name:        No names yet.
// Purpose:     Contrib. demo
// Author:      Aleksandras Gluchovas
// Modified by:
// Created:     2000/02/08
// RCS-ID:      $Id: pm_doc.h,v 1.11 2001/04/23 00:44:29 georgetasker Exp $
// Copyright:   (c) Aleksandras Gluchovas
// Licence:   	GPL (version 2.0 or later)
/////////////////////////////////////////////////////////////////////////////

#ifndef __PM_DOC_G__
#define __PM_DOC_G__

#include "wx/pmf/pm_cmn.h"

#include "wx/docview.h"
#include "wx/docmdi.h"

// base class for views in PMF

class wxPMView : public wxView, public wxPMService
{
public:
	wxPMView();
	~wxPMView();

	// overridden methods of wxPMService
	virtual wxPMMergableMenuChain* GetMergableMenuChain();
	virtual wxObject* GetWxObject();

	// overridden methods of wxView
	virtual void OnDraw( wxDC* pDc );
	virtual bool OnCreate(wxDocument* doc, long flags);
	virtual bool OnClose(bool deleteWindow);
    virtual void OnActivateView(bool activate, wxView *activeView, wxView *deactiveView);
	virtual void Activate( bool activate );

	// used for avoiding multiple requests to Close() document
	virtual void SetClosing( bool closing );
	virtual bool IsClosing();

	virtual wxWindow* GetViewFrame();

	// overridable for the derived classes, returns NULL
	// if view has put no window into view's frame window (ie. into wxMDIChidlFrame)

	virtual wxWindow* GetViewClient();

	DECLARE_DYNAMIC_CLASS( wxPMView )

protected:
	wxStringList m_DocStates;
	wxWindow*    m_pViewFrame;
	bool         m_IsClosing;
};

/*
 * base for classes carrying location-info specific to 
 * the used concrete layout-agorhtim
 */

class wxPMLayoutPreference : public wxObject
{
public:
	wxPMLayoutPreference();

	virtual void Serialize( wxConfigBase& cfg, const wxString& key, bool isLoading );

	DECLARE_DYNAMIC_CLASS( wxPMLayoutPreference )
};

// base class for all panes (which lay "docked" around the MDI-client area)

class wxPMPane : public wxEvtHandler, 
				 public wxPMService
{
public:
	wxPMPane();
	~wxPMPane();

	/*** pane/subpane management ***/
	virtual void SetParentPane( wxPMPane* pPane );
	virtual void AddChildPane( wxPMPane* pPane );
	virtual wxPMPane* GetParentPane();
	virtual PMPaneListT& GetChildPanes();

	virtual void SetPaneName( const wxString& name );
	virtual const wxString& GetPaneName();

	// called for panes with children
	virtual void ActivateChildPane( wxPMPane* pPane );

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

	// method should be overridden in the derived classes to 
	// return a window object representing this pane
	virtual wxWindow* GetPaneWindow();

	virtual void CreatePaneWindow( wxWindow* pParent );

	// retruns NULL if not associated with any specific document-type
	virtual wxStringList* GetDocumentTypes(); 

	virtual wxStringList* GetDocumentStates( const wxString& forDocType );

	virtual void SetDocument( wxPMDocument* pDoc );
	virtual wxPMDocument* GetDocument();

	virtual wxPMLayoutPreference* GetLayoutPefs();
	virtual void SetLayoutPrefs( wxPMLayoutPreference* pPrefs );

	virtual void SetShown( bool shown );
	virtual bool IsShown();

	// overridden method of wxPMService
	virtual bool SerializeState( wxPMSerializer& ser );

	// notifications sent by PMF

	virtual void OnDocumentActivated( wxPMDocument* pDoc );
	virtual void OnDocumentDeactivated( wxPMDocument* pDoc );
	virtual void OnClosingWorkplace();

	DECLARE_DYNAMIC_CLASS( wxPMPane )

protected:
	wxPMDocument*    m_pDoc;
	wxPMLayoutPreference* m_pLayoutPref;

	wxPMPane*   m_pParentPane;
	PMPaneListT m_ChildPanes;
	bool		m_IsShown;
	wxString    m_PaneName;
};

// prototype pane, which wrapps up given isntance of window
// (should be a child of main-window)

class wxPMSimplePane : public wxPMPane
{
public:
	wxPMSimplePane( wxWindow* wnd, wxPMLayoutPreference* layoutPrefs );

	virtual void CreatePaneWindow( wxWindow* pParent );
	virtual wxWindow* GetPaneWindow();
	virtual wxPMLayoutPreference* GetLayoutPefs();

	DECLARE_CLASS( wxPMSimplePane )
protected:
	wxWindow* mpWnd;
	wxPMLayoutPreference* mpPrefs;
};

// base class for all documents in PMF

class wxPMDocument : public wxDocument, public wxPMService
{
public:
	wxPMDocument();
	~wxPMDocument();

	// overridden methods of wxPMService
	virtual wxPMMergableMenuChain* GetMergableMenuChain();
	virtual wxObject* GetWxObject();

	// overridable
	virtual bool CanHaveFile(); // returns TRUE by default

	// management of hierarchical containment

	virtual void SetParentDocument( wxPMDocument* pParent );
	virtual wxPMDocument* GetParentDocument();

	virtual void AddSubdocument( wxPMDocument* pSubdoc );
	virtual void RemoveSubdocument( wxPMDocument* pSubdoc );

	virtual wxPMDocument* FindSubdocumentForFile( const wxPMFileInfo& finfo );

	// registers services which are automatically started after opening
	// this document

	virtual void AssociateService( wxClassInfo* pSvcClass );
	virtual PMClassInfoListT& GetAssociatedServices();

	virtual void OnClosingChildDocument( wxPMDocument* pChild, bool wasSaved );

	/*** saving/loading of document ***/

	// overridable to, return TRUE if binary file used (default FALSE)
	virtual bool UseSerializer(); 

	// NOTE:: use Save/LoadObject of wxDocument is not used, since
	//        it relies on wxUSE_STD_IOSTREAM. Interfaces
	//        of wx'-native and std:: streams are not compatible,
	//        it is probably better to stick with wx-ones, also they
	//        have better API for storing binary data types.
	//        These methods should not be overridden if your document
	//		  class returns TRUE from UseSerializer()

	virtual bool SavePMDocument( wxOutputStream& s );
	virtual bool LoadPMDocument( wxInputStream& s );

	// override this, if your document returns TRUE for UseSerializer();
	virtual bool SerializePMDocument( wxPMSerializer& ser );
	
	// overridden method of wxPMService, saves "visual" state
	// of this document (possibly to the configuration file of containing workplace)
	virtual bool SerializeState( wxPMSerializer& ser );

	// overridables for documents which return FALSE for CanHaveFile();
	virtual bool SavePMDocument();
	virtual bool LoadPMDocument();

	virtual void SetFileInfo( wxPMFileInfo* pFile );
	virtual wxPMFileInfo* GetFileInfo(); // NULL, if file is not determined yet

	virtual PMDocumentListT& GetSubdocuments();

	virtual wxList* GetAllViews();

	virtual wxPMView* GetFirstPMView();

	// notification called whenever the document becomes active
	virtual void OnActivatePMDocument();

	// utility methods
	
	// returns path relative to the directory from which
	// this document was loaded

	virtual wxString GetRelativePath( const wxString& absPath );
	virtual wxString GetAbsolutePath( const wxString& relPath );

	DECLARE_DYNAMIC_CLASS( wxPMDocument )

protected:
	PMDocumentListT m_Subdocuments;
	wxPMDocument*   m_pParentDoc;

	wxPMFileInfo*   m_pFile; // NULL, if not assigned yet

	PMClassInfoListT m_ServiceClasses; // services associated with this type
									  // of workplace
};

// NOTE:: it is not wxFileConfig's derivative, because the exact type
//        of a project (and it's corresponding class) is determined 
//        only when project's file is opened and it's is type extracted

class wxPMProject : public wxPMDocument
{
public:
	wxPMProject();
	~wxPMProject();

	// overridable 
	virtual wxPMMergableMenuChain* GetMergableMenuChain();

	// project management

	virtual bool AddMultipleFiles( PMFileInfoListT& lst );
	virtual bool AddFile( wxPMFileInfo* pFile );

	virtual bool RemoveFile( wxPMFileInfo* pFile );

	virtual PMFileInfoListT& GetFiles();

	virtual void FindFilesByMimeType( const wxString& mimeType, PMFileInfoListT& toLst );

	virtual wxPMFileInfo* FindFile( const wxString& shortFileName );

	virtual bool ContainsFile( const wxPMFileInfo& finfo );

	// convinience methods

	virtual wxPMDocument* FindDocumentByFile( const wxPMFileInfo& file );

	virtual bool GetFileTextContent( const wxPMFileInfo& file, wxString& toStr );

	virtual bool CanAcceptOtherFiles();

	// overridden method of wxDocument (in order to succeed without a view-class)

	virtual bool OnCreate(const wxString& path, long flags);

	virtual bool UseSerializer(); // returns TRUE
	virtual bool SerializePMDocument( wxPMSerializer& ser );

	// overridden notification of wxPMDocument

	virtual void OnClosingChildDocument( wxPMDocument* pChild, bool wasSaved );

	/*** command-event handlers ***/

	virtual void OnCmdAddFile( wxCommandEvent& event );
//	virtual void OnCmdAddFiles( wxCommandEvent& event );
	virtual void OnCmdFilesRecursively( wxCommandEvent& event );
	virtual void OnCmdProjectSettings( wxCommandEvent& event );

	// IDs which can be used by other services, for
	// translation of command-events to currently active project

	enum COMMAND_IDS
	{
		ID_ADD_FILE = 100,
//		ID_ADD_FILES,
		ID_ADD_FILES_RECURSIVELY,
		ID_PROJECT_SETTINGS
	};

	DECLARE_DYNAMIC_CLASS( wxPMProject )
	DECLARE_EVENT_TABLE()

protected:
	void DoAddFile( const wxString& path );

	void DoInsertFiles( bool recursive, 
						wxString topDir, 
					    const wxString& mask,
						wxStringList& fileList );

	void InsertFiles( bool recursive );

protected:
	PMFileInfoListT m_Files;
};

class wxPMTempProject : public wxPMProject
{
public:
	wxPMTempProject();
	~wxPMTempProject();

	// overridden methods of wxPMDocument
	virtual bool CanHaveFile(); // returns FALSE
	virtual void AddSubdocument( wxPMDocument* pSubdoc );

	// overridden method of wxPMProject
	virtual bool CanAcceptOtherFiles();

	DECLARE_DYNAMIC_CLASS( wxPMTempProject )
};

/*
 * listener-interfaces have no base classes to avoid having "virtual base"
 * while inheriting serveral of them. Listener intended to receiv workplace-related
 * notifications, which only can occure when there is a workplace opened
 */

class wxPMWorkplaceListener
{
public:
	virtual void OnWorkplaceOpened( wxPMWorkplace& workplace );
	virtual void OnWorkplaceClosing( wxPMWorkplace& workplace );

	virtual void OnProjectAdded( wxPMProject& project );
	virtual void OnProjectRemoved( wxPMProject& project );
	virtual void OnProjectActivated( wxPMProject& project, wxPMProject* pPrevProject );

	virtual void OnFileAdded( wxPMFileInfo& file, wxPMProject* pToProject );
	virtual void OnFileRemoved( wxPMFileInfo& file, wxPMProject* pFromProject  );

	virtual void OnViewActivated( wxPMView& view, wxPMView* pPrevView );
};

// base for all concrete workplace classes of PMF

class wxPMWorkplace : public wxPMDocument
{
public:
	wxPMWorkplace();
	~wxPMWorkplace();

    bool CleanUp();

	// overridden method of wxDocument (in order to succeed without a view-class)
	virtual bool OnCreate(const wxString& path, long flags);

	virtual wxPMMergableMenuChain* GetMergableMenuChain();

	virtual void SetLayoutAlgorithm( wxPMLayoutAlgorithm* pAlg );
	virtual wxPMLayoutAlgorithm* GetLayoutAlgorithm();

	virtual void SetActiveProject( wxPMProject* pPrj );
	virtual wxPMProject* GetActiveProject();
	virtual bool IsActiveProject( wxPMProject* pPrj );

	virtual void AddProject( wxPMProject* pPrj );
	virtual void RemoveProject( wxPMProject* pPrj );

	// type-safe methods for accessing subdocuments of the workplace
	// (ie. instances of wxPMProject)

	virtual size_t GetProjectCount();
	virtual wxPMProject& GetProject( size_t index );

	virtual void UpdateUIForView( wxPMView* pView );

	virtual void AddListener( wxPMWorkplaceListener* pListener );
	virtual void RemoveListener( wxPMWorkplaceListener* pListener );

	// overridden notification of wxPMDocument

	virtual void OnClosingChildDocument( wxPMDocument* pChild, bool wasSaved );

	// notifications received from wxPMProject objects, and forwarded to 
	// all subscribed listeners

	virtual void NotifyFileAdded( wxPMFileInfo& file, wxPMProject* pPrj );
	virtual void NotifyFileRemoved( wxPMFileInfo& file, wxPMProject* pPrj );

	// overridden methods of wxPMDocument
	virtual bool UseSerializer(); // returns TRUE
	virtual bool SerializePMDocument( wxPMSerializer& ser );

	// IDs which can be used by other services, for
	// translation of command-events to currently active project

	enum WORKPLACE_COMMANDS
	{
		ID_INSERT_PROJECT = 200,
		ID_NEW_PROJECT,

		ID_MAKE_PROJECT_ACTIVE,

		ID_NEW_WORKPLACE,
		ID_SAVE_WORKPLACE,
		ID_CLOSE_WORKPLACE,
		ID_TIPS
	};

	/*** command-event handlers ***/

	virtual void OnCmdInsertProject( wxCommandEvent& event );
	virtual void OnCmdNewProject( wxCommandEvent& event );
	virtual void OnCmdMakeProjectActive( wxCommandEvent& event );
	virtual void OnCmdCloseWorkplace( wxCommandEvent& event );
	virtual void OnCmdNewWorkplace( wxCommandEvent& event );
	virtual void OnCmdTips( wxCommandEvent& event );

	DECLARE_EVENT_TABLE()
	DECLARE_DYNAMIC_CLASS( wxPMWorkplace )

protected:
	wxPMProject*   m_pActivePrj;

	wxPMLayoutAlgorithm* m_pLayoutAlg;

	PMWorkplaceListenerListT m_Listeners;

	PMFileInfoListT m_Files;
	size_t			m_ActivePrjNo;
};

#endif // __PM_DOC_G__
