/**************************
**
** $Id:  Finder.c
** $VER: Finder.c V2.06 (04.10.96) by Chris Jones
**
** File Finder Utility with wildcards.
** Based on Amiga Shopper Tutorial by Toby Simpson.
**
** Creation Date: 17.01.96
** Revision History:
**                2.00 : (17.01.96) Initial version (beta release)
**                2.01 : (18.01.96) Added AppMenu support
**                                   (Public Release #1 - AUI May '96)
**                2.02 : (04.02.96) Added option to start program
**                                   iconified via tooltype.
**                                   (Beta Release)
**                2.03 : (04.04.96) Added 'Busy Pointer' while
**                                   searching for files.
**                                   (Not Released)
**                2.04 : (19.07.96) Finder's window will now open on
**                                   the default public screen, not
**                                   on Workbench. (Workbench is
**                                   usually the default public
**                                   screen, but not always).
**                                  When the Zoom gadget is used, the
**                                   ListView no longer forgets what it
**                                   was displaying.
**                                  Major bug fix - In previous
**                                   versions, the Listview would
**                                   'forget' any filenames which left
**                                   the current view.
**                                  Source cleaned up a bit. Some of
**                                   functions generated by GadToolsBox
**                                   which have to be modified have been
**                                   moved from "Finder_GUI.c" to 
**                                   "Finder.c". This makes redesigning
**                                   the GUI easier as the file needs
**                                   less editing.
**                                   NOTE: See "Finder_GUI.c" for the
**                                          Instructions on the changes
**                                          necessary.
**                                   (Not Released)
**                2.05 : (27.07.96) MAJOR bug fix. The IDCMP handler has
**                                   been altered so that is uses no CPU
**                                   time at all instead of (as was the
**                                   case in earlier versions) swallowing
**                                   all spare CPU time and thereby
**                                   causing slow down on everything else.
**                                  Totally new error handling system.
**                                   Up until now I never tested Finder
**                                   in any situation which might cause
**                                   it to fail. When I did, I noticed
**                                   that the error handling system was
**                                   massively flawed. I was using the
**                                   function "sprintf" which copies text
**                                   to a variable, but I was passing it
**                                   a file pointer (stderr). If any of
**                                   the error messages were called this
**                                   caused a crash (e.g. If it is run on
**                                   <OS3.0). Now, Finder opens a small
**                                   CON: window as soon as any faults
**                                   appear and leaves the window until
**                                   the user closes it. It also gives
**                                   a rough idea of a possible solution
**                                   to the problem.
**                                  Changed the ListView from being Read-
**                                   Only to the Show Selected option.
**                                   This has no effect on the operation
**                                   of Finder, but it does mean that
**                                   when you are trying to remember the
**                                   name/path of a file in the display
**                                   while scrolling around, you can mark
**                                   it by clicking on it and it will
**                                   change colour to blue and remain so.
**                                   (I only added this as I thought it
**                                   might be useful).
**                                   (Public Release #2 - Aminet)
**                2.06 : (04.10.96) Nothing particularly new, just added
**                                   the checking for a keyfile. However,
**                                   the program IS NOT shareware, the
**                                   keys are available freely from me.
**                                   This is simply a way of keeping track
**                                   of how many people (if any!) use
**                                   Finder and if it is worth me 
**                                   continuing development. If you use it
**                                   PLEASE register it. IT IS FREE!!!
**                                  Ooops! Just noticed another silly bug!
**                                   If your started Finder via wb, it would
**                                   open the libraries twice (silly me!)
**                                   I only spotted this because the
**                                   registration req. is in the library
**                                   opening routine, so it popped up twice!
**                                   This has now been removed!
**
**
** To compile, type "dcc -3.0 finder.c -o Finder" at a command line.
**  and if you have DICE and the Exec 3.0 includes installed,
**  it will compile.
** If you want CPU optimisation, use -020 or -030 options in DICE
**
** VERY IMPORTANT: If you are using GadToolsBox and wish to alter the
**  GUI and re-generate it's source code you must first consult the
**  "ReadMe" file in the "Source" directory.
**
** Wherever possible, I have put comments in the source so it
** should be fairly easy to follow.
**
** My very largest thanks _MUST_ go to Toby Simpson who wrote the
** C Tutorial that this is based on. He is entirely responsible
** for my desire to program. I saw the first 'episode' of his
** tutorial and knew I had bought 'Complete Amiga C' (by Cliff
** Ramshaw) for a good reason. After many months playing with the
** very excellent 'GadToolsBox' (nice one Jan) with not a ROM
** Kernel manual in sight (not easy!) my Finder was born.
** Without Toby, this would be a program which did nothing except
** appear in the 'Tools' menu and read ToolTypes (not very useful)!
**
** However, I would like to complain that the original GUI that
** Toby used was ridiculously complicated (it scaled to fit the
** screen it was on). GadTools provides a perfectly good solution
** to this; If Finder is unable to open it's screen/window, it will
** "fall back" onto a custom screen. Also, the program GUI was not
** finished when I stopped reading Amiga Shopper (i.e. the Cancel
** button).
**
** Other than that, cheers Toby, I would like to buy you a pint.
**
**                                                       Chris.
*/

