#include "GeomListC.h"
#include "TCSetC.h"
#include "MtlLayerC.h"
#include "ColorC.h"
#include "PajaTypes.h"
#include <assert.h>
#include "minilzo.h"

using namespace PajaTypes;
using namespace FileIO;


GeomListC::GeomListC() :
	m_ui16IndexCount( 0 ),
	m_ui16NormalIndexCount( 0 ),
	m_ui16ColorIndexCount( 0 ),
	m_ui16VertexCount( 0 ),
	m_ui16NormalCount( 0 ),
	m_ui16ColorCount( 0 ),
	m_pIndices( 0 ),
	m_pNormalIndices( 0 ),
	m_pColorIndices( 0 ),
	m_pVertices( 0 ),
	m_pNormals( 0 ),
	m_pColors( 0 ),
	m_rMin( 0, 0, 0 ),
	m_rMax( 0, 0, 0 ),
	m_bBBoxValid( false ),
	m_ui8Flags( 0 )
{
	// empty
}

GeomListC::~GeomListC()
{
	uint32	i;
	delete m_pColorIndices;
	delete m_pColors;
	delete m_pIndices;
	delete m_pNormalIndices;
	delete m_pNormals;
	delete m_pVertices;

	for( i = 0; i < m_rTexCoordSets.size(); i++ )
		delete m_rTexCoordSets[i];
	for( i = 0; i < m_rMtlLayers.size(); i++ )
		delete m_rMtlLayers[i];
}


GeomListC&
GeomListC::operator=( const GeomListC& rGeomList )
{
	m_bBBoxValid = rGeomList.m_bBBoxValid;
	m_bBBoxEmpty = rGeomList.m_bBBoxEmpty;
	m_rMin = rGeomList.m_rMin;
	m_rMax = rGeomList.m_rMax;
	m_ui8Flags = rGeomList.m_ui8Flags;

	//Geom..
	m_ui16IndexCount = rGeomList.m_ui16IndexCount;
	m_ui16NormalIndexCount = rGeomList.m_ui16NormalIndexCount;
	m_ui16ColorIndexCount = rGeomList.m_ui16ColorIndexCount;
	m_ui16VertexCount = rGeomList.m_ui16VertexCount;
	m_ui16NormalCount = rGeomList.m_ui16NormalCount;
	m_ui16ColorCount = rGeomList.m_ui16ColorCount;

	delete m_pIndices;
	m_pIndices = 0;
	if( m_ui16IndexCount ) {
		m_pIndices = new uint16[m_ui16IndexCount];
		memcpy( m_pIndices, rGeomList.m_pIndices, sizeof(uint16) * m_ui16IndexCount );
	}

	delete m_pNormalIndices;
	m_pNormalIndices = 0;
	if( m_ui16NormalIndexCount ) {
		m_pNormalIndices = new uint16[m_ui16NormalIndexCount];
		memcpy( m_pNormalIndices, rGeomList.m_pNormalIndices, sizeof(uint16) * m_ui16NormalIndexCount );
	}

	delete m_pColorIndices;
	m_pColorIndices = 0;
	if( m_ui16ColorIndexCount ) {
		m_pColorIndices= new uint16[m_ui16ColorIndexCount];
		memcpy( m_pColorIndices, rGeomList.m_pColorIndices, sizeof(uint16) * m_ui16ColorIndexCount );
	}

	delete m_pVertices;
	m_pVertices = 0;
	if( m_ui16VertexCount ) {
		m_pVertices = new float32[(int32)m_ui16VertexCount * 3];
		memcpy( m_pVertices, rGeomList.m_pVertices, sizeof(float32) * m_ui16VertexCount * 3);
	}

	delete m_pNormals;
	m_pNormals = 0;
	if( m_ui16NormalCount ) {
		m_pNormals = new float32[(int32)m_ui16NormalCount * 3];
		memcpy( m_pNormals, rGeomList.m_pNormals, sizeof(float32) * m_ui16NormalCount * 3 );
	}

	delete m_pColors;
	m_pColors = 0;
	if( m_ui16ColorCount ) {
		m_pColors = new uint8[(int32)m_ui16ColorCount * 4];
		memcpy( m_pColors, rGeomList.m_pColors, m_ui16ColorCount * 4 );
	}


	uint32	i;

	// delete old texture coord sets
	for( i = 0; i < m_rTexCoordSets.size(); i++ )
		delete m_rTexCoordSets[i];
	m_rTexCoordSets.clear();

	for( i = 0; i < rGeomList.m_rTexCoordSets.size(); i++ ) {
		TCSetC*	pSet = add_texture_channel();
		*pSet = *(rGeomList.m_rTexCoordSets[i]);
	}


	// delete old layers
	for( i = 0; i < m_rMtlLayers.size(); i++ )
		delete m_rMtlLayers[i];
	m_rMtlLayers.clear();

	for( i = 0; i < rGeomList.m_rMtlLayers.size(); i++ ) {
		MtlLayerC*	pLayer = add_layer();
		*pLayer = *(rGeomList.m_rMtlLayers[i]);
	}

//	m_rTexCoords = rGeomList.m_rTexCoords;
//	m_rMtlLayers = rGeomList.m_rMtlLayers;

	return *this;
}

