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


		#include "core/light.h"
		#include "metafile/nml_object.h"
		#include "reflection/c_refl.h"
		#include "log/log.h"

		using GS::Core::Light;
		using GS::NML::Tag;
		using namespace GS::Reflection;


//------------------------------------------------------------------------------
Enum::Dict Light::model_dict[] =
{
	{	Model_None, "None"	},
	{	Model_Point, "Point"	},
	{	Model_Linear, "Parallel"	},
	{	Model_Spot, "Spot"	}
};
Enum::Dict Light::shadow_dict[] =
{
	{	Shadow_None, "None"	},
	{	Shadow_ProjectionMap, "PMap"	},
	{	Shadow_Map, "Map"	}
};
Enum::Dict Light::falloff_dict[] =
{
	{	Falloff_Linear, "Linear"	},
	{	Falloff_InvDist, "InvDist"	},
	{	Falloff_InvDist2, "InvDist2"	}
};
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
Property	Light::serializable[] =
{
	{	Property::EnumProp, "Type", offsetof(Light, model), model_dict	},
	{	Property::EnumProp, "Falloff", offsetof(Light, falloff), falloff_dict	},
	{	Property::FloatProp, "Range", offsetof(Light, range), 0	},
	{	Property::FloatProp, "VolumeRange", offsetof(Light, volume_range), 0	},
	{	Property::FloatProp, "ClipDistance", offsetof(Light, clip_distance), 0	},

	{	Property::StringProp, "ProjectionMap", offsetof(Light, projection_texture), 0	},

	{	Property::FloatProp, "DiffuseIntensity", offsetof(Light, diffuse_intensity), 0	},
	{	Property::FloatProp, "SpecularIntensity", offsetof(Light, specular_intensity), 0	},

	{	Property::FloatProp, "ConeAngle", offsetof(Light, cone_angle), 0	},
	{	Property::FloatProp, "EdgeAngle", offsetof(Light, edge_angle), 0	},
	{	Property::FloatProp, "ZNear", offsetof(Light, z_near), 0	},

	{	Property::EnumProp, "Shadow", offsetof(Light, shadow), shadow_dict	},
	{	Property::FloatProp, "ShadowBias", offsetof(Light, shadow_bias), 0	},
	{	Property::FloatProp, "ShadowDistribution", offsetof(Light, shadow_distribution), 0	},
	{	Property::FloatProp, "ShadowRange", offsetof(Light, shadow_range), 0	},
	{	Property::BoolProp, "ShadowCastAll", offsetof(Light, shadow_cast_all), 0	},

	{	Property::BoolProp, "Volumetric", offsetof(Light, volumetric), 0	},
	{	Property::FloatProp, "VolumetricSampleStep", offsetof(Light, volumetric_sample_step), 0	},
	{	Property::FloatProp, "VolumetricThick", offsetof(Light, volumetric_thickness), 0	},
	{	Property::FloatProp, "VolumetricRange", offsetof(Light, volumetric_range), 0	},

	{	Property::InvalidProp, 0, 0	}
};
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
bool				Light::FromMetaTag(Tag &t)
{
	SetDefaults();
	if	((t.name != "Light") || !GenericObjectFromMetaTag(t, this, serializable))
		return false;
	if	(Tag *c = t.GetTag("Item"))			Item::FromMetaTag(*c);
	if	(Tag *c = t.GetTag("Diffuse"))		diffuse_color.FromMetaTag(*c);
	if	(Tag *c = t.GetTag("Specular"))		specular_color.FromMetaTag(*c);
	if	(Tag *c = t.GetTag("ShadowColor"))	shadow_color.FromMetaTag(*c);
	return true;
}
Tag					*Light::AsMetaTag()
{
	Tag *t = new Tag("Light");
	t->AddChild(Item::AsMetaTag());
	t->AddChild(diffuse_color.AsMetaTag("Diffuse"));
	t->AddChild(specular_color.AsMetaTag("Specular"));
	t->AddChild(shadow_color.AsMetaTag("ShadowColor"));
	return GenericObjectToMetaTag(t, this, serializable);
}
//------------------------------------------------------------------------------
