c
	-------------------------------------------------
	Guide to API of Project Managemet Framework (PMF)
	-------------------------------------------------
	
Version: 0.1
Updated: 2000/01/11
Authors: Aleksandras Gluchovas
 E-mail: <alex@soften.ktu.lt>
    URL: http://www.soften.ktu.lt/~alex/
    
[Tab-size=8]

NOTE:: This text intends to provide API-level guidance
       to PMF. For overview of it's functional requirements, 
       please, see to pmf-proposal.txt (has no changes since then)

Contnets:
       
1. Abstract
2. Class Categories
3. Class Hierarchy
4. wxMPService class
5. wxPMDocument class
6. Listener interfaces
7. wxPMProject class
8. wxPMWorkplace class

(TODO:: the rest)       

1. Abstract
===========

Functionality of PMF is mostly straightforward (common
to other well-known IDEs), but it's APIs are not 
simple as they could possibly be, because the 
nature of wxStudio as an IDE puts tough requirements,
eg. a rather simple app could live without abstraction of
a "service", where most aspects in such app are known in
advance and don't change much, whereas an IDE (integrating) app 
should be able to deal with all sorts of "alien" components, 
controlling them as well as providing them with as much freedom 
and "loose" coupling as it is possible. All this rises up the 
depth-level needed to comprehensively cover such arch., but 
it does not necessarily increase the complexity/bugginess.

2. Class Categories
===================

PMF classes can be grouped into three major categories,
each of which is describes dependencies of the contained
classes with respect to those in other categories:

1) Extension classes independent of PMF  - use only wxWindows classes.
2) PMF core classes - use only those in 1)
3) Extension classes which depend on PMF - use 1) and 2)
4) Application's classes - -/-

here, categories are numbered in the order of increasing
dependency to the upper category. There is a basic
rule, that classes from different categories are not 
mixed in one header file. Current tree has the following 
structure:


1) wx/wx.h	keybinder.h	fl.h	newsash.h
	|	|		|	|
	|	|		|	|
	----------------\	|	|
			|	|	|
2)			pmcmn.h	|	|
			|	|	|
			|	|	|
			----------------/
			|
3)			pmgui.h
			|
			|
4)			pm_sample.h and wkp_main.h


fl.h not used yet, shown as an example for 1) category.


3. Class Hierarchy
==================

(not-core classes are labeled with header file
from which they come)

							class wxPMService
class wxObject;						|
	class wxPMFileInfo;				|
	class wxPMFileLoader;				|
		class wxPMLocalFileLoader;		|
		class wxPMHttpFileLoader;		|
		class wxPMFtpFileLoader;		|
							|
	class wxPMLayoutPrefs;				|
		class wxPMSashLayoutPreference; 	|  (pmgui.h)
							|
	class wxPMBitmapManager;			|
	class wxPMMergableMenuChain;			|
	class wxPMMenuTreeItem;				|
							|
class wxView;						|
	class wxPMView; --------------------------------|
		class wxPMWorkplaceBrowserPane;		|  (pmgui.h)
			class wxPMFileBrowserPane;	|  (pmgui.h)
							|
class wxDocument;					|
	class wxPMDocument; ----------------------------|
		class wxPMProject;			|
		class wxPMWorkplace;			|
							|
class wxEvtHandler;					|
        class wxPMBootstrapService; --------------------|
        class wxPMServiceProvider; ---------------------|
        class wxPMLayoutAlgorithm; ---------------------|
        	class wxPMSashLayoutAlgorithm ----------| (pmgui.h)
        						|
        class wxPMPane; --------------------------------|

class wxDocManager;
	class wxPMDocManager;

class wxPMWorkplaceListener;
class wxPMBootstrapServiceListener;

4. wxMPService class
====================

