/* (c) 1999-2000 Tino Schwarze, see COPYING for details */
/**@pkg cObject*/
/**
 * base class for any object
 *
 * #include "cObject.hh"
 *
 * -lMesaGL or -lGL
 *
 * @pkgdoc cObject
 */

#ifndef cObject_hh
#define cObject_hh

// get STL slist template (unfortunately not part of C++ standard but
// of SGI's STL implementation)
#include <slist.h>

#include <string> // include STL strings

// include OpenGL functions
#include <GL/gl.h>

// PROJECT INCLUDES (used classes)
//#include "cVertex.hh"
//#include "cMatrix.hh"

/**
 * This object provides any means neccessary to build a scene graph.
 *
 * It is intended to derive from it, overloading the DrawTheObject() and 
 * probably Init() methods.
 *
 * @note Uses STL vector template.
 * @note this is already OpenGL specific!
 * @note If we talk about a position, it's OpenGL's notion of a
 *       translation via glTranslatef, that means, that not the object
 *       but the object's coordinate system is translated!
 *       Take care of that!
 */
class cObject {

// LIFECYCLE
public:
	/** 
	 * a type for the list of childs an object has
	 *
	 * The scene graph is an n-ary tree, cObjects are the nodes.
	 *
	 *@@ We cannot store plain cObjects here since vector<> might invalidate
	 *@@ iterators during realloc()'ing (thatswhy, we use slist<>)
	 *
	 * We make it public to provide limited access to child tree.
	 * @see #GetChildsBeginIterator
	 * @see #GetChildsEndIterator
	 */
	typedef slist<class cObject *> childs_t;

	/**
	 * constructor with initialization for name (default constructor)
		* @param name name to identify the object (optional)
		*/
	cObject (const char *name = NULL);

	/**
	 * copy constructor
	 	*/
	cObject (const cObject &);

	/**
	 * destructor
	 	*/
	virtual ~cObject ();

// OPERATORS
	/* boolean operations go there ;-> */
	//cObject &operator + (cObject &, cObject &) const
	//cObject &operator - (cObject &, cObject &) const
	//cObject &operator && (cObject &, cObject &) const

// OPERATIONS
	/**
	 * initialization function (candidate for overloading!)
	 * note: You *have to* call this function, even if overloaded!
	 *       (best way is to call cObject::Init after having done your
	 *       specific work)
	 *       You may not display anything during Init().
	 	* @return -1 on error, 0 on success
	 	*/
	virtual int Init ();

// ACCESS
	/**
	 * add new child object (copy it!)
	 	* @param child reference to cObject object
		* @return pointer to copied cObject object, NULL on error
		* @note child might/should be destroyed after adding it
		*/
	cObject *AddChild (cObject *child);

	/**
	 * determine whether the object has got any siblings
	 	*/
	bool HasChilds ();

	/**
	 * provide access to childs
	 	* @return const_iterator for childs
		*/
	childs_t::const_iterator GetChildsBeginIterator ()
	{
		return mChilds.begin();
	}

	/**
	 * determine iterator for end of child list
	 	* @return const_iterator
		*/
	childs_t::const_iterator GetChildsEndIterator ()
	{
		return mChilds.end ();
	}

	/**
	 * query name of object
	 	* @return name of object
	 	*/
	const char *GetName () const;

	/**
	 * set name of object
	 	* @param name name of object
		*/
	void SetName (const char *n);


protected:	// protected functions
// INTERNAL OPERATIONS

/**
 * The object is activated via Activate() to perform it's action.
 *
 * Activate() works as follows: (see implementation for details)
 * 1. call Activate() of all siblings
 * 2. Deactivate ()	(may be overloaded)
 */

	/**
	 * actions to perform before drawing the object and it's siblings
	 * (might be overloaded)
	 	*/
	virtual void Activate ();

	/**
	 * actions to perform after drawing the object and it's siblings
	 * (might be overloaded)
	 	*/
	virtual void Deactivate ();

	/**
	 * return default name of object (the poor man's RTTI)
	 *
	 * Every object within the scene graph can be associated a name.
	 * By default, the class of the object is used.
	 * @see #GetName
	 */
	virtual const char *GetDefaultName () const
	{
		return "cObject";
	}

// protected data - it may only be accessed after deriving from this class

	/**
	 * singly linked list of all childs (uses STLs slist template)
	 	*/
	childs_t mChilds;

	/**
	 * name of this object (defaults to class name)
	 *
	 * @see #GetDefaultName
	 */
	string *mName;
};

#endif	// ifndef cObject_hh

