//	ProCatalog.c

#if 0
#include <ctype.h>	//	for tolower
#include <string.h>
#include <stdio.h>
#include "IC_Errors.h"
#include "ProFileTypes.h"
#include "ProCatalog.h"

#ifndef ushort
	typedef unsigned short ushort;
#endif

/****************************************************
	count blocks used in entire volume
*/
static	ushort			GetUsedBlocks(DiskImageRec *imageRec, ushort total, ushort bitMapBlock)
{
	ushort				loop1, loop2, usedBlocks = 0, mapBlock = 0, 
						lastBitMabBlock = bitMapBlock + (total >> 12); 	//	div 4096 bits per block
	long				curLong;
	Pro_BitMapBlock		*vBitMap;
	OSErr				err = noErr;

	for (; !err && bitMapBlock <= lastBitMabBlock; bitMapBlock++) {

		err = Pro_GetBlock(imageRec, bitMapBlock, &(Pro_Block *)vBitMap);

		if (!err) for (loop1 = 0; loop1 < Pro_kLongsPerBlock && total; loop1++) {
			curLong = (*vBitMap)[loop1];
			
			for (loop2 = 0; loop2 < 32 && total; loop2++) {
				usedBlocks += 1 - ((curLong & 0x80000000) != 0);
				curLong = curLong << 1;
				total--;
			}
		}
	}
	
	return usedBlocks;
}

/****************************************************
	Lock (access bits)
*/
static	char		GetLockedStatus(Pro_AccessPriv access)
{
	char	status	= '*';
	
	if (*(Pro_AccessPrivMem *)&access == *(Pro_AccessPrivMem *)&Pro_kAccess_UNLOCKED)
		status = ' ';
	
	return status;
}


/****************************************************
	File Type
*/
char			*Pro_GetShortFileType(Byte fileType, char *fileTypeStr)
{
	Pro_FileTypeRec	typeRec;
	
	typeRec.fileType	= fileType;
	typeRec.auxType		= 0;
	
	if (Pro_GetFileType(&typeRec)) {
	//	strcpy(fileTypeStr, typeRec.typeStr);
	} else {
		sprintf(fileTypeStr, "$%02X", (short)fileType);
	}

	return fileTypeStr;
}

/****************************************************
	Date and Time
*/
typedef 	char		MonthName[4];
static		MonthName	calandar[12] = {
	"JAN", "FEB", "MAR", "APR", "MAY", "JUN", 
	"JUL", "AUG", "SEP", "OCT", "NOV", "DEC"
};

static	char			*GetDateTimeStr(Pro_DateTime dateTime, char *buf)
{
	Pro_DateTimeMem	dateTimeMem;
	
	dateTimeMem.split.ymd 	= GetRboShort(dateTime.ymd);
	dateTimeMem.split.hm	= GetRboShort(dateTime.hm);
	
	if (dateTimeMem.dt.year > 99)
		dateTimeMem.dt.year -= 100;
	
	//	so it works for null dates
	if (dateTimeMem.dt.month != 0) {
		dateTimeMem.dt.month--;
	}
	
	sprintf(buf, "%2d-%s-%02d %2d:%02d", 
		(int)dateTimeMem.dt.day, 
		calandar[dateTimeMem.dt.month], 
		(int)dateTimeMem.dt.year, 
		(int)dateTimeMem.dt.hour, 
		(int)dateTimeMem.dt.minute
	);

	return buf;
}

/****************************************************
	file length (EOF)
*/
static	char			*GetEndFileStr(Rbo3Byte eof, char *buf)
{
	sprintf(buf, "$%06lX", GetRbo3Bytes(eof));
	return buf;
}

/****************************************************
	subtype/auxtype (bload address)
*/
static	char			*GetSubTypeStr(Byte fileType, RboShort auxType, char *buf)
{
	short		shortAux = GetRboShort(auxType);
	
	switch (fileType) {
		
		case 0x04: {	//	Text
			sprintf(buf, "R=%5d", shortAux);
			break;
		}
		
		case 0x06: {	//	Binary
			sprintf(buf, "A=$%04X", shortAux);
			break;
		}
		
		default: {
			buf[0] = 0;
			break;
		}
	}
	
	return buf;
}

char	*Pro_GetFileDesc(Pro_DirEntry *entry, char *buf)
{
	char			created[16], modified[16];
	char			fileTypeBuf[4], endFileBuf[8], subTypeBuf[8];
	Pro_FileNameStr	nameBuf;

	Pro_GetFileName(entry, nameBuf);
	Pro_GetShortFileType(entry->fileType, fileTypeBuf);
	GetDateTimeStr(entry->modifiedTime, modified);
	GetDateTimeStr(entry->createdTime, created);
	GetEndFileStr(entry->eof, endFileBuf);
	GetSubTypeStr(entry->fileType, entry->auxType, subTypeBuf);

	sprintf(buf, "%c%-15s %s  %6d  %s  %s  %s %s\n", 
		GetLockedStatus(entry->access), 
		nameBuf, 
		fileTypeBuf, 
		(int)GetRboShort(entry->blocksUsed), 
		modified, 
		created, 
		endFileBuf, 
		subTypeBuf
	);
	
	return buf;
}

/****************************************************
	Catalog
*/
void		Pro_Catalog(DiskImageRec *imageRec)
{
	OSErr			err				= noErr;
	ushort			curBlock		= 2, 
					bitMapBlock, 
					entryNum, 
					usedBlocks, 
					totalBlocks;
	Boolean			isKeyBlock		= TRUE, 
					firstTime		= TRUE;
	Pro_DirEntry	*entry;
	Pro_DirBlock	*dirBlock;	
	Pro_FileNameStr	nameBuf;
	char			buf[84];
	
	do {
		err = Pro_GetBlock(imageRec, curBlock, &(Pro_Block *)dirBlock);
		
		if (!err) {
			isKeyBlock	= ((unsigned char)dirBlock->blockType.typeName.stnl.storageType & 0x0E) == 0x0E;
			
			if (firstTime) {
			
				bitMapBlock	= GetRboShort(dirBlock->blockType.key.header.headerType.volume.bitMap);
				totalBlocks	= GetRboShort(dirBlock->blockType.key.header.headerType.volume.totalBlocks);

				//	print volume name
				printf("\nProDOS Volume: /%s\n\n", 
					Pro_GetDirName(&dirBlock->blockType.key.header, nameBuf)
				);
				
				//	and header
				printf(" NAME           TYPE  BLOCKS  MODIFIED         CREATED          ENDFILE SUBTYPE\n\n");
				
				firstTime = FALSE;
			}
			
			for (entryNum = 0; entryNum < (Pro_kMaxEntriesPerBlock - isKeyBlock); entryNum++) {
				if (isKeyBlock) {
					entry = &(dirBlock->blockType.key.entry[entryNum]);
				} else {
					entry = &(dirBlock->blockType.standard.entry[entryNum]);
				}
				
				//	not deleted
				if (*(Byte *)(&entry->typeName.stnl) != 0) {
					printf(Pro_GetFileDesc(entry, buf));
				}
			}
			
			curBlock = GetRboShort(dirBlock->list.next);
		}
	} while (!err && curBlock);
	
	if (!err) {
		usedBlocks = GetUsedBlocks(imageRec, totalBlocks, bitMapBlock);
		
		printf("\nBLOCKS FREE:%5hu     BLOCKS USED:%5hu     TOTAL BLOCKS:%5hu\n\n", 
			totalBlocks - usedBlocks, usedBlocks, totalBlocks
		);
	}
}
#endif