TCSetC*
GeomListC::add_texture_channel()
{
	add_flags( GEOMLIST_HAS_TEXTURES );

	TCSetC*	pSet = new TCSetC;
	m_rTexCoordSets.push_back( pSet );
	return pSet;
}

MtlLayerC*
GeomListC::add_layer()
{
	add_flags( GEOMLIST_HAS_TEXTURES );

	MtlLayerC*	pLayer = new MtlLayerC;
	m_rMtlLayers.push_back( pLayer );
	return pLayer;
}
		
TCSetC*
GeomListC::get_texture_channel( uint16 ui16Index )
{
	assert( ui16Index < m_rTexCoordSets.size() );

	return m_rTexCoordSets[ui16Index];
}


MtlLayerC*
GeomListC::get_layer( uint16 ui16Index )
{
	assert( ui16Index < m_rMtlLayers.size() );
	return m_rMtlLayers[ui16Index];
}


uint16
GeomListC::get_texture_channel_count() const
{
	return (uint16)m_rTexCoordSets.size();
}
uint16
GeomListC::get_layer_count() const
{
	return (uint16)m_rMtlLayers.size();
}

uint8
GeomListC::get_flags()
{
	return m_ui8Flags;
}

void
GeomListC::add_flags( uint8 ui8Flags )
{
	m_ui8Flags |= ui8Flags;
}

void
GeomListC::del_flags( uint8 ui8Flags )
{
	m_ui8Flags &= ~ui8Flags;
}


bool
GeomListC::get_bounds( Vector3C& rMin, Vector3C& rMax )
{
	if( !m_bBBoxValid )
		update_bounds();

	rMin = m_rMin;
	rMax = m_rMax;

	return m_bBBoxEmpty;
}

void
GeomListC::update_bounds()
{
	m_bBBoxValid = true;
	
	if( m_ui16VertexCount > 0 ) {

		m_rMin = m_rMax = Vector3C( 0, 0, 0 );
		
		for( uint32 i = 3; i < m_ui16VertexCount * 3; i += 3 ) {
			for( uint32 j = 0; j < 3; j++ ) {
				if( m_pVertices[i + j] < m_rMin[j] ) m_rMin[j] = m_pVertices[i + j];
				if( m_pVertices[i + j] > m_rMax[j] ) m_rMax[j] = m_pVertices[i + j];
			}	
		}

		m_bBBoxEmpty = false;

		return;
	} 

	// boudning box is empty
	m_rMin = m_rMax = Vector3C( 0, 0, 0 );

	m_bBBoxEmpty = true;
}
		


// allocate space for geometry
void
GeomListC::reserve_indices( uint16 ui16Size )
{
	delete m_pIndices;
	m_pIndices = 0;

	if( ui16Size )
		m_pIndices = new uint16[ui16Size];

	m_ui16IndexCount = ui16Size;
}

void
GeomListC::reserve_normal_indices( uint16 ui16Size )
{
	delete m_pNormalIndices;
	m_pNormalIndices = 0;
	
	if( ui16Size )
		m_pNormalIndices = new uint16[ui16Size];

	m_ui16NormalIndexCount = ui16Size;
}

void
GeomListC::reserve_color_indices( uint16 ui16Size )
{
	delete m_pColorIndices;
	m_pColorIndices = 0;
	
	if( ui16Size )
		m_pColorIndices = new uint16[ui16Size];

	m_ui16ColorIndexCount = ui16Size;
}

