
#include "PajaTypes.h"
#include "ColorC.h"
#include "MtlLayerC.h"

using namespace PajaTypes;
using namespace FileIO;
using namespace Import;


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 );
}




MtlLayerC::MtlLayerC() :
	m_f32SelfIllumination( 0 ),
	m_ui16Flags( LAYER_NONE ),
	m_ui16MappingChannel( 0 ),
	m_eMappingType( MAPPING_NONE ),
	m_eMappingAxis( MAPPING_AXIS_UV),
	m_f32Opacity( 1.0f ),
	m_pTextureHandle( 0 )
{
	// empty
}

MtlLayerC::~MtlLayerC()
{
	// empty
}

void
MtlLayerC::set_ambient( const ColorC &rAmbient )
{
	m_rAmbient = rAmbient;
}

void
MtlLayerC::set_diffuse( const ColorC &rDiffuse )
{
	m_rDiffuse = rDiffuse;
}

void
MtlLayerC::set_specular( const ColorC &rSpecular )
{
	m_rSpecular = rSpecular;
}

void
MtlLayerC::set_shininess( const float32 f32Shininess )
{
	m_f32Shininess = f32Shininess;
}

void
MtlLayerC::set_opacity( const float32 f32Opacity )
{
	m_f32Opacity = f32Opacity;
}

void
MtlLayerC::set_self_illumination( const float32 f32SelfIllum )
{
	m_f32SelfIllumination = f32SelfIllum;
}


const ColorC&
MtlLayerC::get_ambient() const
{
	return m_rAmbient;
}

const ColorC&
MtlLayerC::get_diffuse() const
{
	return m_rDiffuse;
}

const ColorC&
MtlLayerC::get_specular() const
{
	return m_rSpecular;
}

float32
MtlLayerC::get_shininess()
{
	return m_f32Shininess;
}

float32
MtlLayerC::get_opacity()
{
	return m_f32Opacity;
}

float32
MtlLayerC::get_self_illumination()
{
	return m_f32SelfIllumination;
}

		
void
MtlLayerC::set_texture( FileHandleC* pHandle )
{
	m_pTextureHandle = pHandle;
}

FileHandleC*
MtlLayerC::get_texture() const
{
	return m_pTextureHandle;
}

void
MtlLayerC::set_mapping_type( MappingTypeE eType )
{
	m_eMappingType = eType;
}

MtlLayerC::MappingTypeE
MtlLayerC::get_mapping_type() const
{
	return m_eMappingType;
}

void
MtlLayerC::set_mapping_axis( MappingAxisE eAxis )
{
	m_eMappingAxis = eAxis;
}

MtlLayerC::MappingAxisE MtlLayerC::get_mapping_axis() const
{
	return m_eMappingAxis;
}


void
MtlLayerC::set_flags( uint16 ui16Flags )
{
	m_ui16Flags = ui16Flags;
}

void
MtlLayerC::add_flags( uint16 ui16Flags )
{
	m_ui16Flags |= ui16Flags;
}

void
MtlLayerC::del_flags( uint16 ui16Flags )
{
	m_ui16Flags &= ~ui16Flags;
}

uint16
MtlLayerC::get_flags()
{
	return m_ui16Flags;
}


void
MtlLayerC::set_mapping_channel( uint16 u16Ch )
{
	m_ui16MappingChannel = u16Ch;
}

uint16
MtlLayerC::get_mapping_channel()
{
	return m_ui16MappingChannel;
}

