// TreeFile.cpp

#include <windows.h>

#include "Types.h"
#include "TreeFile.h"


static void Swap16( void *mem )
{
	u8
		t,
		*ptr = (u8 *)mem;

	t = ptr[0];
	ptr[0] = ptr[1];
	ptr[1] = t;
}


static void Swap32( void *mem )
{
	u8
		t,
		*ptr = (u8 *)mem;

	t = ptr[0];
	ptr[0] = ptr[3];
	ptr[3] = t;

	t = ptr[1];
	ptr[1] = ptr[2];
	ptr[2] = t;
}


void CTreeFile::CloseTree( CTreeFile *parent )
{
	CTreeFile
		*child;
	s32
		i,
		pos,
		size;
	u8
		*data;

	size = GetSize();
	data = new u8[size];
	Seek( 0 );
	Read( data, size );
	Close();
	DeleteFile( Filename );

	pos = parent->GetPos();
	parent->Write( data, size );
	parent->Seek( Pos );
	parent->WriteLong( pos );
	parent->End();

	delete [] data;


	for (i=0; i<Children.Count; i++)
	{
		child = Children[i];

		child->Pos += pos;

		child->CloseTree( parent );
	}


	DeleteFile( Filename );
}


void CTreeFile::CreateFile( const char *filename )
{
	Pos = -1;

	Create( filename );
}


void CTreeFile::CloseFile()
{
	s32
		i;

	for (i=0; i<Children.Count; i++)
		Children[i]->CloseTree( this );

	Close();
}


void CTreeFile::WriteByte( const u8 value )
{
	Write( &value, 1 );
}


void CTreeFile::WriteWord( const u16 value )
{
	u16
		temp;

	temp = value;
	Swap16( &temp );
	Write( &temp, 2 );
}


void CTreeFile::WriteLong( const u32 value )
{
	u32
		temp;

	temp = value;
	Swap32( &temp );
	Write( &temp, 4 );
}


void CTreeFile::Pad( const s32 pad )
{
	s32
		diff,
		zero = 0;

	End();

	diff = GetSize() % pad;
	diff = pad - diff;

	if (diff < pad)
		Write( &zero, diff );
}


CTreeFile *CTreeFile::NewTree()
{
	CTreeFile
		*tree;

	tree = new CTreeFile;
	Children.Add( tree );

	tree->Pos = GetPos();
	WriteLong( 0 );

	GetTempFileName( ".", "ZZZ", 0, tree->Filename );
	tree->Create( tree->Filename );

	return( tree );
}
