/*
 *  AddIcon.c - Copyright © 1994 by S.R. & P.C.
 *
 *	Created:	23 May 1992  12:00:40
 *  Modified:   18 Dec 1994  16:59:33
 *
 *  Make>> rx BumpRev AddIcon 1 3
 *  Make>> sc <file>.c
 *  Make>> slink LIB:cs.o <file>.o SC SD ND BATCH NOICONS TO <file> LIB LIB:c.lib
 */

#include <libraries/WhatIsBase.h>
#include <proto/WhatIs.h>
#include <clib.h>
#include "AddIcon_rev.h"

// Startup Modules...
CliArgs; 

struct Library *WhatIsBase;
struct Library *IconBase;

#define MAXFULLNAMELEN 255

char *Template = "FileName/A,ONLYTYPE/K,FILESONLY/S,DIRSONLY/S,QUIET/S,FLOAT/S,OVERWRITE/S,ALL/S";
char *CliHelp = "AddIcon V"VERSIONREVISION" © 1992-94 [32mS.R. & P.C.[31m";
static char Version[] = VERSTAG;

#define ARG_FileName 0
#define ARG_ONLY		1
#define ARG_FILES		2
#define ARG_DIRS		3
#define ARG_QUIET		4
#define ARG_FLOAT		5
#define ARG_OVERWRITE	6
#define ARG_ALL			7
#define ARG_ENDARG		8


static void GetDefIconsDir(char *Buf)
{
	#define DOSLISTFLAGS	(LDF_READ|LDF_VOLUMES|LDF_ASSIGNS)
	struct DosList *dl;
	BOOL Done = FALSE;

	if (dl = LockDosList(DOSLISTFLAGS)) {
		if (FindDosEntry(dl, "ICONS", DOSLISTFLAGS)) {
			strcpy(Buf, "ICONS:");
			Done = TRUE;
		}
		UnLockDosList(DOSLISTFLAGS);
	}
	if (!Done)
		strcpy(Buf, "ENV:Sys");
}


/* FIB can be null but give it if you alredy have it. */

BOOL AddIcon(char *FileName, FileType OnlyType, BOOL Quiet, BOOL Float, BOOL Overwrite, struct DiskObject ** LastDOb, FileType * LastType, struct FileInfoBlock * FIB)
{
	char *IconName = NULL;
	char Buf[255];
	FileType Type;
	LONG WBType = 0;
	BOOL Idem;
	BOOL Ok = FALSE;	/* assume the worst */
	struct DiskObject *dob = NULL;
	BPTR L;

	if (!Quiet) {
		Printf("%-32s  ", FileName);
		Flush(Output());
	}
	SPrintf(Buf, "%s.info", FileName);
	if (!Overwrite && (L = Lock(Buf, ACCESS_READ))) {
		UnLock(L);
		if (!Quiet)
			PutStr("Icon already exist.\n");
		return TRUE;
	}
	Type = WhatIsTags(FileName, WI_Deep, DEEPTYPE, (FIB) ? WI_FIB : TAG_IGNORE, FIB, TAG_DONE);
	if (!Quiet) {
		Printf("%-12s ", GetIDString(Type));
		Flush(Output());
	}
	if ((OnlyType != TYPE_UNSCANNED) && CmpFileType(Type, OnlyType)) {
		if (!Quiet)
			PutStr("Type not desired\n");
		return TRUE;
	}
	Idem = !CmpFileType(Type, *LastType);

	if (CmpFileType(Type, TYPE_UNKNOWNFILETYPE)) {
		if (!CmpFileType(Type, GetIDType("Volume"))) {
			IconName = "def_Disk";
			FileName = "Disk";
			WBType = WBDISK;	/* To use ROM resident icon if no def_Tool defined in ENV:Sys */
		}
		else if (!CmpFileType(Type, GetIDType("Dir"))) {
			IconName = "def_Drawer";
			WBType = WBDRAWER;	/* To use ROM resident icon if no def_Tool defined in ENV:Sys */
		}
		else if (IconName = GetIconName(Type)) {
			if (!Stricmp(IconName, "def_Tool"))
				WBType = WBTOOL;	/* To use ROM resident icon if no def_Tool defined in ENV:Sys */
			else if (!Stricmp(IconName, "def_Project"))
				WBType = WBPROJECT;	/* To use ROM resident icon if no def_Project defined in ENV:Sys */
		}
		if (!Quiet) {
			if (IconName) {
				Printf("%s...", IconName);
				Flush(Output());
			}
			else
				Printf("No icon defined!\n");
		}
		GetDefIconsDir(Buf);
		AddPart(Buf, IconName, 50);		// Use AddPart() so that user can configure DEFICONS:def_Mumble is S:FileTypes
		if ((dob = (Idem) ? *LastDOb : ((WBType) ? GetDefDiskObject(WBType) : GetDiskObject(Buf)))) {
			if (Float) {
				dob->do_CurrentX = NO_ICON_POSITION;
				dob->do_CurrentY = NO_ICON_POSITION;
			}
			if (PutDiskObject(FileName, dob)) {
				if (!Quiet)
					PutStr("Ok\n");
				if (!Idem) {
					if (*LastDOb)
						FreeDiskObject(*LastDOb);
					*LastDOb = dob;	/* memorise the current icon */
					*LastType = Type;	/* memorise the current type */
				}
				Ok = TRUE;
			}
			else
				PutStr("Can't write icon !\n");
		}
		else if (IconName)
			PutStr("Can't read icon.\n");
	}
	else
		PutStr("Unknown file type.\n");
	return Ok;
}