This important class is introduced to reduce diversity of 
PMF classes, by making them comply to a common interface.
It serves as an interface (or mix-in class in C++ terms),
which itself cannot represent an independent object, it 
should be inherited as a second (or third) base class.
Such multiple inheritance is necessiated by the fact that
it is impossible to derive all possible service classes
from a common base, a typical example of such case is
wxPMView class, which is a kind of wxDocumnet, however, the
latter cannot be made derivative of wxPMService. To solve
such dilemma, wxPMView becomes a service by inheriting
wxPMService interface as a second base class. This class
defines methods essential to any service, thus it's important
to describe it first:

	virtual bool Start();
	virtual bool Stop();
	
	virtual bool IsStarted();
	virtual void SetIsStarted( bool isStarted );
	
	virtual wxPMMergableMenuChain* GetMergableMenuChain();
	
	virtual bool SerializeState( wxPMSerializer& ser );
	
	virtual wxObject* GetObject()


The first four describe themselves. The first two are overridden 
to move any complex code from ctor and dtor to these virtual methods,
which can be overridden/mutated in the subclasses. Within them service
class may perform subscription of events, locate relevant services or
initialize it's gui-objects.

GetMergableMenuChain() - returns not NULL value if service wishes to
add it's specific menu commands, which can be inserted virtually into
any part of menu-tree.

SerializeState( wxPMSerializer& ser ) can be overridden to save data,
related only to the current visual regimentation other service, e.g.
text editor may save X-Y position of the cursor. There shouldn't be 
any data saved or loaded which relates to project or particular storable 
document. The wxPMSerializer argument is a derivative of wxConfigBase which will
provide human-readable storage for the state. More about this class later.

First it is assumed and required that a service class will always have 
wxObject as it's possibly distant base class. It also is derived
from wxPMSerivce (the latter is derived from nothing as mentioned),
for that reason, any give code in PMF cannot cast a reference to 
wxPMService to wxObject in order to know the exact class of the
service (using wxObject::IsKindOf()), e.g. the fragment

void foo( wxPMService* ref )
{
	wxObject* objPtr = (wxObject*)ref;
}

