#include <windows.h>

#include "PGF.h"


s32 CPhilGenFile::CreateFile( const char *filename, const s32 type, const s32 version )
{
	if (!Create( filename ))
		return( FALSE );

	Writing = TRUE;

	WriteLong( PGF_ID_PGF );
	WriteLong( type );
	Write( &version, 4 );
	Write( &version, 4 );			// Will be size, later.

	Depth = -1;

	return( TRUE );
}


s32 CPhilGenFile::OpenFile( const char *filename, s32 *type, s32 *version, s32 *size )
{
	if (!Open( filename ))
		return( FALSE );

	Writing = FALSE;

	Read( type, 4 );
	if (*type != PGF_ID_PGF)
	{
		Close();
		return( FALSE );
	}

	Read( type, 4 );
	Read( version, 4 );
	Read( size, 4 );

	Depth = -1;

	return( TRUE );
}


void CPhilGenFile::CloseFile()
{
	s32
		size;

	if (Writing)
	{
		WriteLong( PGF_ID_END );
		WriteLong( 0 );

		size = GetSize() - (4*4);
		Seek( 3*4 );
		Write( &size, 4 );
	}

	Close();
}


void CPhilGenFile::CreateChunk( const s32 type )
{
	Depth++;
	List[Depth].Pos = GetPos();
	List[Depth].Size = 0;

	Write( &type, 4 );
	Write( &type, 4 );			// Will be size, later.
}


s32 CPhilGenFile::OpenChunk()
{
	s32
		type,
		size;

	Read( &type, 4 );
	Read( &size, 4 );

	Depth++;
	List[Depth].Pos = GetPos() + size;
	List[Depth].Size = size;

	return( type );
}


s32 CPhilGenFile::GetChunkSize()
{
	return( List[Depth].Size );
}


void CPhilGenFile::CloseChunk()
{
	s32
		size;

	if (Writing)
	{
		size = GetPos() - List[Depth].Pos - 8;
		Seek( List[Depth].Pos + 4 );
		Write( &size, 4 );
		End();
		Depth--;
	}
	else
	{
		Seek( List[Depth].Pos );
		Depth--;
	}
}


void CPhilGenFile::WriteByte( const u8 value )
{
	Write( &value, 1 );
}


void CPhilGenFile::WriteWord( const u16 value )
{
	Write( &value, 2 );
}


void CPhilGenFile::WriteLong( const u32 value )
{
	Write( &value, 4 );
}


void CPhilGenFile::WriteString( const char *string )
{
	s32
		len,
		size,
		zero = 0;

	len = 0;
	while (string[len])
		len++;

	size = (len + 4) & ~3;

	WriteLong( size );
	Write( string, len );
	Write( &zero, size-len );
}


void CPhilGenFile::WriteFloat( const float value )
{
	Write( &value, 4 );
}


u8 CPhilGenFile::ReadByte()
{
	u8
		value;

	Read( &value, 1 );
	return( value );
}


u16 CPhilGenFile::ReadWord()
{
	u16
		value;

	Read( &value, 2 );
	return( value );
}


u32 CPhilGenFile::ReadLong()
{
	u32
		value;

	Read( &value, 4 );
	return( value );
}


u32 CPhilGenFile::ReadString( char *string )
{
	u32
		size;

	Read( &size, 4 );
	Read( string, size );
	return( size );
}


float CPhilGenFile::ReadFloat()
{
	float
		value;

	Read( &value, 4 );
	return( value );
}