long Main(char *argv[], struct WBStartup *WBenchMsg)
{
	long rc = 0, NumSub = 0;
	char *FileName;
	BOOL Files, Dirs, Quiet, Float, OverWrite, All;
	struct AnchorPath *AP;

	FileName = argv[ARG_FileName];
	Files = (BOOL) argv[ARG_FILES];
	Dirs = (BOOL) argv[ARG_DIRS];
	Quiet = (BOOL) argv[ARG_QUIET];
	Float = (BOOL) argv[ARG_FLOAT];
	OverWrite = (BOOL) argv[ARG_OVERWRITE];
	All = (BOOL) argv[ARG_ALL];

	if (!(IconBase = OpenLibrary("icon.library", 37L)))
		return 20;
	if (WhatIsBase = OpenLibrary("whatis.library", 0)) {
		if (AP = AllocVec(sizeof(struct AnchorPath) + 256, MEMF_PUBLIC|MEMF_CLEAR)) {
			struct DiskObject *LastDOb = NULL;
			FileType LastType = TYPE_UNKNOWNFILETYPE, OnlyType = TYPE_UNSCANNED;
			LONG MatchErr;
			BPTR StartDir;

			if (argv[ARG_ONLY])
				OnlyType = GetIDType(argv[ARG_ONLY]);
			AP->ap_BreakBits = SIGBREAKF_CTRL_C;	/* Break on these bits	*/
			AP->ap_Strlen = 255;
			AP->ap_Flags = (All) ? APF_DODOT : APF_DODOT|APF_DOWILD;	/* allow convertion of '.' to CurrentDir */

			switch (ParsePatternNoCase(FileName, AP->ap_Buf, 256)) {
			case 1:		// Pattern
				StartDir = CurrentDir(((struct Process *) SysBase->ThisTask)->pr_CurrentDir);
				for (MatchErr = MatchFirst(FileName, AP); MatchErr == 0; MatchErr = MatchNext(AP)) {
					if (AP->ap_Flags & APF_DirChanged) {
						CurrentDir(AP->ap_Current->an_Lock);
					}
					if (AP->fib_DirEntryType > 0) {
						if (AP->ap_Flags & APF_DIDDIR) {
							if (!Files)
								AddIcon(AP->fib_FileName, OnlyType, Quiet, Float, OverWrite, &LastDOb, &LastType, &AP->ap_Info);
							/* clear the completed directory flag */
							AP->ap_Flags &= ~APF_DIDDIR;
							NumSub--;
						}
						else {
							if (All) {
								long i;

								if (!Quiet) {
									for (i=0; i<NumSub; i++)
										Printf("    ");
									Printf("[33m%s  (dir)[31m\n", AP->fib_FileName);
								}
								/* make it enter the directory */
								AP->ap_Flags |= APF_DODIR;
								NumSub++;
							}
							else
								AddIcon(AP->fib_FileName, OnlyType, Quiet, Float, OverWrite, &LastDOb, &LastType, &AP->ap_Info);
						}
					}
					else {		// File
						if (!Dirs && !MatchPatternNoCase("\X80.INFO", AP->fib_FileName))
							AddIcon(AP->fib_FileName, OnlyType, Quiet, Float, OverWrite, &LastDOb, &LastType, &AP->ap_Info);
					}
				}
				MatchEnd(AP);	/* This absolutely, positively must be called, all of the time. */
				CurrentDir(StartDir);
				if (MatchErr != ERROR_NO_MORE_ENTRIES) {
					PrintFault(MatchErr, "AddIcon");
					rc = RETURN_ERROR;
				}
				break;
			case 0:
				// Normal file or dir, no pattern.
				if (!MatchPatternNoCase("\X80.INFO", AP->fib_FileName))
					AddIcon(FileName, OnlyType, Quiet, Float, OverWrite, &LastDOb, &LastType, NULL);
				break;
			default:
				PrintFault(IoErr(), "AddIcon");
				rc = RETURN_ERROR;
			}
			if (LastDOb)
				FreeDiskObject(LastDOb);
			FreeVec(AP);
		}
		CloseLibrary(WhatIsBase);
	}
	else
		Printf("Requires whatis.library\n");
	CloseLibrary(IconBase);
	return rc;
}