void
GeomListC::reserve_vertices( uint16 ui16Size )
{
	delete m_pVertices;
	m_pVertices = 0;

	if( ui16Size )
		m_pVertices = new float32[(uint32)ui16Size * 3];

	m_ui16VertexCount = ui16Size;
}

void
GeomListC::reserve_normals( uint16 ui16Size )
{
	delete m_pNormals;
	m_pNormals = 0;

	if( ui16Size )
		m_pNormals = new float32[(uint32)ui16Size * 3];

	m_ui16NormalCount = ui16Size;
}

void
GeomListC::reserve_colors( uint16 ui16Size )
{
	delete m_pColors;
	m_pColors = 0;

	if( ui16Size )
		m_pColors = new uint8[(uint32)ui16Size * 4];

	m_ui16ColorCount = ui16Size;
}

void
GeomListC::set_index( uint16 ui16Idx, uint16 ui16Index )
{
	assert( ui16Idx < m_ui16IndexCount );
	m_pIndices[ui16Idx] = ui16Index;
}

void
GeomListC::set_normal_index( uint16 ui16Idx, uint16 ui16Index )
{
	assert( ui16Idx < m_ui16NormalIndexCount );
	m_pNormalIndices[ui16Idx] = ui16Index;
}

void
GeomListC::set_color_index( uint16 ui16Idx, uint16 ui16Index )
{
	assert( ui16Idx < m_ui16ColorIndexCount );
	m_pColorIndices[ui16Idx] = ui16Index;
}

void
GeomListC::set_vertex( uint16 ui16Index, Vector3C& rVec )
{
	assert( ui16Index < m_ui16VertexCount );
	uint32	ui32Offset = (uint32)ui16Index * 3;

	m_pVertices[ui32Offset] = rVec[0];			// x
	m_pVertices[ui32Offset + 1] = rVec[1];		// y
	m_pVertices[ui32Offset + 2] = rVec[2];		// z
}

void
GeomListC::set_normal( uint16 ui16Index, Vector3C& rNorm )
{
	assert( ui16Index < m_ui16NormalCount );
	uint32	ui32Offset = (uint32)ui16Index * 3;

	m_pNormals[ui32Offset] = rNorm[0];			// x
	m_pNormals[ui32Offset + 1] = rNorm[1];		// y
	m_pNormals[ui32Offset + 2] = rNorm[2];		// z
}

void
GeomListC::set_color( uint16 ui16Index, ColorC& rColor )
{
	assert( ui16Index < m_ui16ColorCount );
	uint32	ui32Offset = (uint32)ui16Index * 4;

	m_pColors[ui32Offset] = (uint8)(rColor[0] * 255.0f);			// r
	m_pColors[ui32Offset + 1] = (uint8)(rColor[1] * 255.0f);		// g
	m_pColors[ui32Offset + 2] = (uint8)(rColor[2] * 255.0f);		// b
	m_pColors[ui32Offset + 3] = (uint8)(rColor[3] * 255.0f);		// a
}

uint16
GeomListC::get_index_count() const
{
	return m_ui16IndexCount;
}

uint16
GeomListC::get_normal_index_count() const
{
	return m_ui16NormalCount;
}

uint16
GeomListC::get_color_index_count() const
{
	return m_ui16ColorIndexCount;
}

uint16
GeomListC::get_vertex_count() const
{
	return m_ui16VertexCount;
}

uint16
GeomListC::get_normal_count() const
{
	return m_ui16NormalCount;
}

uint16
GeomListC::get_color_count() const
{
	return m_ui16ColorCount;
}

uint16
GeomListC::get_index( uint16 ui16Index )
{
	assert( ui16Index < m_ui16IndexCount );
	return m_pIndices[ui16Index];
}

uint16
GeomListC::get_normal_index( uint16 ui16Index )
{
	assert( ui16Index < m_ui16NormalIndexCount );
	return m_pNormalIndices[ui16Index];
}

uint16
GeomListC::get_color_index( uint16 ui16Index )
{
	assert( ui16Index < m_ui16ColorIndexCount );
	return m_pColorIndices[ui16Index];
}

Vector3C
GeomListC::get_vertex( uint16 ui16Index )
{
	assert( ui16Index < m_ui16VertexCount );
	uint32	ui32Offset = (uint32)ui16Index * 3;
	return Vector3C( m_pVertices[ui32Offset], m_pVertices[ui32Offset + 1], m_pVertices[ui32Offset + 2] );
}

