/* -----------------------------------------------------------------------------
	GSFramework
	Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */


#ifndef	__NGROUP__
#define	__NGROUP__


		#include "scene3d/mitem.h"
		#include "motion/scene_motion_container.h"
		#include "automation/automation_player.h"
		#include "memory/bit_field.h"


namespace GS {
	class Matrix4;

	namespace Core { struct ResourceFactories; }
	namespace S3D {
		class MItem;

/*!
	@short	Group of managed items.
	@Note	The group root item is not part of the group.
	@author	Emmanuel Julien (ejulien@gsworks.fr)
*/
class	Group : public SharedObject
{
		MItem			*root;

		SharedList <MItem *> item_list;
		SharedList <Group *> group_list;

public:

enum
{
		Hidden			=	(1 << 0),
		Locked			=	(1 << 1)
};

		String			name;
		BitField		flags;

inline	MItem			*GetRootItem() const { return root; }
		void			SetRootItem(MItem *);

		/// Return the group item member list.
inline	const SharedList <MItem *> &GetItemList() const { return item_list; }

		/// Return the number of members in group.
inline	uint			GetMemberCount() const { return item_list.GetCount(); }

		MItem			*Item(const char *) const;
		MItem			*ItemFromUid(uint uid) const;
		bool			IsMember(const MItem *) const;

		MItem			*Add(MItem *, bool block_duplicate = false);
		bool			Remove(MItem *);

		Group			*GetGroup(const char *) const;
		bool			IsMember(const Group *) const;

		Group			*Add(Group *, bool block_duplicate = false);
		bool			Remove(Group *);

		/// Append a group content to this group.
		bool			AppendGroup(const Group &);

		/// Set the invisible flag of all items in group.
		void			SetInvisible(bool invisible);

		void			Offset(const Matrix4 &);
		void			Translate(float, float, float);
		void			Rotate(float, float, float);

		Core::SceneMotionContainer motion;

		/// Set motion on all group items.
		void			SetMotion(const char *name, Automation::SourceGroup ** = 0, float blend = Units::Sec(0.1), Automation::Player::AddSourceMode = Automation::Player::SourceSet, float weight = 1);

		void			RenderSetup(Core::ResourceFactories *);
		void			Setup();
		void			Reset();

		Group() : root(0) {}
};

	} // S3D
} // GS


#endif	// __NGROUP__
