/*

         *********************************************************
         *                                                       *
         *          The Betelgeuse File Requester                *
         *             (c) Hugh Allan 1987                       *
         *                                                       *
         *    It is FREE to use the FR.o object file in any PD   *
         *    program but... If the program you use FR.o in is   *
         *  comercial or ShareWare, you MUST send 10 pounds to:  *
         *                                                       *
         *             Hugh Allan                                *
         *             Betelgeuse Development                    *
         *             Ness Castle                               *
         *             Dores Rd                                  *
         *             Inverness IV1 2DJ                         *
         *             Scotland                                  *
         *                                                       *
         *********************************************************


Get_File                                                           Get_File

NAME
    Get_File -- Displays File Requester and gets FileName.

SYNOPSIS
    Get_File(Window,String,FileBuffer,DirBuffer);

FUNCTION
   This function displays a requester on the same screen as your window, and
   returns NULL if the user selected Cancel, or a pointer to the filebuffer.
   The requester is argument compatable with the excellent MicroSmiths PD
   requester so it can be slotted into existing programs that need their
   requester to appear on their custom screen. The program may preset the
   File and Dir buffers to any string they want. Note that the file and
   directory strings are independantly played with, so the dir and file
   names combined may not be the name of an existing file. The Parent
   gadget for various complex reasons does not use the ParentDir function
   , it strips the last directory off the Dir Buffer. The difference is
   un-noticable if the Dir Buffer has been set with a full drive and
   path. The string is automatcally centred and the name is taken from
   the screen, not the window so that a title can appear even in the case
   that the window is a titleless one....

INPUTS
   Window     == pointer to an Intuition Window structure.
   String     == pointer to a null terminated string.
   DirBuffer  == pointer to buffer for Directory Name.
   FileBuffer == pointer to buffer for File Name.

RESULT
   If user selects cancel, NULL is returned.
   else a pointer to the file buffer is returned.

BUGS
   Well... None that I can find, but it crashed a lot in development
   (don't all amiga progs?) and I was never totally happy that the
   bug that crashed it has gone. Also even when the requester is
   apparently doing nothing it runs loops and doesn't Wait, not that
   this should be a problem... (and of course, its actually a WINDOW
   and not a requester! This is so it can be dragged about, but it
   does mean input is not blocked from the caller window)

SEE ALSO
   None.




p.s. I've been a little cheeky and borrowed the source from the MicroSmiths
Demo cos I'm just TOO lazy to write my own. Hope you don't mind guys!

*/


/*

    ***************************************
    * Betelgeuse File Requester Version 2 *
    ***************************************

The file requester has been twiddled to make it slightly nicer, the new
additions are...

o Entry highlighting
o Uses REAL Disk Name
o Sorts entries into alpha order
o separates directories from files
o HD Bug sorted (Uses HD0: instead of HD:)

Entry Highlighting works by checking each entry for either an extension or a
comment pointed to in an extra argument to Get_File. i.e.

   Get_File(MyWindow,"Load Icon",File,Dir,"info");

this will highlight any entry with "info" as an extension, or "info" as a
comment. Use the AmigaDOS FileNote command or the SetComment function to add
comments to files...

Real Disk Names means the file requester uses "Hyper:" or "Workbench:"
instead of DF1: or DF0: etc. This may not affect you if your program is just
using the File requester to load files but it is invaluable if your program
saves references to files.

Alphabetical Order and separanting directories from files are there to make
the file list more manageable. Note that although the file requester does
its best to keep the entires still while the user aims his pointer at one,
entries near the bottom of the requester may still run away from the user
while the requester is taking a directory!

The HD bug existed because I don't have a hard drive, and only noticed it
when being forced to use other requesters.

Other bugs.... Sometimes when you're using the pot gadget to move around the
directory, it misses files at the end. This only happens if you're moving
the pot real fast. Its really a bug in intuition and nothing to do with me,
guv.

If you have any suggestions for imrovements don't hesitate to mail me,
either my snail mail or one of these MailBoxs

Prestel: 011111314
CIX: hallan

            **********************************************
            *      Desperate plea for spondulix          *
            * The wonderous BFR has been in limited      *
            * circulation for a short while and I havent *
            * heard a peep out of anyone. If you send    *
            * £5(or more) to the above address I'll put  *
            * you on the mailing list, and you will      *
            * recieve info on new Betelgeuse PD/ShareWare*
            * programs. The Amiga ShareWare scene is     *
            * almost dead in the UK and your contribution*
            * will make me more likely to write and      *
            * update new ShareWare and recommend it to   *
            * other proggers.                            *
            *                                            *
            *  Givus the money sonny, or I'll tell Ron   *
            *  to have a little word with you.           *
            **********************************************


               *****************************************
               *    The usual hellos and insults       *
               *                                       *
               * Hello to my ol' mate who I never hear *
               * from now-a-days, DJ. Robert Macdougall*
               * who I hear far too much from, the     *
               * entire hacking community of Inverness *
               * (Both of you), John Burge, RH, Si     *
               * Grant, Andy Grant and all the little  *
               * Grants. Jim Franklin, All on the CIX  *
               * Amiga.Dev and Amiga conferences, all  *
               * on Betelgeuse 5, the board that made  *
               * disk error a house hold word(s). Esp  *
               * Mike Scott, Angie Thompson, Steve     *
               * Smith, Kenneth Roback, String Fellow, *
               * Alan Sugar(No, not that one) and      *
               * anyone else who knows me!!!!!(hic)    *
               *****************************************

*/