/* Includes, defines, etc. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <dos/dos.h>
#include <dos/dostags.h>
#include <exec/exec.h>
#include <exec/libraries.h>
#include <exec/types.h>
#include <intuition/intuition.h>
#include <intuition/classes.h>
#include <intuition/classusr.h>
#include <intuition/imageclass.h>
#include <intuition/gadgetclass.h>
#include <libraries/gadtools.h>
#include <graphics/displayinfo.h>
#include <graphics/gfxbase.h>
#include <clib/dos_protos.h>
#include <clib/alib_protos.h>
#include <clib/exec_protos.h>
#include <clib/intuition_protos.h>
#include <clib/gadtools_protos.h>
#include <clib/graphics_protos.h>
#include <clib/utility_protos.h>
#include <clib/wb_protos.h>
#include <workbench/workbench.h>
#include <workbench/startup.h>

#define HELP_RAW_KEY 95 /* Raw key code for 'HELP' */

#include "Finder_GUI.c"

/* Prototype funcrions */
extern int  wbmain(struct WBStartup *wbs);
extern void OpenLibs(void);
extern void main(int argc, char argv[]);
extern void CloseResources(void);
extern void About_Req(void);
extern void GUI_Find(void);
extern void BusyPointer(struct Window *FinderWnd, struct Requester *myReq);
extern void NormalPointer(struct Window *FinderWnd, struct Requester *myReq);
extern BOOL SearchDir(char *directory, char *pattern);
extern BOOL NotifyFind(char *file, BOOL log_find);
extern void ClearGUI_List(void);
extern void AppMenuHide(void);
extern void VanillaPressed(char vanilla_value);
extern void RawPressed(char raw_value);
extern void GadgetPressed(char gadget_value);
extern int RegisterNagReq(void);

/* Global variables. */
long  files_matched = 0;   /* Total # of files found */
char  *VERSION = "\0$VER: Finder V2.06 (04.10.96)"; /* Version string */
char  fname[256];
char  Name[256];
char  Path[256];
extern struct DiskObject *def_assign;
int   result = NULL; /* Variable used when calling certain fuctions */
struct List            find_list;
struct IntuiMessage   *m;
char                   key_pressed;
char                   help_command[256];
BOOL                   running = TRUE;
SHORT                  Id;
FILE                  *error_pointer;


/* Library bases */
extern struct Library *SysBase;
struct Library *GadToolsBase  = NULL;
struct Library *IntuitionBase = NULL;
struct Library *UtilityBase   = NULL;
struct GfxBase *GfxBase       = NULL;
struct Library *WorkbenchBase = NULL;
struct Library *IconBase      = NULL;

