#include "PajaTypes.h"
#include "Vector3C.h"
#include <vector>
#include "ScenegraphItemI.h"


using namespace PajaTypes;
using namespace FileIO;



static
void
TRACE( const char* szFormat, ...  )
{
	char	szMsg[256];
	va_list	rList;
	va_start( rList, szFormat );
	_vsnprintf( szMsg, 255, szFormat, rList );
	va_end( rList );
	OutputDebugString( szMsg );
}




ScenegraphItemI::ScenegraphItemI() :
	m_pParent( 0 ),
	m_bHidden( false )
{
	m_rBaseTM = m_rBaseTM.set_identity();
}


ScenegraphItemI::~ScenegraphItemI()
{
}

void
ScenegraphItemI::set_name( const char* szName )
{
	m_sName = szName;
}

const char*
ScenegraphItemI::get_name()
{
	return m_sName.c_str();
}

void
ScenegraphItemI::set_parent_name( const char* szName )
{
	m_sParentName = szName;
}

const char*
ScenegraphItemI::get_parent_name()
{
	return m_sParentName.c_str();
}


ScenegraphItemI*
ScenegraphItemI::get_parent() const
{
	return m_pParent;
}

void
ScenegraphItemI::set_parent( ScenegraphItemI* pParent )
{
	m_pParent = pParent;
}

void
ScenegraphItemI::set_tm( const Matrix3C& rMat )
{
	m_rTM = rMat;
}

const Matrix3C&
ScenegraphItemI::get_tm()
{
	return m_rTM;
}

void
ScenegraphItemI::set_base_tm( const Matrix3C& rTM )
{
	m_rBaseTM = rTM;
}

const Matrix3C&
ScenegraphItemI::get_base_tm() const
{
	return m_rBaseTM;
}

void
ScenegraphItemI::set_hidden( bool bState )
{
	m_bHidden = bState;
}

bool
ScenegraphItemI::get_hidden() const
{
	return m_bHidden;
}


enum CameraChunksE {
	CHUNK_CGITEM_BASE			= 0x1000,
	CHUNK_CGITEM_HIDDEN			= 0x1001,
};

const uint32	CGITEM_VERSION = 1;

uint32
ScenegraphItemI::save( SaveC* pSave )
{
	uint32	ui32Error = IO_OK;
	float32	f32Matrix[12];
	uint32	i, j;

	// item base
	pSave->begin_chunk( CHUNK_CGITEM_BASE, CGITEM_VERSION );
		// write name
		std::string	sStr;
		
		sStr = m_sName;
		if( sStr.size() > 255 )
			sStr.resize( 255 );
		ui32Error = pSave->write_str( sStr.c_str() );

		// write parent name
		sStr =  m_sParentName;
		if( sStr.size() > 255 )
			sStr.resize( 255 );
		ui32Error = pSave->write_str( sStr.c_str() );

		// save TM
		for( i = 0; i < 4; i++ )
			for( j = 0; j < 3; j++ )
				f32Matrix[(i * 3) + j] = m_rTM[i][j];
		ui32Error = pSave->write( f32Matrix, sizeof( f32Matrix ) );

		// save base TM
		for( i = 0; i < 4; i++ )
			for( j = 0; j < 3; j++ )
				f32Matrix[(i * 3) + j] = m_rBaseTM[i][j];
		ui32Error = pSave->write( f32Matrix, sizeof( f32Matrix ) );


	pSave->end_chunk();

	// item hidden
	if( m_bHidden ) {
		pSave->begin_chunk( CHUNK_CGITEM_HIDDEN, CGITEM_VERSION );
		pSave->end_chunk();
	}

	return ui32Error;
}

uint32
ScenegraphItemI::load( LoadC* pLoad )
{
	uint32	ui32Error = IO_OK;
	float32	f32Matrix[12];
	uint32	i, j;
	char	szStr[256];

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

		switch( pLoad->get_chunk_id() ) {
		case CHUNK_CGITEM_BASE:
			{
				if( pLoad->get_chunk_version() == CGITEM_VERSION ) {

					// read name
					ui32Error = pLoad->read_str( szStr );
					m_sName = szStr;

					// read parent name
					ui32Error = pLoad->read_str( szStr );
					m_sParentName = szStr;

					// read TM
					ui32Error = pLoad->read( f32Matrix, sizeof( f32Matrix ) );
					for( i = 0; i < 4; i++ )
						for( j = 0; j < 3; j++ )
							m_rTM[i][j] = f32Matrix[(i * 3) + j];

					// read base TM
					ui32Error = pLoad->read( f32Matrix, sizeof( f32Matrix ) );
					for( i = 0; i < 4; i++ )
						for( j = 0; j < 3; j++ )
							m_rBaseTM[i][j] = f32Matrix[(i * 3) + j];
				}
			}
			break;

		case CHUNK_CGITEM_HIDDEN:
			{
				if( pLoad->get_chunk_version() == CGITEM_VERSION ) {
					m_bHidden = true;
				}
			}
			break;

		default:
			assert( 0 );
		}

		pLoad->close_chunk();

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

	return ui32Error;
}
