//	PasStructs.h

#ifndef _H_PasStructs
#define _H_PasStructs

#ifndef ushort
	typedef unsigned short ushort;
#endif

#include "FileSystemTypes.h"
#include "PasDiskLocSpec.h"

#pragma options align = packed

//	all disks
#define Pas_kNumBootBlocks			2L
#define Pas_kDirStartBlock			Pas_kNumBootBlocks
#define Pas_kDirEndBlockPlusOne		6L
#define	Pas_kNumDirBlocks			(Pas_kDirEndBlockPlusOne - Pas_kDirStartBlock)
#define	Pas_kBytesPerBlock			512L		//	0x0200L bytes
#define	Pas_kMaxDirEntries			77
#define	Pas_kVolIDLength			7
#define	Pas_kTitleIDLength			15

typedef struct {
	Byte		byte[Pas_kBytesPerBlock];
} Pas_Block;

//	140k disk constants
#define	Pas_kBlocksPerDisk			280L		//	0x0118L blocks
#define	Pas_kBlocksPerTrack			8L
#define	Pas_kSectorsPerBlock		2L

typedef struct Pas_Disk {
	Pas_Block	block[Pas_kBlocksPerDisk];
} Pas_Disk;

//	other disk sizes
#define	Pas_kBlocksPerDisk400		800L
#define	Pas_kBlocksPerDisk800		1600L
#define	Pas_kBlocksPerDisk1440		2880L
#define	Pas_kBlocksPerDisk5M		10240L

typedef struct Pas_Disk400 {
	Pas_Block	block[Pas_kBlocksPerDisk400];
} Pas_Disk400;

typedef struct Pas_Disk800 {
	Pas_Block	block[Pas_kBlocksPerDisk800];
} Pas_Disk800;

typedef unsigned short	Pas_BlockNum, Pas_EntryIndex;
#define	Pas_kNoBlock	((Pas_BlockNum)0xFFFF)

OSErr	Pas_GetBlock(DiskImageRec *imageRec, Pas_BlockNum blockNum, Pas_Block **blockP);


typedef union {
	#if TARGET_RT_LITTLE_ENDIAN
		struct {
			unsigned short	month	: 4;
			unsigned short	day		: 5;
			unsigned short	year	: 7;
		} date;
	#else
		struct {
			unsigned short	year	: 7;
			unsigned short	day		: 5;
			unsigned short	month	: 4;
		} date;
	#endif
	
	RboShort	rboShort;
	ushort		value;
} Pas_DateRec;

typedef unsigned	char	Pas_VolumeID[Pas_kVolIDLength + 1];
typedef 			char	Pas_VolumeIDStr[Pas_kVolIDLength + 1];

typedef unsigned	char	Pas_TitleID[Pas_kTitleIDLength + 1];
typedef 			char	Pas_TitleIDStr[Pas_kTitleIDLength + 1];

typedef enum {
	Pas_FileKind_VOL_DIR, 		//	(Disk Volume Entry)
	Pas_FileKind_BAD_BLOCKS,	//	(File Containig Bad Blocks)
	Pas_FileKind_CODE,			//	(Code File, Machine Executable)
	Pas_FileKind_TEXT,			//	(Text File, Human Readable)
	Pas_FileKind_INFO,			//	(Information File, For Debugger)
	Pas_FileKind_DATA,			//	(Data File)
	Pas_FileKind_GRAF,			//	(Graphics Vectors)
	Pas_FileKind_FOTO,			//	(Graphics Screen Image, Fonts)
	Pas_FileKind_SECURE_DIR,	//	(Security, not used)
	
	Pas_FileKind_NUMTYPES
} Pas_FileKindType;

char	*Pas_GetFileType(Pas_FileKindType fileKind);

/*************
	Pas_DirEntryVolume is for these types:
		Pas_FileKind_VOL_DIR
		Pas_FileKind_SECURE_DIR
*/
typedef struct {						//	volume info - only in Pas_DirEntry[0]
	Pas_VolumeID	volumeID;			//	name of disk volume
	Pas_BlockSpec	endOfVolume;		//	last block in volume
	Byte			numFiles;			//	number of files in directory
	RboShort		loadTime;			//	time of last access
	Pas_DateRec		lastBoot;			//	most recent date settings
} Pas_DirEntryVolume;

typedef struct {						//	regular file info
	Pas_TitleID		titleID;			//	name of file
	RboShort		lastByte;			//	num bytes in last file block
	Pas_DateRec		access;				//	date of last modification
} Pas_DirEntryFile;

typedef union {
	Pas_DirEntryVolume		volume;
	Pas_DirEntryFile		file;
} Pas_DirEntryUnion;

typedef struct {
	Pas_BlockSpec		firstBlock;
	Pas_BlockSpec		lastBlockPlusOne;
	RboShort			fileKind;		//	Pas_FileKindType
	Pas_DirEntryUnion	entryType;
} Pas_DirEntry;

typedef Pas_DirEntry	Pas_Directory[Pas_kMaxDirEntries];

#pragma options align = reset

Boolean		Pas_IsPas(DiskImageRec *imageRec);
void		Pas_Catalog(DiskImageRec *imageRec);
void		Pas_SanitizeName(char *pasNameZ, short maxLenS);

#endif