/***************
**
** int wbmain(struct WBStartup *wbs)
**
** Workbench entry point.
**
** This makes Finder run from Wb.
**
** This function is messy because Tooltypes are case-sensitive
** so you need to check for any different spellings.
**
*/
int wbmain(struct WBStartup *wbs)
{

   BOOL menu = FALSE;
   BPTR oldlock;
   struct WBArg *wba;
   struct DiskObject *dob;
   UBYTE **ta, *s;

   /* Open Libraries */
   OpenLibs();

   /* Check our Tooltypes */
      wba = wbs->sm_ArgList;
      if (wbs->sm_NumArgs > 1)
         {
          NameFromLock(wba[1].wa_Lock,(STRPTR)fname,256);
          AddPart((STRPTR)fname,(STRPTR)wba[1].wa_Name,256);
          oldlock = CurrentDir(wba[1].wa_Lock);
          dob     = (struct DiskObject *)GetDiskObject(wba[1].wa_Name);
          CurrentDir(oldlock);
          if (dob)
           {
            if (dob->do_ToolTypes)
               {
                ta = (UBYTE **)dob->do_ToolTypes;
                if (s = (UBYTE *)FindToolType((char **)ta,"ACTION"))
                 {
                  if (MatchToolValue(s,(UBYTE *)"MENU"))       menu = TRUE; /* Here is the case stuff */
                  if (MatchToolValue(s,(UBYTE *)"menu"))       menu = TRUE; /* (mENu, mEnu, meNu, etc.*/
                  if (MatchToolValue(s,(UBYTE *)"Menu"))       menu = TRUE; /* are not checked! */
                 }
               }
           }
         }
       else
         {
          oldlock = CurrentDir(wba->wa_Lock);
          dob     = (struct DiskObject *)GetDiskObject(wba->wa_Name);
          CurrentDir(oldlock);
          if (dob)
             {
              if (dob->do_ToolTypes)
                 {
                  ta = (UBYTE **)dob->do_ToolTypes;
                  if (s = (UBYTE *)FindToolType((char **)ta,"ACTION"))
                     {
                      if (MatchToolValue(s,(UBYTE *)"MENU"))    menu = TRUE;
                      if (MatchToolValue(s,(UBYTE *)"menu"))    menu = TRUE;
                      if (MatchToolValue(s,(UBYTE *)"Menu"))    menu = TRUE;
                     }
                 }
              FreeDiskObject(dob);
             };
          }

   if (menu)
      {
       /* User wants us to enter the Tools menu */
       AppMenuHide();

       /* User must have selected the AppMenuItem so, run the IDCMP handler */
       NewList(&find_list);
       do
         {
          result = HandleFinderIDCMP();
         }
       while (result!=0);

       /* If we are here, the user must have quit */
       CloseResources();
       exit(0);
       return;
      }

   else
      {
      return(main(0,0));
      }

   return;

}

/*****************
**
** void OpenLibs(void)
**
** Function to open required libraries
**
*/
void OpenLibs(void)
{

   /* Open libraries */
   if (!(IntuitionBase = OpenLibrary("intuition.library", 39L)))
      {
       fprintf(error_pointer, "Can't open intuition.library V39+\n");
       fprintf(error_pointer, " Check you are using OS3.0+\n");
       exit(0);
      }

   /* Ooooo, new routine! */
   /* Before we do any more of the old lib opening */
   /* Let's find out if Finder has been registered...*/
   FILE *finder_pointer;

   if (!(finder_pointer=fopen("s:Finder.key","r")))
      {
         RequesterNagReq();
      }
   fclose(finder_pointer);

    if (!(GadToolsBase = OpenLibrary("gadtools.library", 39L)))
      {
       fprintf(error_pointer, "Can't open gadtools.library V39+\n");
       fprintf(error_pointer, " Check you are using OS3.0+\n");
       CloseLibrary(IntuitionBase);
       exit(0);
      }
    if (!(UtilityBase = OpenLibrary("utility.library", 39L)))
      {
       fprintf(error_pointer, "Can't open utility.library V39+\n");
       fprintf(error_pointer, " Check you are using OS3.0+\n");
       CloseLibrary(IntuitionBase);
       CloseLibrary(GadToolsBase);
       exit(0);
      }
    if (!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 39L)))
      {
       fprintf(error_pointer, "Can't open graphics.library V39+\n");
       fprintf(error_pointer, " Check you are using OS3.0+\n");
       CloseLibrary(IntuitionBase);
       CloseLibrary(GadToolsBase);
       CloseLibrary(UtilityBase);
       exit(0);
      }
    if (!(IconBase = OpenLibrary("icon.library", 39L)))
      {
       fprintf(error_pointer, "Can`t open icon.library V39+\n");
       fprintf(error_pointer, " Check you are using OS3.0+\n");
       CloseLibrary(IntuitionBase);
       CloseLibrary(GadToolsBase);
       CloseLibrary(UtilityBase);
       CloseLibrary((struct Library *)GfxBase);
       exit(0);
      }

   /* Setup HELP command */
   sprintf(help_command, "run <NIL: >NIL: Sys:Utilities/Multiview HELP:Finder.guide");

   /* All done, so return */
   return;

}

