#include "PajaTypes.h"
#include "Vector3C.h"
#include "ControllerC.h"
#include "ContFloatC.h"
#include "ContVector3C.h"
#include "LightC.h"

using namespace Composition;
using namespace PajaTypes;
using namespace FileIO;


LightC::LightC() :
	m_rColor( 1, 1, 1 ),
	m_f32Multiplier( 1 ),
	m_pPosCont( 0 ),
	m_pTargetCont( 0 )
{
	// empty
}

LightC::~LightC()
{
	delete m_pPosCont;
	delete m_pTargetCont;
}

int32
LightC::get_type()
{
	return CGITEM_LIGHT;
}

void
LightC::set_position( const Vector3C& rPos )
{
	m_rPos = rPos;
}

void
LightC::set_target( const Vector3C& rPos )
{
	m_rTarget = rPos;
}

const
Vector3C&
LightC::get_position()
{
	return m_rPos;
}

const
Vector3C&
LightC::get_target()
{
	return m_rTarget;
}

void
LightC::set_color( const ColorC& rVal )
{
	m_rColor = rVal;
}

const
ColorC&
LightC::get_color()
{
	return m_rColor;
}

void
LightC::set_multiplier( float32 f32Val )
{
	m_f32Multiplier = f32Val;
}

float32
LightC::get_multiplier()
{
	return m_f32Multiplier;
}

void
LightC::eval_state( int32 i32Time )
{
	if( m_pPosCont )
		m_rPos = m_pPosCont->get_value( i32Time ); 
	if( m_pTargetCont )
		m_rTarget = m_pTargetCont->get_value( i32Time ); 
}

void
LightC::set_position_controller( ContVector3C* pCont )
{
	m_pPosCont = pCont;
}

ContVector3C*
LightC::get_position_controller()
{
	return m_pPosCont;
}

void
LightC::set_target_controller( ContVector3C* pCont )
{
	m_pTargetCont = pCont;
}

ContVector3C*
LightC::get_target_controller()
{
	return m_pTargetCont;
}


enum LightChunksE {
	CHUNK_LIGHT_BASE			= 0x1000,
	CHUNK_LIGHT_STATIC			= 0x1001,
	CHUNK_LIGHT_CONT_POS		= 0x2000,
	CHUNK_LIGHT_CONT_TARGET		= 0x3000,
};

const uint32	LIGHT_VERSION = 1;


uint32
LightC::save( SaveC* pSave )
{
	uint32	ui32Error = IO_OK;

	std::string	sStr;
	float32	f32Temp[3];

	// light base
	pSave->begin_chunk( CHUNK_LIGHT_BASE, LIGHT_VERSION );
		ScenegraphItemI::save( pSave );
	pSave->end_chunk();

	// light base (static)
	pSave->begin_chunk( CHUNK_LIGHT_STATIC, LIGHT_VERSION );
		// position
		f32Temp[0] = m_rPos[0];
		f32Temp[1] = m_rPos[1];
		f32Temp[2] = m_rPos[2];
		ui32Error = pSave->write( f32Temp, sizeof( f32Temp ) );

		// color
		f32Temp[0] = m_rColor[0];
		f32Temp[1] = m_rColor[1];
		f32Temp[2] = m_rColor[2];
		ui32Error = pSave->write( f32Temp, sizeof( f32Temp ) );

		// mulltiplier
		ui32Error = pSave->write( &m_f32Multiplier, sizeof( m_f32Multiplier ) );

	pSave->end_chunk();

	// pos controller
	if( m_pPosCont ) {
		pSave->begin_chunk( CHUNK_LIGHT_CONT_POS, LIGHT_VERSION );
			m_pPosCont->save( pSave );
		pSave->end_chunk();
	}

	// tgt controller
	if( m_pTargetCont ) {
		pSave->begin_chunk( CHUNK_LIGHT_CONT_TARGET, LIGHT_VERSION );
			m_pPosCont->save( pSave );
		pSave->end_chunk();
	}

	return ui32Error;
}

uint32
LightC::load( LoadC* pLoad )
{
	uint32	ui32Error = IO_OK;
	float32	f32Temp[3];

	while( (ui32Error = pLoad->open_chunk()) == IO_OK ) {

		switch( pLoad->get_chunk_id() ) {
		case CHUNK_LIGHT_BASE:
			if( pLoad->get_chunk_version() == LIGHT_VERSION )
				ScenegraphItemI::load( pLoad );
			break;

		case CHUNK_LIGHT_STATIC:
			if( pLoad->get_chunk_version() == LIGHT_VERSION ) {
				// position
				ui32Error = pLoad->read( f32Temp, sizeof( f32Temp ) );
				m_rPos[0] = f32Temp[0];
				m_rPos[1] = f32Temp[1];
				m_rPos[2] = f32Temp[2];

				// color
				ui32Error = pLoad->read( f32Temp, sizeof( f32Temp ) );
				m_rColor[0] = f32Temp[0];
				m_rColor[1] = f32Temp[1];
				m_rColor[2] = f32Temp[2];

				// mult
				ui32Error = pLoad->read( &m_f32Multiplier, sizeof( m_f32Multiplier ) );
			}
			break;

		case CHUNK_LIGHT_CONT_POS:
			if( pLoad->get_chunk_version() == LIGHT_VERSION ) {
				ContVector3C*	pCont = new ContVector3C;
				ui32Error = pCont->load( pLoad );
				m_pPosCont = pCont;
			}
			break;

		case CHUNK_LIGHT_CONT_TARGET:
			if( pLoad->get_chunk_version() == LIGHT_VERSION ) {
				ContVector3C*	pCont = new ContVector3C;
				ui32Error = pCont->load( pLoad );
				m_pPosCont = pCont;
			}
			break;

		default:
			assert( 0 );
		}

		pLoad->close_chunk();

		if( ui32Error != IO_OK && ui32Error != IO_END ) {
			return ui32Error;
		}
	}

	return ui32Error;
}