will compile ok, but the cast produces reference to 
incorrect v-method-table (i've tested this several times),
therefor the only solution is to have each service override

	virtual wxObject* GetObject()

of the inherited service-interfaces, to return properly casted
pointer, because such cast is correct only in the case when,
the the end-class of of the reference is known to compiler, e.g.

virtual wxObject* wxView::GetObject()
{
	return (wxObject)this; // the type of this known, thus
			       // compiler "adjusts" pointer to
			       // the correct virtual table
}

This method should be overridden by all classes which comply with
wxPMService interfaces.

I've only have experimented yet (with MSDev 4.0), not check yet
what the C++ ARM has to say about it. 

It would be could if one tests if the "trick" works with other
compilers.


5. wxPMDocument class
=====================

As mentioned in proposal, document can be hierarchically composed
of subbasements, the nesting level of which is not limited. Methods:

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

	virtual void AddSubdocument( wxPMDocument* pSubdoc );
	virtual void RemoveSubdocument( wxPMDocument* pSubdoc );
	virtual PMDocumentListT& GetSubdocuments();

	// overidables:
	
	virtual bool UseSerializer(); 

	virtual bool SavePMDocument( wxOutputStream& s );
	virtual bool LoadPMDocument( wxInputStream& s );
	
	virtual bool SerializePMDocument( wxPMSerializer& ser );
	virtual bool SerializeState( wxPMSerializer& ser );

It is important to note, that all methods related to accessing and
saving/loading of this run-time hierarchy are mostly defined in this 
base class. It's subclasses override them or add only few more methods 
specific only to the subclass.

UseSerializer() - returns TRUE by default, indicating that saving/loading
of documents non-visual data should proceed using wxPMSerializer, which
as mentioned provides human-readable storage. Using this approach, methods

	virtual bool SerializePMDocument( wxPMSerializer& ser );
	virtual bool SerializeState( wxPMSerializer& ser );

should be overridden instead of 

	virtual bool SavePMDocument( wxOutputStream& s );
	virtual bool LoadPMDocument( wxInputStream& s );
	
which do semantically should do the same, except the non-visual data
is stored/loaded using given binary streams.

See details, section for explanation why SaveDocument()/LoadDocument()
of wxDocument class are not used by PMF.

	virtual bool SerializeState( wxPMSerializer& ser );

is overridden method of wxPMService, which stores visual-data related to
the document's current state. Notice, that state-serialization in PMF
is never done by storing data into streams, because it is usually a bad
practise to store configuration info into a binary file. Plus the fact,
that wxPMSerializer provides Exchage(..) mehtods which allow serialization
to performed consistently and more briefly within one method, without 
"if"'s for loading or saving.

	virtual void SetFileInfo( wxPMFileInfo* pFile );
	virtual wxPMFileInfo* GetFileInfo();

used for associating document with a storage file, described in
details section.

6. Listener interfaces
======================

Before describing derivatives of wxPMDocument, it is worthwhile to 
mention listener interfaces, which are used by other services for
reacting to the actions performed on the document or workplace objects,
since each action of potential interest is reflected to these interfaces.

wxPMWorkplaceListener notify about the following:

	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 OnViewActiavated( wxPMView& view, wxPMView* pPrevView );
	virtual void OnActiveProjectSet( wxPMProject& project );

most of these notifications are reacted upon in gui-related classes, such as
wxPMWorkplaceBrowserPane class which mirrors a composition of workplace and
it's project into nodes of it's tree-control. This implies that, document-related 
non-visual information is not managed by these extension classes, instead it
maintained within the classes of PMF's core category.

wxPMBootstrapServiceListener notify about the following:

	virtual void OnServiceStarted( wxPMService& service );
	virtual void OnServiceStopped( wxPMService& service );

	virtual void OnPaneShown( wxPMPane& pane );
	virtual void OnPaneHidden( wxPMPane& pane );

First two can be used by classes which, for some reason, have
to monitor activation/deactivation of services, perhaps internally
using IsKindOf() to see if the given service is of interests. Could
could be used by services which are started earlier then those, 
notifications from which the wish to receive, because subscription
is not possible while the service which sends them is not started yet.

The latter two are taken by wxPMLayoutAlgorithm class, which
does relayouting of corresponding windows in the main-frame to 
match change visibility of panes.

For more details of why listeners are not meant to receive actions
in an ordered manner of notifications/subscriptions, like it can
be achieved using wxEvtHandler mechanism, see details section.


7. wxPMProject class
====================

Is derivative of wxPMDocument, adds following methods specific only
to the project-document:

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

	virtual void RemoveFile( wxPMFileInfo* pFile );
	virtual bool ActivateFileInEditor( wxPMFileInfo* pFile );
	
	virtual PMFileInfoListT& GetFiles();
	
which manipulate the aggregated array of wxPMFileInfo objects. After
that is done, it notifications are sent to all subscribed 
wxPMWorkplaceListenr listeners.

Overridden methods of wxPMDocument 
	
	virtual bool UseSerializer(); 
	virtual bool SerializePMDocument( wxPMSerializer& ser );

the first returns TRUE, to indicate that class prefers to store non-visual 
data of the project in a human-readable format, and consequently implements
SerializePMDocument() which takes serializer. It is still possible to
override the first method to store custom projects into binary streams,
but as mentioned, this is not recommended.

SerializePMDocument() stores/loads it's list of wxPMFileInfo* objects.
By overriding it, the method of base class should be invoked first,
to store the file list and other possible contents common to any 
type of project, after that they serialize their specific data.

The class does not override

	virtual bool SerializeState( wxPMSerializer& ser );
	
method of wxPMDocument, since project documents have no visual
appearance, thus do not posses any visual state.


8. wxPMWorkplace class
======================

As mentioned in proposal, only one workplace can say opened at 
a time, this has effect that instance of wxPMWorkplace class is 
always a top-level document of run-time doc. containment hierarchy.

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

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

	// type-safe methods for accessing subbasements 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 );


TBD::.. the rest