/***************
**
** void main (int argc, char argv[])
**
** CLI Entry Point
**
** This function is called by CLI entry and the wbmain() function.
** It basically sets up the window and does the
**  input loop (IDCMP Handler).
**
*/
void main(int argc, char argv[])
{

   /* Setup Error Output system */
   if(!(error_pointer=fopen("CON:10/10/320/80/FinderError/AUTO/CLOSE/WAIT","w")))
      {
      fclose(error_pointer);
      CloseResources();
      exit(0);
      }

   /* Open our libraries */
   if(GfxBase==NULL)
      {
      OpenLibs();
      }

   /* Since we were called from CLI (or any icon work is finished), we don`t need icon.library */
   if (IconBase)  CloseLibrary(IconBase);

   /* Call function to set the screen up properly */
   result = SetupScreen();
   if (result!=0)
      {
       fprintf(error_pointer, "Error opening screen\n");
       fprintf(error_pointer, " Check you have Workbench open\n or there is another screen\n defined as the default public\n");
       CloseResources();
       exit(0);
      }

   /* Call function to open our window */
   result = OpenFinderWindow();
   if (result!=0)
      {
       fprintf(error_pointer, "Error opening window\n");
       fprintf(error_pointer, " Check the resolution of this screen\n If it is too small,\n Finder will not run, but\n should have opened its\n own screen.\n");
       CloseResources();
       exit(0);
      }

   /* Activate our window */
   /* The window should have the GT_ACTIVATE tag, but this makes sure */
   ActivateWindow(FinderWnd);

   /* Initialise the file list and clear the listview (should by empty anyway) */
   ClearGUI_List();

   /* Put up welcome message to user */
   NotifyFind("", FALSE);
   NotifyFind("", FALSE);
   NotifyFind("        Finder V2.06 by Chris Jones", FALSE);
   NotifyFind("        ©1996 Dynamic Software", FALSE);
   NotifyFind("        All Rights Reserved", FALSE);
   NotifyFind("", FALSE);
   NotifyFind("        For more information, please see the docs", FALSE);
   NotifyFind("         or press 'HELP'.", FALSE);

   /* Call IDCMP handler loop function */
   do
     {
      result = HandleFinderIDCMP();
     }
   while (result!=0);

   /* If we are here, the user has selected a quit so we need to close down */
   CloseResources();

   /* Close our error window */
   fclose(error_pointer);

   /* Everything is finished and closed */
   return;

}

/**************
**
** int HandleFinderIDCMP( void )
**
** Handles all incoming messages from Intuition (e.g. button clicks, etc)
**
** Returns "FALSE" if the program needs to be quit
** All other functions (e.g. redraws, zooming, finding, etc.) are handled
**  from this function. (Not very efficient, but time saving!)
**
*/

