// Copyright 1999
// College of Computer Science
// Northeastern University Boston MA 02115

// This software may be used for educational purposes as long as this copyright
// notice is retained at the top of all files

// Should this software be modified, the words "Modified from Original" must be
// included as a comment below this notice

// All publication rights are retained.  This software or its documentation may
// not be published in any media either in whole or in part.

///////////////////////////////////////////////////////////////////////////////

// GraphicsObject.h

// GraphicsObject is the abstract base class for graphics objects
// that write directly to the system or change system state
//
// IndirectObject is the abstract base class for graphics objects
// that call other GraphicsObject's and IndirectObject's to do
// their work
//
// Graphics objects, direct or indirect, will be called widgets
//
// See GraphicsWidget.h and GraphicsWidget.cpp

///////////////////////////////////////////////////////////////////////////////

#ifndef GRAPHICSOBJECT_H_
#define GRAPHICSOBJECT_H_

#include "CHeaders.h"


// must forward declare GraphicsWindow to avoid circular include chain

class EXPORT GraphicsWindow;

// forward declarations

class EXPORT GraphicsObject;
class EXPORT IndirectObject;


// required declaration of Array<GraphicsObject*>
// to satisfy Visual C++ DLL rules

#if defined(CORE_PLATFORM_WIN32)
#pragma warning(disable: 4231)
#endif	// end WIN32 specific

TEMPLATE_PREFIX template class EXPORT Array<GraphicsObject*>;


///////////////////////////////////////////////////////////////////////////////

class EXPORT GraphicsBase {

private:

	// Permanent variable says whether action should be saved in
	// window DrawList

	bool Permanent;

public:

	GraphicsBase() : Permanent(true) { };

	virtual ~GraphicsBase() { };

	// controls for Permanent variable

	void SetPermanent() { Permanent = true; };

	void SetTemporary() { Permanent = false; };

	bool IsPermanent() const { return Permanent; };
};


///////////////////////////////////////////////////////////////////////////////

class EXPORT GraphicsObject : public GraphicsBase {

	// make GraphicsWindow a friend of GraphicsObject
	friend class GraphicsWindow;

private:

	// DrawDetails does the actual draw or modify action on the
	// graphics window assuming that the window is prepared
	//
	// DrawDetails must be defined in each derived widget class
	// of GraphicsObject

	virtual void DrawDetails(GraphicsWindow& G) const = 0;

public:

	// default constructor

	GraphicsObject() { };


	// trivial default destructor
	// must be virtual to support derived widget classes

	virtual ~GraphicsObject() { };


	// Clone must be defined in each derived widget class of GraphicsObject
	//
	// Clone must deliver a pointer to a new heap based widget.  This clone
	// is released automatically when the window DrawList is cleared.
	//
	// The clone widget represents how the object should be drawn at this
	// moment
	//
	// This design permits a parametrized widget to clone itself with its
	// parameters set so clone is ready to draw
	//
	// In particular, clone need not be a strict copy of the original

	virtual GraphicsObject* Clone() const = 0;


	// The public function Draw provides the interface for the user to ask
	// the widget to draw into the graphics window G
	//
	// Underneath this function will:
	//
	// Step 1. Prepare system graphics resources
	// Step 2. Clone the object
	// Step 3. Call clone->DrawDetails() to do the graphics
	// Step 4. If object is permanent insert the clone into the G.DrawList
	// Step 5. Release system graphics resources
	//
	// This design permits widget actions to be focused in DrawDetails and
	// avoids needless repetition of standard GraphicsObject code

	void Draw(GraphicsWindow& G) const;


	// Draw with an index parameter finds the graphics window by its index
	// in the GraphicsWindowList
	//
	// This permits drawing even if the window variable is not in scope
	//
	// The default index of -1 means draw into the current graphics window

	void Draw(int index = -1) const;

}; // GraphicsObject

///////////////////////////////////////////////////////////////////////////////

class EXPORT IndirectObject : public GraphicsBase {

	// make GraphicsWindow a friend of IndirectObject
	friend class GraphicsWindow;

private:

	// DrawDetails does the actual draw or modify action on the
	// graphics window assuming that the window is prepared
	//
	// DrawDetails must be defined in each derived widget class
	// of IndirectObject
	//
	// This function must draw by using GraphicsObject widgets
	// or by using other IndirectObject widgets
	//
	// An IndirectObject does not write directly to the system

	virtual void DrawDetails(GraphicsWindow& G) const = 0;

public:

	// default constructor

	IndirectObject() { };


	// trivial default destructor
	// must be virtual to support derived widget classes

	virtual ~IndirectObject() { };


	// The public function Draw provides the interface for the user to ask
	// the widget to draw into the graphics window G

	void Draw(GraphicsWindow& G) const { DrawDetails(G); };


	// Draw with an index parameter finds the graphics window by its index
	// in the GraphicsWindowList
	//
	// This permits drawing even if the window variable is not in scope
	//
	// The default index of -1 means draw into the current graphics window

	void Draw(int index = -1) const;

}; // IndirectObject

#endif // GRAPHICSOBJECT_H_

