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


		#include "scene3d/scene.h"
		#include "scene3d/mlight.h"
		#include "scene3d/mobject.h"
		#include "scene3d/mcamera.h"
		#include "scene3d/mtrigger.h"
		#include "scene3d/instance.h"
		#include "scene3d/mconstraint.h"
		#include "scene3d/group.h"
		#include "scene3d/mitem_event_interface.h"
		#include "physic/physic_world.h"
		#include "physic/physic_constraint.h"

		using namespace GS::S3D;


//------------------------------------------------------------------------------
uint				Scene::GetItemCountByType(MItemType type) const
{
	uint count = 0;
	ListForeachPtr(MItem *, i, item_list)
		if	(i->GetItemType() == type)
			++count;
	return count;
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
template <class T> T *DuplicateItemType(MItem *item, T *clone, Scene *scene)
{
	if	(clone)
	{
		GS::AutoPtr <GS::NML::Tag> tag(((T *)item)->AsMetaTag());
		scene->SetupItemComponents(clone);
		clone->FromMetaTag(*tag);
		scene->AddItem(clone, false);
	}
	return clone;
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
MItem				*Scene::DuplicateItem(MItem *item)
{
	MItem *new_instance = NULL;

	switch (item->GetItemType())
	{
		case Type_Camera:		new_instance = DuplicateItemType <MCamera> (item, new MCamera, this); break;
		case Type_Object:		new_instance = DuplicateItemType <MObject> (item, new MObject, this); break;
		case Type_Light:		new_instance = DuplicateItemType <MLight> (item, new MLight, this); break;
		case Type_Trigger:		new_instance = DuplicateItemType <MTrigger> (item, new MTrigger, this); break;
		case Type_Constraint:	new_instance = DuplicateItemType <MConstraint> (item, new MConstraint(physic_world->NewConstraint()), this); break;

		case Type_Instance:
		{
			Instance *i = (Instance *)(new_instance = DuplicateItemType <Instance> (item, new Instance, this));

			if	(((Instance *)item)->instance_group)
				i->Instantiate(this);

			if	(i->instance_group)
				i->instance_group->Setup();

			i->Setup(physic_world);
		}
		break;

		default: break;
	}

	// Duplicate hierarchy.
	if	(new_instance)
		new_instance->GetBaseItem()->SetParent(item->GetBaseItem()->GetParent());

	return new_instance;
}
//------------------------------------------------------------------------------