int HandleFinderIDCMP( void )
{

   WaitPort(FinderWnd->UserPort);
   while( m = GT_GetIMsg( FinderWnd->UserPort )) {

      CopyMem(( char * )m, ( char * )&FinderMsg, (long)sizeof( struct IntuiMessage ));

      Id = ((struct Gadget *)(m->IAddress))->GadgetID;
      GT_ReplyIMsg( m );

switch ( FinderMsg.Class ) {

   case  IDCMP_REFRESHWINDOW:
         GT_BeginRefresh( FinderWnd );
         GT_EndRefresh( FinderWnd, TRUE );
   break;

   case  IDCMP_CLOSEWINDOW:
         AppMenuHide();
   break;

   case  IDCMP_VANILLAKEY:
         VanillaPressed(m->Code);
   break;

   case  IDCMP_RAWKEY:
         /* Call RAW key handler */
         RawPressed(m->Code);
   break;

   case  IDCMP_GADGETUP:
         /* Call gadget handler */
         GadgetPressed(Id);
   break;

break;
      }
   }
   return( running );
}

/****************
**
** void VanillaPressed(char vanilla_value)
**
** Deals with any key strokes within the normal ASCII set
**
*/
void VanillaPressed(char vanilla_value)
{

/* Key presses don't need to be case-sensetive */
/* Therefore, convert upper case to lower; thus */
key_pressed = vanilla_value;
if (key_pressed >= 'A' && key_pressed <='Z')
   key_pressed = key_pressed + 0x20;

/* Act on the key press */
switch(key_pressed)
   {
   case 'f': /* FIND button has been chosen */
      GUI_Find();
   break;

   case 'q': /* QUIT button has been chosen */
      running = FALSE;
   break;

   case 'h': /* HELP button has been chosen */
      SystemTags(help_command, SYS_Input, NULL, SYS_Output, NULL, TAG_DONE);
   break;

   case 'a': /* ABOUT button has been chosen */
      About_Req();
   break;

   case 's': /* Search dir string gadget has been chosen */
      ActivateGadget(FinderGadgets[GD_path], FinderWnd, NULL);
   break;

   case 'p': /* Pattern string gadget has been chosen */
      ActivateGadget(FinderGadgets[GD_pattern], FinderWnd, NULL);
   break;
   }

return;

}

/****************
**
** void RawPressed(char raw_value)
**
** Function to deal with  any non-ASCII key presses
**  Currently, only 'Help' is supported
**
*/
void RawPressed(char raw_value)
{

switch(raw_value)
   {
   case HELP_RAW_KEY: /* Help button */
      SystemTags(help_command, SYS_Input, NULL, SYS_Output, NULL, TAG_DONE);
   break;

break;   
   }

return;

}

/****************
**
** void GadgetPressed(char gadget_value)
**
** Function to deal with any gadget presses
**
*/
void GadgetPressed(char gadget_value)
{

switch(gadget_value)
   {
   case GD_quit:
      running = FALSE;
   break;

   case GD_find:
      GUI_Find();
   break;

   case GD_about:
      About_Req();
   break;

   case GD_help:
      SystemTags(help_command, SYS_Input, NULL, SYS_Output, NULL, TAG_DONE);
   break;
   }

return;

}


/****************
**
** void CloseResources();
**
** Function to close screen, window, libraries, etc.
**
*/
void CloseResources(void)
{

   if (FinderWnd)             CloseFinderWindow();
   if (Scr)                   CloseDownScreen();
   if (IntuitionBase)         CloseLibrary(IntuitionBase);
   if (GadToolsBase)          CloseLibrary(GadToolsBase);
   if (UtilityBase)           CloseLibrary(UtilityBase);
   if (GfxBase)               CloseLibrary((struct Library *)GfxBase);
   if (IconBase)              CloseLibrary(IconBase);
   if (SysBase)               CloseLibrary(SysBase);

return;

}

/*******************
**
** void About_Req(void);
**
** Function to display simple about requester.
** This uses the _VERY_ simple 'EasyRequest'
**
*/
void About_Req( void )
{
   /* Set up information for requester */
   struct Requester tinyReq;
   struct EasyStruct about =
      {
       sizeof(struct EasyStruct),
       0,
       "About Finder",

       "Finder V2.06\nBy Chris Jones\n©1996 Dynamic Software\nAll rights reserved.\n\nFor more information, see docs or press 'Help'.\n\nFinder is FREEWARE.\nPlease copy it to all your friends.\n\nTo contact author, see docs\n",
       "Continue"
       };

   /* Call requester */
   BusyPointer(FinderWnd, &tinyReq);
   EasyRequest(NULL, &about, NULL, NULL);
   NormalPointer(FinderWnd, &tinyReq);

   return;

}