/*****
   Demo Program for using FILE NAME REQUESTER
    This program shows how to use the file name requester, getfil.o

(c) 1986 by MicroSmiths, Inc.
Permission is granted to use the object code routine 'getfile' in any
Amiga program, commercial or otherwise, EXCEPT that it shall NOT BE
used in any Text Editor, and it shall NOT BE SOLD as an OBJECT MODULE
or in a LIBRARY.

    This program is used with the Object Code file, 'getfil.o',
to provide a file name requester.  The object code file is posted
in the 'listings' area.

    The object code file will need to be truncated if you got these
two files via modem.  The correct size for 'getfile.o' is 5680 bytes.

    This program will compile using the Lattice 'C' compiler.  The program
is linked with the command shown below:

Alink df1:lib/lstartup.obj,gfdemo.o,getfile.o LIB df1:lib/lc.lib,df1:lib/amiga.lib TO gfdemo

  The basic call is:

   getfile(Window,Hailing_string,file_name,directory_name);

Where:
   Window is a pointer to your window
   Hailing_string is a prompt displayed in the requester
   file_name is a text array which will be altered by getfile,
      it returns the file name.
   directory_name is a text array altered by getfile, it
      is the directory.

    The return value is either a pointer to your buffer, file_name,
   or NULL if the user selected CANCEL.

    You must reserve two text areas for file and directory like so:

TEXT   file_name[34];
TEXT   dir_name[67]

   Please, if you find any bugs in getfil.o, let us know ASAP so
we can update this file.
************************************************************************/

#include <exec/types.h>
#include <exec/devices.h>
#include <intuition/intuition.h>

struct IntuitionBase *IntuitionBase;   /* Handles for inutition and   */
struct GfxBase   *GfxBase;      /* graphics libraries      */

/************************************************************************/
/* You supply two string buffers, for the filename and directory name   */
/* You may pre-initialize them to any string you want.         */
/************************************************************************/
#define   FNAME_SIZE   33
TEXT file_name[FNAME_SIZE+1];
TEXT dir_name[FNAME_SIZE+FNAME_SIZE+1];

struct Window   *p_Window;      /* Handle for window we open  */

/* Struct to open Window   */
struct NewWindow NewWindow = {
   10,10,400,150, 2,1,      /* Left,Top, Width,Height, Pens  */
   MOUSEBUTTONS | MOUSEMOVE | MENUPICK | CLOSEWINDOW, /* IDCMP flags */
   SMART_REFRESH | ACTIVATE | WINDOWSIZING | WINDOWCLOSE |
     WINDOWDRAG | WINDOWDEPTH | REPORTMOUSE,   /* Window flags   */
   NULL, NULL,         /* First Gadget, Checkmark image */
   (UBYTE *)"MicroSmiths Requester Demo", /* Window Title   */
   NULL, NULL,         /* Screen and BitMap      */
   100,60, 32767,32767,      /* Window Sizing limits      */
   WBENCHSCREEN};      /* WBENCH or CUSTOMSCREEN   */

/* Menu description  */
struct IntuiText menu_text = { 2,1,JAM2, 20,1, NULL, (UBYTE *)"Open",NULL };

struct MenuItem menu_item = {
   NULL, 0,10,100,10,      /* Next item, Left, Top, Width, Height */
   HIGHCOMP | ITEMENABLED | ITEMTEXT | COMMSEQ,
   NULL,(APTR)&menu_text,   /* MutualExclude, ItemFill      */
   NULL, 'Q', NULL };      /* SelectFill, Command , SubItem   */

struct Menu simple_menu = {
   NULL, 0,0,60,10, MENUENABLED, "Menu", &menu_item };


/****************************************************************/
/* init_window()                  */
/*   Opens Window, sets up menu strip and I/O Port      */
/****************************************************************/
init_window()
{
if ( ! (IntuitionBase = (struct IntuitionBase *)
   OpenLibrary("intuition.library",29)) ||
     ! (GfxBase =(struct GfxBase *)OpenLibrary("graphics.library",29)) )
         exit(20);

/* Open the window, sets handle p_Window   */
if ( ! (p_Window = (struct Window *)OpenWindow( &NewWindow )) ) {
    CloseLibrary(GfxBase);    CloseLibrary(IntuitionBase);
    exit(20);
    }

SetMenuStrip( p_Window, &simple_menu );
}

/***************************************************************/
/* clear_window                                                */
/*     Clears window and screen set up by init_window          */
/***************************************************************/
clear_window()
{
   ClearMenuStrip(p_Window);
   CloseWindow(p_Window);
}


/*** Main:  Open window, process inputs , close window ***/
main()
{
struct IntuiMessage *message;   /* Gets input event   */
int   class,code;      /* Event information   */
BOOL   quit_flag;      /* Application flags   */

init_window();                 /* Open the window   */

for ( quit_flag = FALSE; ! quit_flag ; ) {

    while (! (message=(struct IntuiMessage *)GetMsg(p_Window->UserPort)) )
   WaitPort( p_Window->UserPort );  /* Wait for input event          */

    class = message->Class;    code = message->Code;   /* Get event info */
    ReplyMsg( message );    /* Tell intuition we're through with event   */

    switch ( class ) {           /*    Process the input event           */
   case CLOSEWINDOW:   quit_flag = TRUE;
       break;

   /* Heres what you're looking for...   */
   case MENUPICK:
      if ( (MENUNUM( code ) == 0) && (ITEMNUM( code ) == 0) ) {
      /* Call up the filename requester   */
      if ( Get_File(p_Window, "Your String Here",file_name,dir_name,"info") )
          printf("Got name %s directory %s\n",file_name,dir_name);
      else
          printf("User aborted getfile request\n");
      }
   }
    }
clear_window();               /* Return all resources and exit */
}
