/*
 * This code is released under the Microsoft Public License (MS-PL). See license.txt, below.
 */

#pragma pack(1)
__declspec(align(1)) typedef struct _SEQ {
	unsigned long	FORMAT_ID;
	unsigned long	SEQUENCE_ID;
	unsigned short	SEQUENCE_RESOLUTION;
	unsigned char	SEQUENCE_TEMPO[3];
	unsigned short	SEQUENCE_RHYTHM;
} SEQ;
# pragma pack ()

//seqの最大サイズ分からんので、適当に131072
#define MAX_SEQ_SIZE (131072)
#define MAX_SEQ_IN_SEP (16)

typedef struct _VH {
	unsigned long	FORMAT_ID;
	unsigned long	FORMAT_VERSION;
	unsigned long	VAB_ID;
	unsigned long	VAB_SIZE;
	unsigned short	SYSTEM_RESERVED1;
	unsigned short	TOTAL_NUM_OF_PROGRAMS;
	unsigned short	TOTAL_NUM_OF_TONES;
	unsigned short	TOTAL_NUM_OF_VAGS;
	unsigned char	MASTER_VOLUME;
	unsigned char	MASTER_PAN;
	unsigned char	BANK_ATTRIBUTE_1;
	unsigned char	BANK_ATTRIBUTE_2;
	unsigned long	SYSTEM_RESERVED2;
} VH;

typedef struct _InternalMusic {
	unsigned long nSeqIdx;
	unsigned long nVhIdx;
	unsigned long* nSeqOffset;
	unsigned long* nVhOffset;
	unsigned long* nSeqSize;
	unsigned long* nVhSize;
	unsigned long* isSeq;
	unsigned long* isVh;
	unsigned long* isVb;
	_TCHAR pszSeqExt[6];
	_TCHAR pszVhExt[6];
} InternalMusic;

#define PROGRAM_ATTRIBUTES (16)
#define MAX_PROGRAM_ATTRIBUTES (128)
#define TONE_ATTRIBUTES (32)
#define MAX_TONE_ATTRIBUTES (16)
#define VAG_OFFSET_SIZE (512)
#define VAG_OFFSET_NUM (256)

#ifdef _DEBUG
#define OutputString(str, ...) \
		{ \
			CHAR c[256]; \
			sprintf(c, str, __VA_ARGS__); \
			OutputDebugString(c); \
		}
#define OutputErrorString(str, ...) \
		{ \
			CHAR c[256]; \
			sprintf(c, str, __VA_ARGS__); \
			OutputDebugString(c); \
		}
#define OutputLogString(fp, str, ...) \
		{ \
			CHAR c[256]; \
			sprintf(c, str, __VA_ARGS__); \
			OutputDebugString(c); \
		}
#else
#define OutputString(str, ...) \
		{ \
			printf(str, __VA_ARGS__); \
		}
#define OutputErrorString(str, ...) \
		{ \
			fprintf(stderr, str, __VA_ARGS__); \
		}
#define OutputLogString(fp, str, ...) \
		{ \
			fprintf(fp, str, __VA_ARGS__); \
		}
#endif

#define FcloseAndNull(fp) \
		{ \
			if(fp) { \
				fclose(fp); \
				fp = NULL; \
			} \
		}

#define FreeAndNull(buf) \
		{ \
			if(buf) { \
				free(buf); \
				buf = NULL; \
			} \
		}

FILE* CreateOrOpenFile(
	LPCTSTR strSrcPath,
	LPTSTR pszOutPath,
	LPTSTR pszFileNameWithoutPath,
	LPCTSTR strExt,
	LPCTSTR strMode,
	unsigned long nFileCnt,
	unsigned long nMaxFileNum
	);

bool CreateSeq(
	_TCHAR* path, 
	unsigned char* data, 
	unsigned long datasize,
	FILE* csvFp,
	InternalMusic* im
	);

bool CreateSSsq(
	_TCHAR* path, 
	unsigned char* data, 
	unsigned long datasize,
	FILE* csvFp,
	InternalMusic* im
	);

bool CreateKcet(
	_TCHAR* path, 
	unsigned char* data, 
	unsigned long datasize,
	FILE* csvFp,
	InternalMusic* im
	);

bool CreateSntp(
	_TCHAR* path, 
	unsigned char* data, 
	unsigned long datasize,
	FILE* csvFp,
	InternalMusic* im
	);

bool CreateSeqg(
	_TCHAR* path, 
	unsigned char* data, 
	FILE* csvFp,
	InternalMusic* im
	);

bool CreateSeqq(
	_TCHAR* path, 
	unsigned char* data, 
	FILE* csvFp,
	InternalMusic* im
	);

bool CreateSqv(
	_TCHAR* path, 
	unsigned char* data, 
	FILE* csvFp,
	InternalMusic* im
	);

bool CreateSseq(
	_TCHAR* path, 
	unsigned char* data, 
	FILE* csvFp,
	InternalMusic* im
	);

bool CreateVh(
	_TCHAR* path, 
	unsigned char* data, 
	unsigned long datasize,
	FILE* csvFp,
	InternalMusic* im,
	VH* vh,
	unsigned short* vag_offset
	);

bool CreateVhForBastard(
	_TCHAR* path,
	unsigned char* data,
	FILE* csvFp,
	InternalMusic* im,
	VH* vh,
	unsigned short* vag_offset
	);

bool CreateSShd(
	_TCHAR* path, 
	unsigned char* data, 
	unsigned long datasize, 
	unsigned long* vbsize,
	FILE* csvFp,
	InternalMusic* im
	);

bool CreateInst(
	_TCHAR* path, 
	unsigned char* data, 
	FILE* csvFp,
	InternalMusic* im
	);

bool CreateVbForVh(
	_TCHAR* path,
	unsigned char* data,
	unsigned long datasize,
	int is_vb_head_0byte,
	FILE* csvFp,
	InternalMusic* im,
	VH* vh,
	unsigned short* vag_offset
	);

bool CreateVbForSShd(
	_TCHAR* path, 
	unsigned char* data, 
	unsigned long datasize, 
	unsigned long* vbsize, 
	int is_vb_head_0byte,
	FILE* csvFp,
	InternalMusic* im
	);

bool CreateVbForInst(
	_TCHAR* path, 
	unsigned char* data, 
	FILE* csvFp,
	InternalMusic* im
	);
