/*
	$VER: ShowIcon v2.1 (23.02.1997)
	Copyright 1994, 1997 by Dalibor Kezele

	Source code compiled with Aztec C 5.0a.
	e-mail :dkezele@mia.os.carnet.hr !!
*/

#include <stdio.h>
#include <exec/memory.h>
#include <libraries/dos.h>
#include <workbench/workbench.h>
#include <workbench/icon.h>
#include <intuition/intuitionbase.h>
#include <intuition/intuition.h>

#define	INTNAME	"intuition.library"
#define	FIB	FileInfoBlock
#define	UCHAR	unsigned char

#define	INTUITION_FAILED	1
#define	ICON_FAILED	2
#define	DISK_FAILED	3
#define	ALLOC_FAILED	4
#define	LOCK_FAILED	5
#define	EXAMINE_FAILED	6
#define	WINDOW_FAILED	7
#define	ILLEGAL_OPTION 8
#define	NO_FILE_GIVEN	9
#define	ILLEGAL_SWITCH 0

struct	FIB	*MyFIB;
struct	Lock	*MyLock;

struct	Library	*IconBase;
struct	IntuitionBase	*IntuitionBase;

struct	DiskObject	*DO;
struct	Gadget	*GD;
struct	NewWindow NW = { 0, 11, 80, 64, 0, 1, CLOSEWINDOW|VANILLAKEY,
			WINDOWDRAG|WINDOWCLOSE|ACTIVATE|RMBTRAP|NOCAREREFRESH, NULL, NULL,
			(UBYTE *)"ShowIcon", NULL, NULL, 0, 0, 0, 0, WBENCHSCREEN };

struct	Window	*WD;
struct	IntuiMessage	*IM = NULL;
struct	Image	*IMG;

static char version[] =
	"$VER: ShowIcon v2.1 (23.02.1997) Copyright 1994, 1997 by Dalibor Kezele";

/* -------------------------------------------------------------------- */

void searchpattern(char *matchname);
	/* searchs matchname and calls showicon() when files match */

UCHAR is_info(char *string);
	/* checks if it is .info file */

UCHAR mystrcmp(char *string1, char *string2);
	/* compares two strings, case insensitive */

UCHAR compare(char *string1, char *string2);
	/* compares string1 and string2 and calls match() is asterisk detected */

UCHAR match(char *entry, char *pattern);
	/* checks if given filename entry matches with pattern */

void showicon(char *filename);
	/* displays icon, filename is the icon filename without ".info" */

void displayerror(int error);
	/* displays an error message */

UCHAR co = 0, io = 0, po = 0, eo = 0, ro = 0, fo = 0;
char helpname[80];

/* -------------------------------------------------------------------- */

