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


		#include "script_squirrel/engine_vm_debugger.h"
		#include "script_squirrel/cobject/vector_decl.h"
		#include "script_squirrel/cobject/cobject.h"
		#include "script_squirrel/engine_vm.h"
		#include "core/sound.h"
		#include "motion/motion.h"
		#include "scene3d/group.h"
		#include "scene3d/mobject.h"
		#include "scene3d/mlight.h"
		#include "scene3d/mcamera.h"
		#include "scene3d/mtrigger.h"
		#include "scene3d/scene.h"
		#include "project/project.h"
		#include "script/script_profiler.h"
		#include "script/scripted_object.h"
		#include "raytracer/raytracer_core.h"

		using namespace GS;
		using namespace GS::Script;


//------------------------------------------------------------------------------
String				SquirrelDebugger::FormatUserObjectParameter(CObjectType type)
{
	// Check for null safe ptr.
	void *test;
	CObject::Get(vm, -1, &test);
	if	(!test)
		return "Null";

	// Get type specific data.
	switch (type)
	{
		case typetag_Group:
		{
			S3D::Group *group;
			CObject::Get(vm, -1, (void **)&group, type);
			return String::Format("(id='%s', items=%d, ...)", group->name.c_str(), group->GetItemList().GetCount());
		}
		case typetag_Motion:
		{
			Core::Motion *motion;
			CObject::Get(vm, -1, (void **)&motion, type);
			return String::Format("(id='%s', channels=%d, length=%.2fs, ...)", motion->name.c_str(), motion->GetChannelList().GetCount(), motion->GetDuration().toSec());
		}
		case typetag_Geometry:
		{
			Render::Geometry *geometry;
			CObject::Get(vm, -1, (void **)&geometry, type);
			return String::Format("(id='%s', vertex=%d, material=%d, ...)", geometry->name.c_str(), geometry->material_table.GetCount());
		}
		case typetag_Picture:
		{
			Picture *picture;
			CObject::Get(vm, -1, (void **)&picture, type);
			return String::Format("(w=%dpx, h=%dpx, ...)", picture->GetWidth(), picture->GetHeight());
		}
		case typetag_Texture:
		{
			Render::Texture *texture;
			CObject::Get(vm, -1, (void **)&texture, type);
			return String::Format("(id='%s', w=%dpx, h=%dpx, ...)", texture->name.c_str(), texture->GetWidth(), texture->GetHeight());
		}
		case typetag_Sound:
		{
			Audio::Sound *sound;
			CObject::Get(vm, -1, (void **)&sound, type);
			return String::Format("(id='%s')", sound->name.c_str());
		}
		case typetag_Object:
		{
			S3D::MObject *object;
			CObject::Get(vm, -1, (void **)&object, type);
			return String::Format("(id='%s', uid=%d, geometry='%s', ...)", object->name.c_str(), object->GetUid(), object->geometry.IsEmpty() ? "None" : object->geometry.c_str());
		}
		case typetag_Light:
		{
			S3D::MLight *light;
			CObject::Get(vm, -1, (void **)&light, type);
			return String::Format("(id='%s', uid=%d, diffuse=%.2f, specular=%.2f, ...)", light->name.toUtf8(), light->GetUid(), light->diffuse_intensity, light->specular_intensity);
		}
		case typetag_Camera:
		{
			S3D::MCamera *camera;
			CObject::Get(vm, -1, (void **)&camera, type);
			return String::Format("(id='%s', uid=%d, fov=%.2f, ...)", camera->name.toUtf8(), camera->GetUid(), camera->GetFov());
		}
		case typetag_Trigger:
		{
			S3D::MTrigger *trigger;
			CObject::Get(vm, -1, (void **)&trigger, type);
			return String::Format("(id='%s', uid=%d, ...)", trigger->name.toUtf8(), trigger->GetUid());
		}
		case typetag_Scene3d:
		{
			S3D::Scene *scene;
			CObject::Get(vm, -1, (void **)&scene, type);
			return String::Format("(id='%s', items=%d, ...)", scene->name.toUtf8(), scene->GetItemList().GetCount());
		}
		case typetag_Item:
		{
			S3D::MItem *item;
			CObject::Get(vm, -1, (void **)&item, type);
			return String::Format("(id='%s', uid=%d, scripted=%s, ...)", item->name.toUtf8(), item->GetUid(), item->scripted_object.IsValid() && item->scripted_object->GetUnitList().GetCount() ? "True" : "False");
		}
		case typetag_Raytracer:
		{
			Raytrace::Raytracer *ray;
			CObject::Get(vm, -1, (void **)&ray, type);
			Raytrace::Configuration cfg = ray->GetConfiguration();
			return String::Format("(aa=%s, gi=%s, interlaced=%s, ...)", cfg.trace_aa ? "True" : "False", cfg.trace_gi ? "True" : "False", cfg.interlaced ? "True" : "False");
		}
		case typetag_Material:
		{
			Render::Material *material;
			CObject::Get(vm, -1, (void **)&material, type);
			return String::Format("(id='%s', ...)", material->name.toUtf8());
		}
		case typetag_Metafile:
		{
			NML::File *metafile;
			CObject::Get(vm, -1, (void **)&metafile, type);
			return String::Format("(path='%s', ...)", metafile->name.toUtf8());
		}
		case typetag_Metatag:
		{
			NML::Tag *metatag;
			CObject::Get(vm, -1, (void **)&metatag, type);
			return String::Format("(id='%s', ...)", metatag->name.toUtf8());
		}
		case typetag_ColShape:
		{
			S3D::PhysicShape *shape;
			CObject::Get(vm, -1, (void **)&shape, type);

			String	_type = "...";
			switch (shape->GetType())
			{
				case S3D::PhysicShape::TypeBox:		_type = "Box";		break;
				case S3D::PhysicShape::TypeCone:	_type = "Cone";		break;
				case S3D::PhysicShape::TypeSphere:	_type = "Sphere";	break;
				case S3D::PhysicShape::TypeConvex:	_type = "Convex";	break;
				case S3D::PhysicShape::TypeMesh:	_type = "Mesh";		break;

				default: break;
			}
			return String::Format("(type=%s, mass=%.2f, ...)", _type.toUtf8(), shape->mass);
		}
		default: break;
	}
	return String("...");
}
//------------------------------------------------------------------------------

EngineDebugger::EngineDebugger(EngineVM &vm) : SquirrelDebugger(vm) {}