Vector3C
GeomListC::get_normal( uint16 ui16Index )
{
	assert( ui16Index < m_ui16NormalCount );
	uint32	ui32Offset = (uint32)ui16Index * 3;
	return Vector3C( m_pNormals[ui32Offset], m_pNormals[ui32Offset + 1], m_pNormals[ui32Offset + 2] );
}

ColorC
GeomListC::get_color( uint16 ui16Index )
{
	assert( ui16Index < m_ui16ColorCount );
	uint32	ui32Offset = (uint32)ui16Index * 4;
	return ColorC( (float32)m_pColors[ui32Offset] / 255.0f, (float32)m_pColors[ui32Offset + 1] / 255.0f,
					(float32)m_pColors[ui32Offset + 2] / 255.0f, (float32)m_pColors[ui32Offset + 3] / 255.0f );
}

uint16*
GeomListC::get_index_pointer()
{
	return m_pIndices;
}

uint16*
GeomListC::get_normal_index_pointer()
{
	return m_pNormalIndices;
}

uint16*
GeomListC::get_color_index_pointer()
{
	return m_pColorIndices;
}

float32*
GeomListC::get_vertex_pointer()
{
	return m_pVertices;
}

float32*
GeomListC::get_normal_pointer()
{
	return m_pNormals;
}

uint8*
GeomListC::get_color_pointer()
{
	return m_pColors;
}

/*
	bool					m_bBBoxValid;
	bool					m_bBBoxEmpty;
	PajaTypes::Vector3C		m_rMin, m_rMax;
	PajaTypes::uint8		m_ui8Flags;	

	//Geom..
	PajaTypes::uint16		m_ui16IndexCount;
	PajaTypes::uint16		m_ui16NormalIndexCount;
	PajaTypes::uint16		m_ui16ColorIndexCount;
	PajaTypes::uint16		m_ui16VertexCount;
	PajaTypes::uint16		m_ui16NormalCount;
	PajaTypes::uint16		m_ui16ColorCount;

	PajaTypes::uint16*		m_pIndices;
	PajaTypes::uint16*		m_pNormalIndices;
	PajaTypes::uint16*		m_pColorIndices;
	PajaTypes::float32*		m_pVertices;
	PajaTypes::float32*		m_pNormals;
	PajaTypes::uint8*		m_pColors;

	std::vector<TCSetC*>	m_rTexCoordSets;
	std::vector<MtlLayerC*>	m_rMtlLayers;
*/
enum GeomListChunksE {
	CHUNK_GEOMLIST_BASE			= 0x1000,
	CHUNK_GEOMLIST_TCSET		= 0x2000,
	CHUNK_GEOMLIST_MTLLAYER		= 0x3000,
};

const uint32	GEOMLIST_VERSION = 1;