int main(int argc, char **argv)
{
register UCHAR i, j;

if(argc == 0)
	return 0;

if((argc == 1) || ((argc > 1) && (*(*(argv+1)) == '?'))){
	printf("\033[1;33mShowIcon\033[31;0m v2.1 (23.02.1997) Copyright 1994, 1997 by Dalibor Kezele\n");
	printf("Usage: %s [options] pattern/filename [pattern/filename..]\n", argv[0]);
	printf("Options:\n");
	printf(" -i : don't write icon \033[33mI\033[31mnformation\n");
	printf(" -c : don't use ANSI \033[33mC\033[31molors\n");
	printf(" -p : don't display icon \033[33mP\033[31micture\n");
	printf(" -e : don't write \033[33mE\033[31mrror messages\n");
	printf("Press \033[33m<ESC>\033[31m to exit during displaying icon image.\n");
	printf("\033[3m<<< Please support PostCardWare! >>>\033[0m\n");
	return 0;
	}

IntuitionBase = (struct IntuitionBase *)OpenLibrary(INTNAME, NULL);
if (IntuitionBase) {
	IconBase = (struct Library *) OpenLibrary(ICONNAME, NULL);
		if (IconBase) {
			for(i = 1; i < argc; i++) {
				if((*(*(argv+i)) + 0) == '-') {
					for(j = 1; j < strlen(*(argv+i)); j++)
						switch(tolower(*(*(argv+i)+j))) {
							case 'i': io = 1; break;
							case 'c': co = 1; break;
							case 'p': po = 1; break;
							case 'e': ro = 1; break;
							default : displayerror(ILLEGAL_OPTION);
							}
					if(ro && po && io) displayerror(ILLEGAL_SWITCH);
				}
				else {
					fo = 1;
					if(checkfile(*(argv+i))) {
							if(is_info(*(argv+i))) {
								strcpy(&helpname[0], (*(argv+i)));
								helpname[strlen(*(argv+i))-5] = 0;
								if(!eo) showicon(&helpname[0]);
								}
							else
								if(!eo) showicon(*(argv+i));
						}
					else
						searchpattern(*(argv+i));
					}
				}
			CloseLibrary(IconBase);
			}
			else displayerror(ICON_FAILED);
	CloseLibrary(IntuitionBase);
	}
	else displayerror(INTUITION_FAILED);

if(!fo) displayerror(NO_FILE_GIVEN);

return 0;
}

/* -------------------------------------------------------------------- */

int checkfile(char *string)
{
register UCHAR i;

for(i = 0; i < strlen(string); i++)
	if((string[i] == '*') || (string[i] == '?')) return 0;

return 1;
}

/* -------------------------------------------------------------------- */

void searchpattern(char *matchname)
{
char *filename;

MyFIB = (struct FIB *) AllocMem(sizeof(struct FIB), MEMF_CLEAR);
if (MyFIB) {
	filename = MyFIB -> fib_FileName;
	MyLock = (struct Lock *) Lock((UCHAR *)"\0", ACCESS_READ);
	if (MyLock) {
		if ((Examine (MyLock, MyFIB))) {

			while (ExNext (MyLock, MyFIB))
	
				if(MyFIB -> fib_EntryType<0)	
					if(MyFIB -> fib_Size != 0)
						if(compare(filename, matchname))
							if(is_info(filename)) {
								strcpy(&helpname[0], filename);
								helpname[strlen(filename)-5] = 0;
								if(!eo) showicon(&helpname[0]);
							}
			}
			else displayerror(EXAMINE_FAILED);

		UnLock(MyLock);
		}
		else displayerror(LOCK_FAILED);
		FreeMem (MyFIB, (LONG)sizeof(struct FIB));

	}
	else displayerror(ALLOC_FAILED);
}

/* -------------------------------------------------------------------- */

UCHAR is_info(char *string)
{
register UCHAR counter=0;
static char *info = "\0ofni.";

while(counter++<5)
	if(tolower(string[strlen(string)-counter]) != info[counter]) return 0;

return 1;
}

/* -------------------------------------------------------------------- */

UCHAR mystrcmp(char *string1, char *string2)
{

if(strlen(string1) != strlen(string2)) return 0;

while(*string1)
	if (tolower(*string1++) != tolower(*string2++)) return 0;

return 1;
}

/* -------------------------------------------------------------------- */

UCHAR compare(char *string1, char *string2)
{
register UCHAR i;

for(i = 0; i < strlen(string2); i++)
	if((string2[i] == '*') || (string2[i] == '?'))
		return match(string1, string2);

	return mystrcmp(string1, string2);
}

/* -------------------------------------------------------------------- */

UCHAR match(char *entry, char *pattern)
{
register UCHAR i = 0, j = 0, x = 0;

while((i < strlen(pattern)) && (j < strlen(entry))) {
	if(pattern[i] != '?') {
		if(pattern[i] != '*') {
			if(tolower(pattern[i]) != tolower(entry[j])) return 0;	
			}
		else {
			if (++i == strlen(pattern)) return 1;
			if ((pattern[i] == '?') && (pattern[i] == '*')) return 0;
			x = 0;
			while(j < strlen(entry)) {
				if(tolower(pattern[i]) == tolower(entry[j])) { x = 1; break; }
				j++;
				}
			if((j == strlen(entry)) && (x != 1)) return 0;
			}
		}
	i++; j++;
	}
return 1;
}
/* -------------------------------------------------------------------- */

