/* (c) 1999-2000 Tino Schwarze, see COPYING for details */
/**
 * implementation of class cObject
 *
 * #include "cObject.hh"
 *
 * @see cObject.hh
 */

#include "cObject.hh"
#include "common.hh"

/**
 * constructor with initialization for name (default constructor)
	* @param name name to identify the object (optional)
	*/
cObject::cObject (const char *name)
{
	SetName (name);	// first set name to make debug message below more fancy
	ENTER_OBJECT_METHOD("cObject::cObject (pos,rot,name)");
}

/**
 * copy constructor
 	*/
cObject::cObject (const cObject &source)
{
	SetName (source.GetName ());

	ENTER_OBJECT_METHOD("cObject::cObject (const cObject &source)");

	// copy all childs
	for (childs_t::iterator iterator = mChilds.begin ();
		iterator != mChilds.end ();
		++iterator)	// that's the way STL implements for_each
	{
		// *iterator is a pointer to a cObject
		AddChild (*iterator);
	}

}


/**
 * destructor
 	*/
cObject::~cObject ()
{
	ENTER_OBJECT_METHOD("cObject::~cObject()");
	// note that destroying an object might involve destroying a
	// whole sub-tree of our scene (destruction is done implicitly as 
	// the childs member is destructed)

	delete mName;

	// delete all childs
	for (childs_t::iterator iterator = mChilds.begin ();
		iterator != mChilds.end ();
		++iterator)	// that's the way STL implements for_each
	{
		delete (*iterator);
	}

}

/**
 * initialization function
	*/
int cObject::Init ()
{
	/* I like STL! 'though it's quite difficult...
	// We iterate over all childs and execute the Init function.
	// for_each (childs.begin (), childs.end (), 
	//		mem_fun_ref (&cObject::Init));
	// GOTCHA! It does not work as it bypasses virtual methods.
	// We would end up calling _only_ cObject::Init but not a probably
	// overloaded version of a derived class.
	//
	// We need to go on foot then... 
	// well, sorry for random thoughts in source file.
	*/

	for (childs_t::iterator iterator = mChilds.begin ();
		iterator != mChilds.end ();
		++iterator)	// that's the way STL implements for_each
	{
		// call Init() for all childs, check for success
		if ((*iterator)->Init () != 0)
			return -1;	// bail out on error

	}

	return 0;
}

/**
 * perform object's action
	*/
void cObject::Activate ()
{
	ENTER_OBJECT_METHOD ("cObject::SetUpForDrawing ()");

	// let all childs perform their action as well
	for (childs_t::iterator iterator = mChilds.begin ();
		iterator != mChilds.end ();
		++iterator)	// that's the way STL implements for_each
	{
		(*iterator)->Activate ();	// as easy as pie
	}

	Deactivate ();
}

/**
 * actions to perform after drawing the object and it's siblings
	*/
void cObject::Deactivate ()
{
	ENTER_OBJECT_METHOD ("cObject::CleanUpAfterDrawing ()");
}

/**
 * add new child object (copy the pointer to it)
 	* @param child pointer to cObject object
	* @return pointer to copied cObject object for use by program
	*/
cObject *cObject::AddChild (cObject *child)
{
	// insert child at the end of our vector<cObject> by implicitly cloning 
	// it return dereferenced iterator
	return *(mChilds.insert (mChilds.end(), child));
}


/**
 * determine whether the object has got any siblings
 	*/
bool cObject::HasChilds ()
{
	return (! (mChilds.empty ()));
}


/**
 * query name of object
 	* @return name of object, default name if no other name was set
	*/
const char *cObject::GetName () const
{

	if (mName != NULL)
	{
		return mName->c_str ();
	}
	else
	{
		return GetDefaultName ();
	}

}


/**
 * set name of object
 	* @param name new name of object (NULL = use default name)
	*/
void cObject::SetName (const char *name)
{

	if (name == NULL)
	{

		if (mName != NULL)
			delete mName;

		mName = NULL;
	}
	else
	{
		mName = new string (name);
	}

}