uint32
GeomListC::write_compressed( SaveC* pSave, uint8* pBuffer, uint32 ui32BufferSize, uint8* pCompressed, long* pWorkmem )
{
	uint32	ui32Error = IO_OK;
	uint32	ui32CompressedSize;

	if( lzo1x_1_compress( pBuffer, ui32BufferSize, pCompressed, &ui32CompressedSize, pWorkmem ) != LZO_E_OK )
		ui32Error = IO_ERROR_WRITE;

	// write compressed data size
	ui32Error = pSave->write( &ui32CompressedSize, sizeof( ui32CompressedSize ) );

	// write compressed data
	ui32Error = pSave->write( pCompressed, ui32CompressedSize );

	return ui32Error;
}

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

	// save vertices and faces and colors and normals
	pSave->begin_chunk( CHUNK_GEOMLIST_BASE, GEOMLIST_VERSION );

		// find the largest amount of data we need for comression
		uint32	ui32CompressedSize = 0;
		ui32CompressedSize = __max( ui32CompressedSize, (uint32)m_ui16VertexCount * 3 * 4 );
		ui32CompressedSize = __max( ui32CompressedSize, (uint32)m_ui16IndexCount * 2 );
		ui32CompressedSize = __max( ui32CompressedSize, (uint32)m_ui16NormalCount * 3 * 4 );
		ui32CompressedSize = __max( ui32CompressedSize, (uint32)m_ui16NormalIndexCount * 2 );
		ui32CompressedSize = __max( ui32CompressedSize, (uint32)m_ui16ColorCount * 4 );
		ui32CompressedSize = __max( ui32CompressedSize, (uint32)m_ui16ColorIndexCount * 2 );
		ui32CompressedSize = ui32CompressedSize + ui32CompressedSize / 64 + 16 + 3;

		uint8*	pCompressed = new uint8[ui32CompressedSize];
		long*	pWorkmem = new long[((LZO1X_1_MEM_COMPRESS) + (sizeof(long) - 1)) / sizeof(long)];

		// vertices
		ui32Tmp = m_ui16VertexCount;
		ui32Error = pSave->write( &ui32Tmp, sizeof( ui32Tmp ) );
		if( ui32Tmp )
			ui32Error = write_compressed( pSave, (uint8*)m_pVertices, (uint32)m_ui16VertexCount * 3 * 4, pCompressed, pWorkmem );

		// indices
		ui32Tmp = m_ui16IndexCount;
		ui32Error = pSave->write( &ui32Tmp, sizeof( ui32Tmp ) );
		if( ui32Tmp )
			ui32Error = write_compressed( pSave, (uint8*)m_pIndices, (uint32)m_ui16IndexCount * 2, pCompressed, pWorkmem );

		// normals
		ui32Tmp = m_ui16NormalCount;
		ui32Error = pSave->write( &ui32Tmp, sizeof( ui32Tmp ) );
		if( ui32Tmp ) {
			int8*	pCompNorm = new int8[m_ui16NormalCount * 3];
			float32*	pNormFloat = m_pNormals;
			int8*		pNormInt = pCompNorm;
			for( uint32 i = 0; i < m_ui16NormalCount * 3; i++ ) {
				*pNormInt = (int8)(*pNormFloat * 127.0f);
				pNormInt++;
				pNormFloat++;
			}
//			ui32Error = write_compressed( pSave, (uint8*)m_pNormals, (uint32)m_ui16NormalCount * 3 * 4, pCompressed, pWorkmem );
			ui32Error = write_compressed( pSave, (uint8*)pCompNorm, (uint32)m_ui16NormalCount * 3, pCompressed, pWorkmem );
			delete [] pCompNorm;
		}

		// normal indices
		ui32Tmp = m_ui16NormalIndexCount;
		ui32Error = pSave->write( &ui32Tmp, sizeof( ui32Tmp ) );
		if( ui32Tmp )
			ui32Error = write_compressed( pSave, (uint8*)m_pNormalIndices, (uint32)m_ui16NormalIndexCount * 2, pCompressed, pWorkmem );

		// colors
		ui32Tmp = m_ui16ColorCount;
		ui32Error = pSave->write( &ui32Tmp, sizeof( ui32Tmp ) );
		if( ui32Tmp )
			ui32Error = write_compressed( pSave, (uint8*)m_pColors, (uint32)m_ui16ColorCount * 4, pCompressed, pWorkmem );

		// color indices
		ui32Tmp = m_ui16ColorIndexCount;
		ui32Error = pSave->write( &ui32Tmp, sizeof( ui32Tmp ) );
		if( ui32Tmp )
			ui32Error = write_compressed( pSave, (uint8*)m_pColorIndices, (uint32)m_ui16ColorIndexCount * 2, pCompressed, pWorkmem );

		delete [] pWorkmem;
		delete [] pCompressed;

	pSave->end_chunk();

	uint32	i;

	// tc sets
	for( i = 0; i < m_rTexCoordSets.size(); i++ ) {
		// save vertices and faces and colors and normals
		pSave->begin_chunk( CHUNK_GEOMLIST_TCSET, GEOMLIST_VERSION );
			ui32Error = m_rTexCoordSets[i]->save( pSave );
		pSave->end_chunk();
	}

	// material layers
	for( i = 0; i < m_rMtlLayers.size(); i++ ) {
		// save vertices and faces and colors and normals
		pSave->begin_chunk( CHUNK_GEOMLIST_MTLLAYER, GEOMLIST_VERSION );
			ui32Error = m_rMtlLayers[i]->save( pSave );
		pSave->end_chunk();
	}

	return ui32Error;
}


