#include <stdio.h>
#include <string.h>
#include "zlib.h"

#include "Package.h"

const char *cPackageVersion01 = "PKG01";

const unsigned char cPFCompressed = 0x01;
const unsigned char cPFCreatures2 = 0x02;

/* UNCOMPRESSED LOAD
bool LoadPackageFile01(FILE *fPackage, Package *package)
{
	unsigned char nTitleLength;
	int i;
	short nFilenameLength;

	nTitleLength = fgetc(fPackage);
	package->Title = new char[nTitleLength + 1];
	fread(package->Title, nTitleLength, 1, fPackage);
	package->Title[nTitleLength] = 0;

	fread(&package->FileCount, sizeof(package->FileCount), 1, fPackage);
	package->Files = new PackagedFile[package->FileCount];

	for (i = 0; i < package->FileCount; i++)
	{
		fread(&nFilenameLength, sizeof(nFilenameLength), 1, fPackage);
		package->Files[i].Filename = new char[nFilenameLength + 1];
		fread(package->Files[i].Filename, nFilenameLength, 1, fPackage);
		package->Files[i].Filename[nFilenameLength] = 0;
		fread(&package->Files[i].DataLength, sizeof(package->Files[i].DataLength), 1, fPackage);
		package->Files[i].Data = new unsigned char[package->Files[i].DataLength];
		fread(package->Files[i].Data, package->Files[i].DataLength, 1, fPackage);
	}

	return true;
}
*/

/* COMPRESSED LOAD
bool LoadPackageFile02(FILE *fPackage, Package *package)
{
	unsigned char nTitleLength;
	int i;
	short nFilenameLength;
	unsigned long nCompressedFileLength;
	unsigned char *compressedFile;

	nTitleLength = fgetc(fPackage);
	package->Title = new char[nTitleLength + 1];
	fread(package->Title, nTitleLength, 1, fPackage);
	package->Title[nTitleLength] = 0;

	fread(&package->FileCount, sizeof(package->FileCount), 1, fPackage);
	package->Files = new PackagedFile[package->FileCount];

	for (i = 0; i < package->FileCount; i++)
	{
		fread(&nFilenameLength, sizeof(nFilenameLength), 1, fPackage);
		package->Files[i].Filename = new char[nFilenameLength + 1];
		fread(package->Files[i].Filename, nFilenameLength, 1, fPackage);
		package->Files[i].Filename[nFilenameLength] = 0;
		fread(&package->Files[i].DataLength, sizeof(package->Files[i].DataLength), 1, fPackage);
		package->Files[i].Data = new unsigned char[package->Files[i].DataLength];
		fread(&nCompressedFileLength, sizeof(nCompressedFileLength), 1, fPackage);
		compressedFile = new unsigned char[nCompressedFileLength];
		fread(compressedFile, nCompressedFileLength, 1, fPackage);
		uncompress(package->Files[i].Data, &package->Files[i].DataLength, compressedFile, nCompressedFileLength);
	}

	return true;
}
*/

bool LoadPackageFile01(FILE *fPackage, Package *package)
{
	unsigned char nTitleLength;
	int i;
	short nFilenameLength;
	unsigned long nCompressedFileLength;
	unsigned char *compressedFile;

	package->Flags= fgetc(fPackage);
	nTitleLength = fgetc(fPackage);
	package->Title = new char[nTitleLength + 1];
	fread(package->Title, nTitleLength, 1, fPackage);
	package->Title[nTitleLength] = 0;

	fread(&package->FileCount, sizeof(package->FileCount), 1, fPackage);
	package->Files = new PackagedFile[package->FileCount];

	for (i = 0; i < package->FileCount; i++)
	{
		fread(&nFilenameLength, sizeof(nFilenameLength), 1, fPackage);
		package->Files[i].Filename = new char[nFilenameLength + 1];
		fread(package->Files[i].Filename, nFilenameLength, 1, fPackage);
		package->Files[i].Filename[nFilenameLength] = 0;
		fread(&package->Files[i].DataLength, sizeof(package->Files[i].DataLength), 1, fPackage);
		if (package->Files[i].DataLength > 0)
		{
			package->Files[i].Data = new unsigned char[package->Files[i].DataLength];
			if (package->Flags & cPFCompressed)
			{
				fread(&nCompressedFileLength, sizeof(nCompressedFileLength), 1, fPackage);
				compressedFile = new unsigned char[nCompressedFileLength];
				fread(compressedFile, nCompressedFileLength, 1, fPackage);
				uncompress(package->Files[i].Data, &package->Files[i].DataLength, compressedFile, nCompressedFileLength);
			}
			else
			{
				fread(package->Files[i].Data, package->Files[i].DataLength, 1, fPackage);
			}
		}
		else
		{
			package->Files[i].Data = NULL;
		}
	}

	return true;
}

bool LoadPackageFromFILE(FILE *fPackage, Package *package)
{
	bool bSuccess;

	bSuccess = false;

	fread(package->Version, sizeof(package->Version), 1, fPackage);

	if (strncmp(package->Version, cPackageVersion01, cPackageVersionLength) == 0)
		bSuccess = LoadPackageFile01(fPackage, package);

	return bSuccess;
}

bool LoadPackageFile(const char *filename, Package *package)
{
	FILE *fPackage;
	bool bSuccess;

	fPackage = fopen(filename, "rb");
	if (fPackage == NULL)
		return false;

	bSuccess = LoadPackageFromFILE(fPackage, package);

	fclose(fPackage);

	return bSuccess;
}

bool LoadPackageFromExe(const char *filename, Package *package)
{
	FILE *fPackage;
	bool bSuccess;
	long nOffset;

	fPackage = fopen(filename, "rb");
	if (fPackage == NULL)
		return false;

	bSuccess = false;

	fseek(fPackage, -(long)sizeof(nOffset), SEEK_END);
	fread(&nOffset, sizeof(nOffset), 1, fPackage);
	fseek(fPackage, nOffset, SEEK_SET);

	bSuccess = LoadPackageFromFILE(fPackage, package);

	fclose(fPackage);

	return bSuccess;
}
