#pragma once

#include <string>
#include <vector>
#include <Windows.h>

#define MAF_DEF_TEMPBUFFSIZE 1048576
#define MAF_MAX_FILESIZE 4294967295

#define MAF_HEADER_MAGICNUMBER 0x5F46414D //マジックナンバー( MAF_ )
#define MAF_HEADER_VERSION 0x01000000 //バージョン( 1.0.0.0 )

enum MAF_RESULT
{
	MAF_CONTINUE = 1,

	MAF_OK = 0,

	MAF_ERROR_FATAL = -1,
	MAF_ERROR_INVALID_ARGUMENT = -2,
	MAF_ERROR_ILLEGAL_DIRECTORYNAME = -3,
	MAF_ERROR_IO_COLLECTFILE = -4,
	MAF_ERROR_IO_COLLECTFILE_BIGFILE = -5,
	MAF_ERROR_IO_CREATEOUTPUTFILE = -6,
	MAF_ERROR_IO_READSOURCEFILE = -7,
	MAF_ERROR_IO_WRITEOUTPUTFILE = -8,
};

enum MAF_EVENT
{
	MAF_EVENT_OUTPUTPROGRESS	= 0x00000001,
	MAF_EVENT_FILEINDEX			= 0x00000002,
	MAF_EVENT_FILEPROGRESS		= 0x00000004,
};


struct MAF_HEADER
{
	unsigned int magicNumber;
	unsigned int version;
	unsigned int alignment;
	unsigned int fileCount;
	unsigned int stringSize;
	unsigned int reserve;
	unsigned long long fileStart;
	unsigned long long stringStart;
};

struct MAF_FILE
{
	unsigned int namePos;
	unsigned int dataPos;
	unsigned int dataSize;
	unsigned int reserve;
};

struct MAF_CONTEXT
{
	bool initialized;

	unsigned int alignment;
	std::vector<MAF_FILE> fileList;
	std::vector<wchar_t> stringBuffer;

	unsigned int totalFileSize;
	unsigned int totalSize;
};

struct MAF_CONTEXT_WRITE
{
	bool initialized;

	std::vector<std::wstring> srcFileNameList;
	unsigned long long totalDataAlignmentSize;
	unsigned long long totalDataSize;
	unsigned long long outputDataSize;

	unsigned char* tempBuff;
	unsigned int tempBuffSize;

	unsigned int outputProgress;
	HANDLE outputHandle;

	unsigned int fileIndex;
	unsigned int fileSize;
	unsigned int fileProgress;
	HANDLE fileHandle;

	unsigned int eventFlags;
};

MAF_RESULT MAF_InitializeContext(	const wchar_t* pRootDirectoryName,
									const wchar_t* pInputDirectoryName,
									const wchar_t* pOutputFileName,
									unsigned int alignment,
									unsigned int tempBuffSize,
									MAF_CONTEXT& context,
									MAF_CONTEXT_WRITE& contextWrite );

unsigned int MAF_TakeEvent( MAF_CONTEXT_WRITE& contextWrite );
const wchar_t* MAF_GetFileName( const MAF_CONTEXT& context, const MAF_CONTEXT_WRITE& contextWrite );

MAF_RESULT MAF_BeginWrite( const MAF_CONTEXT& context, MAF_CONTEXT_WRITE& contextWrite );
MAF_RESULT MAF_ProcWrite( const MAF_CONTEXT& context, MAF_CONTEXT_WRITE& contextWrite );
MAF_RESULT MAF_EndWrite( const MAF_CONTEXT& context, MAF_CONTEXT_WRITE& contextWrite );

void MAF_ReleaseContext( MAF_CONTEXT& context, MAF_CONTEXT_WRITE& contextWrite );