uint32
GeomListC::read_compressed( LoadC* pLoad, uint8* pBuffer, uint32 ui32BufferSize )
{
	uint32	ui32Error = IO_OK;
	uint32	ui32DecompressedSize;
	uint32	ui32CompressedSize;

	// read compressed data size
	ui32Error = pLoad->read( &ui32CompressedSize, sizeof( ui32CompressedSize ) );

	uint8*	pCompressed = new uint8[ui32CompressedSize];

	// write compressed data
	ui32Error = pLoad->read( pCompressed, ui32CompressedSize );

	if( lzo1x_decompress( pCompressed, ui32CompressedSize, pBuffer, &ui32DecompressedSize, NULL ) != LZO_E_OK )
		ui32Error = IO_ERROR_READ;

	if( ui32DecompressedSize != ui32BufferSize ) {
		OutputDebugString( "data size mismatch\n" );
		return IO_ERROR_READ;
	}

	delete [] pCompressed;

	return ui32Error;
}


uint32
GeomListC::load( LoadC* pLoad )
{
	uint32	ui32Error = IO_OK;
	uint32	ui32Tmp;

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

		switch( pLoad->get_chunk_id() ) {

		case CHUNK_GEOMLIST_BASE:
			{
				if( pLoad->get_chunk_version() == GEOMLIST_VERSION ) {
					// vertices
					ui32Error = pLoad->read( &ui32Tmp, sizeof( ui32Tmp ) );
					if( ui32Tmp ) {
						reserve_vertices( ui32Tmp );
						ui32Error = read_compressed( pLoad, (uint8*)m_pVertices, (uint32)m_ui16VertexCount * 3 * 4 );
					}

					// indices
					ui32Error = pLoad->read( &ui32Tmp, sizeof( ui32Tmp ) );
					if( ui32Tmp ) {
						reserve_indices( ui32Tmp );
						ui32Error = read_compressed( pLoad, (uint8*)m_pIndices, (uint32)m_ui16IndexCount * 2 );
					}

					// normals
					ui32Error = pLoad->read( &ui32Tmp, sizeof( ui32Tmp ) );
					if( ui32Tmp ) {

						int8*	pCompNorm = new int8[ui32Tmp * 3];

						reserve_normals( ui32Tmp );
						ui32Error = read_compressed( pLoad, (uint8*)pCompNorm, (uint32)m_ui16NormalCount * 3 );

						float32*	pNormFloat = m_pNormals;
						int8*		pNormInt = pCompNorm;
						for( uint32 i = 0; i < m_ui16NormalCount * 3; i++ ) {
							*pNormFloat = (float32)(*pNormInt) / 127.0f;
							pNormInt++;
							pNormFloat++;
						}

						delete [] pCompNorm;
					}

					// normal indices
					ui32Error = pLoad->read( &ui32Tmp, sizeof( ui32Tmp ) );
					if( ui32Tmp ) {
						reserve_normal_indices( ui32Tmp );
						ui32Error = read_compressed( pLoad, (uint8*)m_pNormalIndices, (uint32)m_ui16NormalIndexCount * 2 );
					}

					// colors
					ui32Error = pLoad->read( &ui32Tmp, sizeof( ui32Tmp ) );
					if( ui32Tmp ) {
						reserve_colors( ui32Tmp );
						ui32Error = read_compressed( pLoad, (uint8*)m_pColors, (uint32)m_ui16ColorCount * 4 );
					}

					// color indices
					ui32Error = pLoad->read( &ui32Tmp, sizeof( ui32Tmp ) );
					if( ui32Tmp ) {
						reserve_color_indices( ui32Tmp );
						ui32Error = read_compressed( pLoad, (uint8*)m_pColorIndices, (uint32)m_ui16ColorIndexCount * 2 );
					}
				}
			}
			break;

		case CHUNK_GEOMLIST_TCSET:
			{
				if( pLoad->get_chunk_version() == GEOMLIST_VERSION ) {
					TCSetC*	pSet = add_texture_channel();
					ui32Error = pSet->load( pLoad );
				}
			}
			break;

		case CHUNK_GEOMLIST_MTLLAYER:
			{
				if( pLoad->get_chunk_version() == GEOMLIST_VERSION ) {
					MtlLayerC*	pLayer = add_layer();
					ui32Error = pLayer->load( pLoad );
				}
			}
			break;

		default:
			assert( 0 );
		}

		pLoad->close_chunk();

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

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

	return IO_OK;
}