void showicon(char *filename)
{
register int x, y, d;

DO = (struct DiskObject *) GetDiskObject(filename);
if (DO) {

	GD = (struct Gadget *)&DO -> do_Gadget;
	GD -> NextGadget = NULL;
	GD -> GadgetText = NULL;
	GD -> SpecialInfo = NULL;
	GD -> UserData = NULL;

	NW.FirstGadget = GD;
	NW.Width = GD -> Width + 80;
	NW.Height = GD -> Height + 50;
	x = GD -> LeftEdge;
	y = GD -> TopEdge;

	GD -> LeftEdge = (NW.Width - (GD -> Width)) / 2;
	GD -> TopEdge = (NW.Height - (GD -> Height) + 6) / 2;
	NW.TopEdge = ((IntuitionBase -> ActiveScreen-> Height) - (NW.Height)) / 2;
	NW.LeftEdge = ((IntuitionBase -> ActiveScreen-> Width) - (NW.Width)) / 2;

	IMG = (struct Image *) GD -> SelectRender;
	d = IMG -> Depth;
	if (d > 8) d = 2;

	if(!io) {
		if(co)
			printf("Icon: %s.info, position (%d, %d), size %d x %d, depth %d.\n",
			filename, x, y, GD -> Width, GD -> Height, d);
		else {
			printf("Icon: \033[33m%s.info\033[31m, position ", filename);
			printf("(\033[33m%d\033[31m, \033[33m%d\033[31m), ", x, y);
			printf("size \033[33m%d\033[31m x \033[33m", GD -> Width);
			printf("%d\033[31m, depth \033[33m%d\033[31m.\n", GD -> Height, d);
			}
		}

	if(!po) {
		WD = (struct Window *) OpenWindow(&NW);
		if (WD) {
			while(1) {
				IM = (struct IntuiMessage *)GetMsg(WD -> UserPort);
				if (IM == NULL)
					continue;
				if (IM -> Class == CLOSEWINDOW)
					break;
				if ((IM -> Class == VANILLAKEY) && (IM -> Code == 13))
					break;
	         if ((IM -> Class == VANILLAKEY) && (IM -> Code == 32))
	            break;
				if ((IM -> Class == VANILLAKEY) && (IM -> Code == 27)) {
					eo = 1;
					break;
					}
				ReplyMsg(IM);
				}
			ReplyMsg(IM);
			CloseWindow(WD);
			}
			else displayerror(WINDOW_FAILED);
			FreeDiskObject(DO);
		}
	}
	else displayerror(DISK_FAILED);
}

/* -------------------------------------------------------------------- */

void displayerror(int error)
{
if(!ro) {
	printf("*** ERROR: ");
	switch(error) {
		case INTUITION_FAILED:
			puts("Unable to open intuition.library.");
			break;
		case ICON_FAILED:
			puts("Unable to open icon.library.");
			break;
		case DISK_FAILED:
			puts("Unable to open icon.");
			break;
		case ALLOC_FAILED:
			puts("Unable to allocate memory.");
			break;
		case LOCK_FAILED:
			puts("Unable to lock directory.");
			break;
		case EXAMINE_FAILED:
			puts("Unable to examine directory.");
			break;
		case WINDOW_FAILED:
			puts("Unable to open window.");
			break;
		case NO_FILE_GIVEN:
			puts("No filename.");
			break;
		case ILLEGAL_OPTION:
			puts("Illegal option.");
			break;
		case ILLEGAL_SWITCH:
			puts("Illegal combination of options.");
		}
	}
}
