/**************************
**
**	$Id:	search.c
**
**	Search Module: Amiga Shopper Finder Application.
**	By Toby Simpson
*/

#include	"finder.h"
#include	"externals.h"

/**************************
**
**	BOOL	SearchDir(char *directory, char *pattern)
**
**	Search the named directory. All variables are local, this function
**	is recursive. Returns TRUE if the operation was OK, or FALSE for an
**	error.
*/

BOOL	SearchDir(char *directory, char *pattern)
{
#ifdef _DCC
	__aligned struct	FileInfoBlock		fib;
#else
	struct	FileInfoBlock	__aligned	fib;
#endif

	BPTR		lk 	= NULL;
	char		full_path[255];

	/*
	**	Attempt to get a lock and the initial FIB:
	*/
	if (!(lk = Lock(directory, ACCESS_READ)))	return FALSE;
	if (!(Examine(lk, &fib)))									return FALSE;

	/*
	**	Scan directory:
	*/
	while (ExNext(lk, &fib))
		{
		/*
		**	Deal with CTRL-C:
		*/
    if (SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C)
    	{
    	printf("*** Program Aborted\n");
			UnLock(lk);
    	return FALSE;
    	}
		
		/*
		**	Build full path spec:
		*/
		strcpy(full_path, directory);
		AddPart(full_path, fib.fib_FileName, 255);
		
		/*
		**	ID File entry type:
		*/
		if (fib.fib_DirEntryType > 0)
			{
			/*
			**	Got a directory, recursively scan it:
			*/
			if (!(SearchDir(full_path, pattern)))
				{
				UnLock(lk);
				return FALSE;
				}
			}
		else
			{
			/*
			**	Got a file, try a match check:
			*/
			if (MatchPatternNoCase(pattern, fib.fib_FileName))
				NotifyFind(full_path, TRUE);
			}
		}

	UnLock(lk);

	return TRUE;
}

/**************************
**
**	void	GUI_Find(void)
**
**	This routine is responsible for triggering a find operation. It is
**	called if the FIND button, or its keyboard short-cut is pressed.
*/

void	GUI_Find(void)
{
	char		search_dir[64];
	char		search_string[64];
	char		search_pattern[128];
	char		work_string[128];

	/*
	**	Clear the current list, if any:
	*/
	ClearGUI_List();

	GT_SetGadgetAttrs(gadget_list[GID_LIST], finder_window, NULL,
		GTLV_Labels, NULL,
			TAG_DONE);
	files_matched = 0;
							
	/*
	**	Pull out search strings:
	*/
	NotifyFind("", FALSE);
	NotifyFind("-------------------", FALSE);

	strcpy(search_dir, ((struct StringInfo *)sg_Drawer->SpecialInfo)->Buffer);
	strcpy(search_string, ((struct StringInfo *)sg_Search->SpecialInfo)->Buffer);
	sprintf(work_string, "Searching '%s' for '%s'", search_dir, search_string);
	NotifyFind(work_string, FALSE);

	/*
	**	Pre-Parse the AmigaDOS search pattern:
	*/
	ParsePatternNoCase(search_string, search_pattern, 127);

	/*
	**	Start the search:
	*/
	if (!(SearchDir(search_dir, search_pattern)))
		NotifyFind("-- Operation not totally successful.", FALSE);
	else
		{
		sprintf(work_string, "-- %ld matches found", files_matched);
		NotifyFind(work_string, FALSE);
		}

	/*	
	**	Operation complete, return now.
	*/
	return;
}
