/*	XDocument.h
 *
 *		This is the root document class.
 *
 *		The way the document works is to insert itself in the XGDispatch
 *	list between the XGAppCore class and the XGWindow which displays
 *	the document's contents.
 *
 *		A document then can watch incomming messages and help regulate
 *	how those messages are handled
 */

/**********************************************************************

  YAAF is Copyright 1997-1999 by William Woody.

  Redistribution and use in source and binary forms, with or without 
  modification, are permitted provided that the following conditions 
  are met:

  Redistributions of source code must retain the above copyright notice, 
  this list of conditions and the following disclaimer.

  Neither the name of the copyright holder or other contributors may
  be used to promote products derived from this software without
  specific written prior permission.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 
  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 
  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 
  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 
  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
  SOFTWARE.
  
  Contact:   woody@alumni.caltech.edu
  Web page:  http://www.pandawave.com/yaaf/

**********************************************************************/

#ifndef PandaWave_XDOCUMENT
#define PandaWave_XDOCUMENT

#include <XConfig.h>
#include <XEvent.h>
#include <XDynArray.h>

/**@name Document Processing
 *
 *		These classes provide the basics of YAAF document processing.
 *
 *		The document model used by YAAF is relatively simple. A single
 *	document object (an XGDocument) contains a number of overrides which
 *	give you the chance to reply to "save", "save as", and "revert"
 *	calls. This document also contains pointers to one or more "XGDocEditor"
 *	objects, a mix-in class which provides callbacks for handling document
 *	processing events.
 *
 *		Normally you would mix in the XGDocEditor object into your
 *	document editor (such as a text editor XGView), and hook it into
 *	the XGDocument object when it's created. Then, the XGDocument can
 *	indicate to the XGDocEditor when the document is dirty and needs
 *	updating.
 *
 *		Of course you don't need to use this model; in fact, it's
 *	possible using the XGForm to emulate much of the same functionality.
 */
 
//@{

/************************************************************************/
/*																		*/
/*	Randomness															*/
/*																		*/
/************************************************************************/

class XGDocForm;
class XGDocument;

/************************************************************************/
/*																		*/
/*	Classes																*/
/*																		*/
/************************************************************************/

/*$	XGDocEditor
 *
 *		This defines the basic document editor object. This is a mixin
 *	class which adds support to a view or control for when a control
 *	edits into a document
 */

class XGDocEditor {
	public:
								XGDocEditor();
		virtual					~XGDocEditor();
		
		/*
		 *	Methods for making this thing work
		 */
		
		void					AttachDocument(XGDocument *);
		void					DetachDocument();
		
		/*
		 *	Document editor events
		 */
		 
		virtual void			DoDocumentInitialize();
		virtual void			DoDocumentTerminate();
		
		virtual void			DoDocumentChanged();
		virtual void			DoDocumentRenamed();
		virtual void			DoDocumentRevert();
		virtual void			DoDocumentSaved();
		
	protected:
		/*$	XGDocEditor::GetDocument
		 *
		 *		Returns a pointer to the document associated with
		 *	this particular document editor.
		 */
		
		XGDocument				*GetDocument()
									{
										return fDocument;
									}
	private:
		XGDocument				*fDocument;
		XGDocEditor				*fNext;
		
	friend class XGDocument;
};

/*$	XGDocument
 *
 *		This is the basic document class. This is the root object used
 *	for defining a document. This defines an abstraction of an object
 *	which stores the contents of a file that's being edited by various
 *	XGDocEditor objects.
 */

class XGDocument : public XGDispatch {
	public:
								XGDocument();
		virtual					~XGDocument();
		
		/*
		 *	Send messages up to my editors
		 */
		
		void					DocumentChanged();
		void					DocumentRevert();
		void					DocumentRenamed();
		void					DocumentSaved();
		

		/*
		 *	Document save/restore hooks
		 */
		
		/*$	XGDocument::IsDocumentDirty
		 *
		 *		Returns 'true' if this document is dirty and needs to be
		 *	saved to file.
		 */
		
		virtual bool			IsDocumentDirty();

		/*$	XGDocument::IsDocumentNamed
		 *
		 *		Returns 'true' if this document has a file name.
		 */
		
		virtual bool			IsDocumentNamed() = 0;

		/*$	XGDocument::GetDocumentName
		 *
		 *		Returns the name of this document.
		 */
		
		virtual void			GetDocumentName(char *) = 0;

		/*$	XGDocument::DoDocumentSave
		 *
		 *		Attempts to save this document. Returns 'true' if the
		 *	file was successfully saved.
		 */
		
		virtual bool			DoDocumentSave() = 0;

		/*$	XGDocument::DoDocumentSaveAs
		 *
		 *		Attempts to save this document to a new file. Returns
		 *	'true' if successful.
		 */
		
		virtual bool			DoDocumentSaveAs() = 0;

		/*$	XGDocument::DoDocumentRevert
		 *
		 *		Reverts the contents of this file from the values
		 *	written to disk.
		 */
		
		virtual void			DoDocumentRevert() = 0;
		
		DECLAREDISPATCH
		long					DoGetMenuStatus(long,void *);
		long					DoMenuCommand(long,void *);
		long					DoPostPeriodic(long,void *);

	protected:
		XGDocEditor				*GetFirstEditor()
									{
										return fList;
									}
		static XGDocEditor		*GetNextEditor(XGDocEditor *e)
									{
										return e->fNext;
									}

		XGDispatch				*GetParentDispatch();
		
	private:
		bool					fDirty;
		bool					fChanged;
		XGDocEditor				*fList;
		XGDocForm				*fForm;
		
		long					fDocFormCount;
		
	friend class XGDocEditor;
	friend class XGDocForm;
};

#endif /* PandaWave_XDOCUMENT */

//@}
