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


		#include "scene3d/instance.h"
		#include "scene3d/mobject.h"
		#include "scene3d/group.h"
		#include "scene3d/scene.h"
		#include "script/scripted_object.h"

		using namespace GS::Core;
		using namespace GS::S3D;


//------------------------------------------------------------------------------
void				Instance::RenderSetup(ResourceFactories *f)
{
	if	(instance_group)
		instance_group->RenderSetup(f);
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
void				Instance::ComputeMinMax(GS::MinMax &minmax) const
{
	if	(!instance_group)
		return;

	MinMax l_minmax;
	const SharedList <MItem *> &items = instance_group->GetItemList();

	bool first = true;
	ListForeachPtr(MItem *, i, items)
		if	(i->GetItemType() == Type_Object)
		{
			MObject *o = (MObject *)i;
			o->ComputeLocalMinMax(l_minmax);

			if	(first)
					minmax = l_minmax;
			else	minmax.Grow(l_minmax);
			first = false;
		}
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
bool				Instance::Instantiate(Scene *owner)
{
	if	(instance_group)
		return true;
	if	(!owner || template_path.IsEmpty() || !isActive())
		return false;

	using namespace NML;
	File file;
	if	(Parser::Load(template_path, file))
	{
		// Load scene scripted object on this instance.
		if	(Tag *script_tag = file.GetTag("Scene:ScriptedObject;"))
			scripted_object->FromMetaTag(*script_tag);

		// Append template scene to this scene.
		owner->FromMetaFileStoreGroup(template_path, &instance_group, SceneIOAll & ~(SceneIOGlobals | SceneIOSettings | SceneIOHelper | SceneIOScript));
	}

	if	(instance_group)
	{
		instance_group->name = template_path;

		if	(do_not_parent)
				instance_group->Offset(GetMatrix());
		else	instance_group->SetRootItem(this);
	}
	return true;
}
void				Instance::FreeEditorInstance()
{
	instance_scene = NULL;
	instance_group = NULL;
}
//------------------------------------------------------------------------------

Instance::Instance()
{
	item_type = Type_Instance;
	mitem = (void *)((MItem *)this);

	instance_group = NULL;
	do_not_parent = false;
}
Instance::~Instance()
{
	// group is deleted by the scene it belongs to.
}