/*********************
**
** void BusyPointer(struct Window *FinderWnd, struct Requester *myReq)
**
** Function to put a busy pointer on main window if 'About' is displayed
** and while the GUI_Find() function is operating.
** This is so the user can't carry on using the program while there are
**  about requesters showing. (This would cause problems).
**
*/
void BusyPointer(struct Window *FinderWnd, struct Requester *myReq)
{

   InitRequester(myReq);
   Request(myReq, FinderWnd);
   SetWindowPointer(FinderWnd,  WA_BusyPointer, TRUE,
                                WA_PointerDelay,   TRUE,
                                TAG_END);
   return;

}

/********************
**
** void NormalPointer (struct Window *FinderWnd, struct Requester *myReq)
**
** Function to restore pointer to normal.
**
*/
void NormalPointer(struct Window *FinderWnd, struct Requester *myReq)
{

   ClearPointer(FinderWnd);
   EndRequest(myReq, FinderWnd);

return;

}

/**************************
**
** 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.
**
** This function is a shameless copy of Toby Simpson's function
*/

BOOL  SearchDir(char *directory, char *pattern)
{

   __aligned struct  FileInfoBlock     fib;

   BPTR     lk    = NULL;
   char     full_path[255];

   /*
   ** Attempt to get a lock and the initial FIB:
   */
   if (!(lk = Lock(directory, ACCESS_READ)))
      {
      fprintf(error_pointer, "Error accessing directory\n");
      return FALSE;
      }

   if (!(Examine(lk, &fib)))
      {
      fprintf(error_pointer, "Error accessing FileInfoBlock\n");
      return FALSE;
      }

   /*
   ** Scan directory:
   */
   while (ExNext(lk, &fib))
      {
      /*
      ** Deal with CTRL-C (from CLI or 'break'):
      */
    if (SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C)
      {
      fprintf(error_pointer, "Received a Ctrl-C break\n Search stopped\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;

}

/**************************
**
** BOOL  NotifyFind(char *file, BOOL log_find)
**
** Notify that a file was found. The file which matched is passed in
** and this is then shown on the screen in what every way the program
** decides. Returns FALSE for an error.
** If "log_find" is TRUE, this match is counted.
**
** This is also a copy of Toby Simpson's equivalent function.
*/

BOOL  NotifyFind(char *file, BOOL log_find)
{

   struct   Node  *node;
   char           *text_ptr;

   /*
   ** Count matches if required:
   */
   if (log_find)  files_matched++;

   /*
   ** Allocate memory for a list node:
   */
   if (!(node = (struct Node *)malloc(sizeof(struct Node))))
      {
      fprintf(error_pointer, "Error allocating memory.\n Close some other programs\n and try again\n");
      return FALSE;
      }

   if (!(text_ptr = malloc(strlen(file) + 1)))
      {
      free(node);
      return FALSE;
      }

   /*
   ** Initialise our new node, and add it to the list:
   */
   strcpy(text_ptr, file);

   node->ln_Name = text_ptr;
   node->ln_Pri  = 0;

   AddTail(&find_list, node);

   /*
   ** Update the display gadget so it shows the new list:
   */
   GT_SetGadgetAttrs(FinderGadgets[GD_filelister], FinderWnd, NULL,
      (GTLV_Labels), &find_list,
      (GTLV_Top),    files_matched,
      (TAG_DONE));

   return TRUE;

}

/**************************
**
** void  ClearGUI_List(void)
**
** Clears out any memory occupied by the list we build of any matches
** found during the find operation.
**
** Guess what, Toby Simpson wrote one quite similar to this!
*/

void  ClearGUI_List(void)
{

   struct   Node  *node;

   /*
   ** Clear out list if anything in it:
   */
   while (node = RemHead(&find_list))
      {
      free(node->ln_Name);
      free(node);
      }

   NewList(&find_list);    /* Re-initialise list in case it is used again */

   return;

}

/**************************
**
** 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.
**
** Toby Simpson was 'ere
*/

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(FinderGadgets[GD_filelister], FinderWnd, NULL,
      (GTLV_Labels), NULL,
      (TAG_DONE));
   files_matched = 0;

   /*
   ** Activate 'Busy Pointer'
   */
   SetWindowPointer(FinderWnd,
                     WA_BusyPointer, TRUE,
                     WA_PointerDelay, TRUE,
                     TAG_END);

   /*
   ** Pull out search strings:
   */
   NotifyFind("", FALSE);

   strcpy(search_dir,    ((struct StringInfo *)FinderGadgets[GD_path]->SpecialInfo)->Buffer);
   strcpy(search_string, ((struct StringInfo *)FinderGadgets[GD_pattern]->SpecialInfo)->Buffer);
   sprintf(work_string,  "Searching '%s' for files matching '%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);
      }

   /*
   ** Return Pointer to normal
   */
   ClearPointer(FinderWnd);

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

}

/*******************
**
** void AppMenuHide( void )
**
** Closes window and puts name in menu bar
**
** This one is actually mine! (Well, it is based on the Aminet ROM
** Kernel examples!)
*/
void AppMenuHide( void )
{

   struct MsgPort      *myport  =NULL;
   struct AppMenuItem  *appitem =NULL;
   struct AppMessage   *appmsg  =NULL;
   LONG count=0L;
   BOOL success=0L;

   if (WorkbenchBase = OpenLibrary("workbench.library",39))
     {
     if(myport = CreateMsgPort())
       {
       /* Add our own AppMenuItem to the Workbench Tools Menu */
       appitem=AddAppMenuItemA(0L,                   /* Our ID# for item */
                               0L,                   /* Our UserData     */
                              "Finder V2.06",        /* MenuItem Text    */
                               myport,NULL);         /* MsgPort, no tags */

      /* Hide Finder by closing our window and screen */
      if (FinderWnd) CloseFinderWindow();
      if (Scr)       CloseDownScreen();

       if(appitem)
         {

         /* For this program, we allow the AppMenuItem to be selected */
         /* only once, then we remove it and re-open Finder */
         WaitPort(myport);
         while((appmsg=(struct AppMessage *)GetMsg(myport)))
           {
           /* Handle messages from the AppMenuItem - we have only one  */
           /* item so we don't have to check its appmsg->am_ID number. */
           /* We find our userdata pointer in appmsg->am_UserData      */
   
           ReplyMsg((struct Message *)appmsg);
           }
         success=RemoveAppMenuItem(appitem);
         }

       /* Clear away any messages that arrived at the last moment */
       /* and let Workbench know we're done with the messages     */
       while(appmsg=(struct AppMessage *)GetMsg(myport))
         {
          ReplyMsg((struct Message *)appmsg);
         }
       DeleteMsgPort(myport);
       }
     CloseLibrary(WorkbenchBase);
     }

   /* Re-open and activate window and screen */
   SetupScreen();
   OpenFinderWindow();
   ActivateWindow(FinderWnd);

   /*
   ** Update the display gadget so it shows the new list:
   */
   GT_SetGadgetAttrs(FinderGadgets[GD_filelister], FinderWnd, NULL,
      (GTLV_Labels), &find_list,
      (GTLV_Top),    files_matched,
      (TAG_DONE));


   /* We're finished, so return */
   return;

}

/*******************
**
** void RequesterNagReq(void);
**
** Function to display simple nag requester.
** This uses the _VERY_ simple 'EasyRequest'
**
*/
int RequesterNagReq( void )
{
   /* Set up information for requester */
   struct EasyStruct nag =
      {
       sizeof(struct EasyStruct),
       0,
       "Registering Finder",

       "WARNING: You have not registered Finder V2.06\nTo do so IS FREE, YES FREE\n\nSend a mail to me and I will send\nyou the key.\n\nE-Mail: ee61cj@ee.surrey.ac.uk\n\n\nREMEMBER IT IS FREE.\n",
       "Continue"
       };

   /* Call requester */
   EasyRequest(NULL, &nag, NULL, NULL);

   return;

}