uint32
MtlLayerC::save( SaveC* pSave )
{
	uint32	ui32Error = IO_OK;
	uint32	ui32Tmp;
	uint8	ui8Color[4];

	//ambient
	ui8Color[0] = (uint8)(m_rAmbient[0] * 255.0f);
	ui8Color[1] = (uint8)(m_rAmbient[1] * 255.0f);
	ui8Color[2] = (uint8)(m_rAmbient[2] * 255.0f);
	ui8Color[3] = (uint8)(m_rAmbient[3] * 255.0f);
	ui32Error = pSave->write( ui8Color, 4 );

	//diffuse
	ui8Color[0] = (uint8)(m_rDiffuse[0] * 255.0f);
	ui8Color[1] = (uint8)(m_rDiffuse[1] * 255.0f);
	ui8Color[2] = (uint8)(m_rDiffuse[2] * 255.0f);
	ui8Color[3] = (uint8)(m_rDiffuse[3] * 255.0f);
	ui32Error = pSave->write( ui8Color, 4 );

	//specular
	ui8Color[0] = (uint8)(m_rSpecular[0] * 255.0f);
	ui8Color[1] = (uint8)(m_rSpecular[1] * 255.0f);
	ui8Color[2] = (uint8)(m_rSpecular[2] * 255.0f);
	ui8Color[3] = (uint8)(m_rSpecular[3] * 255.0f);
	ui32Error = pSave->write( ui8Color, 4 );

	// shininess
	ui32Error = pSave->write( &m_f32Shininess, sizeof( m_f32Shininess ) );

	// opacity
	ui32Error = pSave->write( &m_f32Opacity, sizeof( m_f32Opacity ) );

	// selfillum
	ui32Error = pSave->write( &m_f32SelfIllumination, sizeof( m_f32SelfIllumination ) );

	// flags
	ui32Error = pSave->write( &m_ui16Flags, sizeof( m_ui16Flags ) );

	// mapping channel
	ui32Error = pSave->write( &m_ui16MappingChannel, sizeof( m_ui16MappingChannel ) );

	// texture handle
	if( m_pTextureHandle )
		ui32Tmp = m_pTextureHandle->get_id();
	else
		ui32Tmp = 0xffffffff;
	ui32Error = pSave->write( &ui32Tmp, sizeof( ui32Tmp ) );

	// mapping type
	ui32Tmp = m_eMappingType;
	ui32Error = pSave->write( &ui32Tmp, sizeof( ui32Tmp ) );

	return ui32Error;
}

uint32
MtlLayerC::load( LoadC* pLoad )
{
	uint32	ui32Error = IO_OK;
	uint32	ui32Tmp;
	uint8	ui8Color[4];

	//ambient
	ui32Error = pLoad->read( ui8Color, 4 );
	m_rAmbient[0] = (float32)ui8Color[0] / 255.0f;
	m_rAmbient[1] = (float32)ui8Color[1] / 255.0f;
	m_rAmbient[2] = (float32)ui8Color[2] / 255.0f;
	m_rAmbient[3] = (float32)ui8Color[3] / 255.0f;

	//diffuse
	ui32Error = pLoad->read( ui8Color, 4 );
	m_rDiffuse[0] = (float32)ui8Color[0] / 255.0f;
	m_rDiffuse[1] = (float32)ui8Color[1] / 255.0f;
	m_rDiffuse[2] = (float32)ui8Color[2] / 255.0f;
	m_rDiffuse[3] = (float32)ui8Color[3] / 255.0f;

	//specular
	ui32Error = pLoad->read( ui8Color, 4 );
	m_rSpecular[0] = (float32)ui8Color[0] / 255.0f;
	m_rSpecular[1] = (float32)ui8Color[1] / 255.0f;
	m_rSpecular[2] = (float32)ui8Color[2] / 255.0f;
	m_rSpecular[3] = (float32)ui8Color[3] / 255.0f;

	// shininess
	ui32Error = pLoad->read( &m_f32Shininess, sizeof( m_f32Shininess ) );

	// opacity
	ui32Error = pLoad->read( &m_f32Opacity, sizeof( m_f32Opacity ) );

	// selfillum
	ui32Error = pLoad->read( &m_f32SelfIllumination, sizeof( m_f32SelfIllumination ) );


	// this is to compensate a old bug
	if( m_f32Shininess == m_f32Opacity && m_f32Shininess == m_f32SelfIllumination ) {
		m_f32Shininess = 10;
		m_f32Opacity = 0;
		m_f32SelfIllumination = 0;
	}


	// flags
	ui32Error = pLoad->read( &m_ui16Flags, sizeof( m_ui16Flags ) );

	// mapping channel
	ui32Error = pLoad->read( &m_ui16MappingChannel, sizeof( m_ui16MappingChannel ) );

	// texture handle
	ui32Error = pLoad->read( &ui32Tmp, sizeof( ui32Tmp ) );
	if( ui32Tmp != 0xffffffff )
		pLoad->add_file_handle_patch( (void**)&m_pTextureHandle, ui32Tmp );

	// mapping type
	ui32Error = pLoad->read( &ui32Tmp, sizeof( ui32Tmp ) );
	m_eMappingType = (MappingTypeE)ui32Tmp;

	return ui32Error;
}

