/*************************************************************************

                            F I L E M A N A G E R

**************************************************************************

**************************************************************************

 Hacked from File Window (a public domain program)...

*************************************************************************/

#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/lists.h>
#include <exec/libraries.h>
#include <exec/ports.h>
#include <exec/interrupts.h>
#include <exec/io.h>
#include <exec/memory.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <intuition/intuition.h>
#include <string.h>

#define LOAD 500
#define SAVE 600
#define DELETE 700
#define CANCEL 800
#define QUIT 900
#define PANIC 1000

#define DRAWER_LENGTH 100
#define FILE_LENGTH 30
#define TOTAL_LENGTH 130

#define MAK_PIC 0

USHORT File_Man();
STRPTR right_pos();
APTR save_file_info();
BOOL file_comp();
BOOL directory();
BOOL last_check();
BOOL new_drawer();
BOOL pick_file();
BOOL request_ask();
void put_in();
void deallocate_file_info();
void change_device();
void parent();
void request_ok();
void display_list();
void connect_dir_file();
void adjust_string_gadgets();
void delete_file_dir();


extern struct TextAttr Font;
extern struct Screen *FirstScreen;
extern struct IntuiMessage *message;
extern struct Window *FirstWindow;
extern struct IntuitionBase *IntuitionBase;
extern USHORT *Pointer,*Sleepy;
extern SHORT op_code;

struct Window *file_window;
struct IntuiMessage *my_gadget_message;

struct file_info
{
  BYTE name[28];        
  BOOL directory;      
  struct file_info *next; 
};


struct FileInfoBlock *file_info;
struct FileLock *lock, *Lock();


BOOL file_lock; 
BOOL more_files; 
BOOL first_file;


struct file_info *first_pointer;

/* ********************************************************************* */
/* * IntuiText structures for the requesters                           * */
/* ********************************************************************* */


struct IntuiText text_request=
{
  0, 2,                 
  JAM1,                 
  15, 5,  
  &Font,
  NULL,    
  NULL     
};


struct IntuiText ok_request=
{
  0, 2,    
  JAM1,    
  6, 3,    
  &Font,
  "OK",    
  NULL     
};


struct IntuiText option1_request=
{
  0, 2,    
  JAM1,    
  6, 3,     
  &Font, 
  NULL,    
  NULL  
};


struct IntuiText option2_request=
{
  0, 2,   
  JAM1,   
  6, 3,   
  &Font, 
  NULL,     
  NULL     
};


SHORT points4[]=
{
   0,  0,
  44,  0,
  44, 14,
   0, 14,
   0,  0
};



SHORT points6[]=
{
   0,  0,
  60,  0,
  60, 14,
   0, 14,
   0,  0
};


struct Border border_text4=
{
  0, 0,        
  1, 2, JAM1,  
  5,           
  points4,     
  NULL         
};



struct Border border_text6=
{
  0, 0,        
  1, 2, JAM1,  
  5,           
  points6,     
  NULL        
};



/* ********************************************************************* */
/* * Information for the proportional gadget                           * */
/* ********************************************************************* */

struct Image image_prop;

struct PropInfo prop_info=
{
  AUTOKNOB|
  FREEVERT, 
  0,0,     
  0,       
  0xFFFF,   
  0,0,0,0,0,0 
};

struct Gadget gadget_proportional=
{
  NULL,                   
  290, 50, 21, 72,         
  GADGHCOMP,               
  GADGIMMEDIATE|FOLLOWMOUSE|RELVERIFY,
  PROPGADGET,              
  (APTR) &image_prop,      
  NULL,                    
  NULL,                    
  NULL,                    
  (APTR) &prop_info,      
  NULL,                    
  NULL                    
};



/* UndoBuffer for the string gadgets: */
UBYTE name_backup[DRAWER_LENGTH];



/* ********************************************************************* */
/* * Information for the string gadget "Drawer:"                       * */
/* ********************************************************************* */

UBYTE drawer_name[DRAWER_LENGTH];


SHORT points28s[]=
{
   -7, -4,
  200, -4,
  200, 11,
   -7, 11,
   -7, -4
};



struct Border border_text28s=
{
  0, 0,       
  1, 2, JAM1,  
  5,           
  points28s,   
  NULL         
};


struct IntuiText text_drawer=
{
  1, 2,      
  JAM1,     
  -69, 0,    
  &Font,  
  "Drawer:", 
  NULL       
};


struct StringInfo string_drawer=
{
  drawer_name,       
  name_backup,       
  0,                 
  70,                
  0,                 
  0,               
  0, 0,            
  NULL,            
  NULL,            
  NULL,            
};


struct Gadget gadget_drawer=
{
  &gadget_proportional,   
  83, 35, 198, 8,         
  GADGHCOMP,              
  RELVERIFY,           
  STRGADGET,             
  (APTR) &border_text28s, 
  NULL,                 
  &text_drawer,         
  NULL,                 
  (APTR) &string_drawer, 
  NULL,                  
  NULL                    
};



/* ********************************************************************* */
/* * Information for the string gadget "File:"                         * */
/* ********************************************************************* */


UBYTE file_name[FILE_LENGTH];


SHORT points30s[]=
{
   -7, -4,
  244, -4,
  244, 11,
   -7, 11,
   -7, -4
};


struct Border border_text30s=
{
  0, 0,        
  1, 2, JAM1, 
  5,           
  points30s,
  NULL       
};


struct IntuiText text_file=
{
  1, 2,    
  JAM1,   
  -53, 0, 
  &Font, 
  "File:",  
  NULL    
};


struct StringInfo string_file=
{
  file_name,        
  name_backup,    
  0,                
  40,              
  0,              
  0,             
  0, 0,           
  NULL,           
  NULL,            
  NULL,            
};


struct Gadget gadget_file=
{
  &gadget_drawer,      
  66, 129, 240, 8,     
  GADGHCOMP,             
  NULL,                 
  STRGADGET,           
  (APTR) &border_text30s,
  NULL,                  
  &text_file,         
  NULL,                 
  (APTR) &string_file, 
  NULL,                 
  NULL                 
};



/* ********************************************************************* */
/* * Information for the string gadget "Extension"                     * */
/* ********************************************************************* */


UBYTE extension_name[7];


SHORT points6s[]=
{
  -7, -4,
  57, -4,
  57, 10,
  -7, 10,
  -7, -4
};


struct Border border_text6s=
{
  0, 0,        
  1, 2, JAM1,  
  5,            
  points6s,   
  NULL        
};


struct IntuiText text_extension=
{
  1, 2,    
  JAM1,   
  -45, 0,  
  &Font,
  "Ext:",
  NULL    
};


struct StringInfo string_extension=
{
  extension_name,  
  name_backup,       
  0,               
  7,                
  0,               
  0,                
  0, 0,            
  NULL,            
  NULL,           
  NULL,           
};


struct Gadget gadget_extension=
{
  &gadget_file,          
  253, 17, 59, 8,          
  GADGHCOMP,              
  RELVERIFY,              
  STRGADGET,               
  (APTR) &border_text6s,   
  NULL,                   
  &text_extension,         
  NULL,                    
  (APTR) &string_extension, 
  NULL,                 
  NULL                  
};



/* ********************************************************************* */
/* * Information for the boolean gadget parent "<"                     * */
/* ********************************************************************* */



SHORT points1[]=
{
   0,  0,
  20,  0,
  20, 15,
   0, 15,
   0,  0
};



struct Border border_text1=
{
  0, 0,       
  1, 2, JAM1,  
  5,          
  points1,   
  NULL         
};


struct IntuiText text_parent=
{
  1, 2,    
  JAM1,     
  7,4,    
  &Font,
  "<",     
  NULL    
};


struct Gadget gadget_parent=
{
  &gadget_extension,   
  290, 31, 21, 16,       
  GADGHCOMP,            
  RELVERIFY,            
  BOOLGADGET,          
  (APTR) &border_text1,  
  NULL,                
  &text_parent,      
  NULL,                 
  NULL,               
  NULL,             
  NULL                 
};



/* ********************************************************************* */
/* * Information for the boolean gadget "dh0:"                         * */
/* ********************************************************************* */


struct IntuiText text_dh0=
{
  1, 2,    
  JAM1,   
  7,4,    
  &Font, 
  "dh0:", 
  NULL   
};


struct Gadget gadget_dh0=
{
  &gadget_parent,      
  110, 13, 45, 15,      
  GADGHCOMP,           
  RELVERIFY,          
  BOOLGADGET,            
  (APTR) &border_text4, 
  NULL,                
  &text_dh0,            
  NULL,                 
  NULL,                
  NULL,              
  NULL                 
};



/* ********************************************************************* */
/* * Information for the boolean gadget "df1:"                         * */
/* ********************************************************************* */


struct IntuiText text_df1=
{
  1, 2,    
  JAM1,   
  7,4,     
  &Font, 
  "df1:",  
  NULL   
};


struct Gadget gadget_df1=
{
  &gadget_dh0,          
  59, 13, 45, 15,    
  GADGHCOMP,           
  RELVERIFY,            
  BOOLGADGET,            
  (APTR) &border_text4, 
  NULL,                
  &text_df1,          
  NULL,               
  NULL,              
  NULL,              
  NULL               
};



/* ********************************************************************* */
/* * Information for the boolean gadget "df0:"                         * */
/* ********************************************************************* */


struct IntuiText text_df0=
{
  1, 2,   
  JAM1,  
  7,4,      
  &Font, 
  "df0:",
  NULL     
};


struct Gadget gadget_df0=
{
  &gadget_df1,          
  8, 13, 45, 15,         
  GADGHCOMP,           
  RELVERIFY,           
  BOOLGADGET,           
  (APTR) &border_text4,  
  NULL,                 
  &text_df0,         
  NULL,               
  NULL,              
  NULL,               
  NULL                 
};



/* ********************************************************************* */
/* * Information for the boolean gadget "CANCEL"                       * */
/* ********************************************************************* */


struct IntuiText text_cancel=
{
  1, 2,     
  JAM1,     
  7,4,     
  &Font, 
  "CANCEL",
  NULL    
};


struct Gadget gadget_cancel=
{
  &gadget_df0,         
  177, 144, 61, 15,      
  GADGHCOMP,        
  RELVERIFY,            
  BOOLGADGET,            
  (APTR) &border_text6,  
  NULL,               
  &text_cancel,        
  NULL,                 
  NULL,               
  NULL,               
  NULL                 
};



/* ********************************************************************* */
/* * Information for the boolean gadget "DELETE"                       * */
/* ********************************************************************* */


struct IntuiText text_delete=
{
  1, 2,    
  JAM1,    
  7,4,    
  &Font, 
  "DELETE", 
  NULL    
};


struct Gadget gadget_delete=
{
  &gadget_cancel,       
  110, 144, 61, 15,    
  GADGHCOMP,            
  RELVERIFY,             
  BOOLGADGET,           
  (APTR) &border_text6,   
  NULL,                
  &text_delete,        
  NULL,                
  NULL,               
  NULL,               
  NULL                
};



/* ********************************************************************* */
/* * Information for the boolean gadget "SAVE"                         * */
/* ********************************************************************* */


struct IntuiText text_save=
{
  1, 2,   
  JAM1,  
  7,4,     
  &Font, 
  "SAVE",  
  NULL    
};


struct Gadget gadget_save=
{
  &gadget_delete,     
  59, 144, 45, 15,    
  GADGHCOMP,            
  RELVERIFY,            
  BOOLGADGET,           
  (APTR) &border_text4, 
  NULL,              
  &text_save,          
  NULL,                 
  NULL,              
  NULL,               
  NULL                
};



/* ********************************************************************* */
/* * Information for the boolean gadget "LOAD"                         * */
/* ********************************************************************* */


struct IntuiText text_load=
{
  1, 2,    
  JAM1,   
  7,4,     
  &Font, 
  "LOAD", 
  NULL   
};


struct Gadget gadget_load=
{
  &gadget_save,        
  8, 144, 45, 15,       
  GADGHCOMP,            
  RELVERIFY,            
  BOOLGADGET,            
  (APTR) &border_text4,   
  NULL,                
  &text_load,        
  NULL,               
  NULL,                
  NULL,                
  NULL             
};



UBYTE display_text[8][34];

struct IntuiText text_list[8]=
{
  {
    1, 0,         
    JAM2,        
    0,0,           
    &Font,       
    display_text[0], 
    &text_list[1]  
  },
  {
    1, 0,           
    JAM2,          
    0,8,           
    &Font,       
    display_text[1], 
    &text_list[2]   
  },
  {
    1, 0,          
    JAM2,           
    0,16,          
    &Font,       
    display_text[2], 
    &text_list[3]   
  },
  {
    1, 0,        
    JAM2,            
    0,24,          
    &Font,        
    display_text[3],
    &text_list[4]  
  },
  {
    1, 0,           
    JAM2,          
    0,32,            
    &Font,       
    display_text[4], 
    &text_list[5]  
  },
  {
    1, 0,           
    JAM2,        
    0,40,           
    &Font,        
    display_text[5], 
    &text_list[6]  
  },
  {
    1, 0,          
    JAM2,        
    0,48,        
    &Font,    
    display_text[6], 
    &text_list[7]  
  },
  {
    1, 0,         
    JAM2,           
    0,56,          
    &Font,      
    display_text[7],
    NULL           
  }
};



struct Gadget gadget_display[8]=
{
  {
    &gadget_display[1], 
    8, 50, 276, 12,     
    GADGHNONE,       
    GADGIMMEDIATE,    
    BOOLGADGET,        
    NULL,            
    NULL,           
    NULL,            
    NULL,           
    NULL,              
    NULL,             
    NULL             
  },
  {
    &gadget_display[2],
    8, 62, 276, 8,     
    GADGHNONE,        
    GADGIMMEDIATE,    
    BOOLGADGET,        
    NULL,             
    NULL,            
    NULL,            
    NULL,             
    NULL,           
    NULL,           
    NULL              
  },
  {
    &gadget_display[3], 
    8, 70, 276, 8,     
    GADGHNONE,         
    GADGIMMEDIATE,    
    BOOLGADGET,      
    NULL,            
    NULL,            
    NULL,             
    NULL,            
    NULL,            
    NULL,             
    NULL            
  },
  {
    &gadget_display[4], 
    8, 78, 276, 8,    
    GADGHNONE,        
    GADGIMMEDIATE,    
    BOOLGADGET,       
    NULL,             
    NULL,           
    NULL,             
    NULL,             
    NULL,           
    NULL,           
    NULL           
  },
  {
    &gadget_display[5], 
    8, 86, 276, 8,      
    GADGHNONE,       
    GADGIMMEDIATE,   
    BOOLGADGET,       
    NULL,           
    NULL,           
    NULL,           
    NULL,            
    NULL,           
    NULL,            
    NULL            
  },
  {
    &gadget_display[6],
    8, 94, 276, 8,     
    GADGHNONE,          
    GADGIMMEDIATE,     
    BOOLGADGET,       
    NULL,              
    NULL,            
    NULL,             
    NULL,             
    NULL,            
    NULL,              
    NULL             
  },
  {
    &gadget_display[7], 
    8, 102, 276, 8,      
    GADGHNONE,         
    GADGIMMEDIATE,   
    BOOLGADGET,         
    NULL,             
    NULL,             
    NULL,           
    NULL,            
    NULL,             
    NULL,              
    NULL              
  },
  {
    &gadget_load,       
    8, 110, 276, 12,   
    GADGHNONE,         
    GADGIMMEDIATE,     
    BOOLGADGET,         
    NULL,               
    NULL,               
    NULL,             
    NULL,             
    NULL,            
    NULL,            
    NULL              
  }
};



/* ********************************************************************* */
/* * BIG BOX                                                           * */
/* ********************************************************************* */


SHORT points_big_box[]=
{
   8, 50,
 283, 50,
 283, 121,
   8, 121,
   8, 50
};


struct Border border_big_box=
{
  0, 0,          
  1, 2, JAM1,    
  5,             
  points_big_box, 
  NULL          
};



/* ********************************************************************* */
/* * Information for the window                                          */
/* ********************************************************************* */

struct NewWindow new_file_window=
{
  0,0,             
  320, 163,       
  0,1,           
  CLOSEWINDOW|    
  GADGETDOWN|
  MOUSEMOVE|
  GADGETUP,
  ACTIVATE|        
  WINDOWDEPTH|
  WINDOWDRAG|
  WINDOWCLOSE|
  SMART_REFRESH,
  &gadget_display[0], 
  NULL,              
  NULL,            
  NULL,              
  NULL,            
  0,0,               
  0,0,             
  CUSTOMSCREEN
};


file_manager(FirstWindow,Pointer,op_code)
struct Window *FirstWindow;
USHORT *Pointer;
SHORT op_code;
  {
    USHORT operation;
    UBYTE file[TOTAL_LENGTH];	
    strcpy(file, "df1:");
    operation=File_Man("File Manager  V1.0 ",
                        NULL,
            		   0,0,
			               file,
                        op_code);
                        
    do_Sleepy(FirstWindow);
    ClearPointer(file_window);
    SetPointer(file_window,Sleepy,25,16,0,0);
                        
    switch(operation)
      {
   case SAVE: if( op_code == 1)
                {
                  WindowToFront(FirstWindow);   
                  SaveIt(file);
                }
              if( op_code == 2)
                {
                  SaveParms(file);
                }  
	           break;      
         
	case LOAD: if( op_code == 3)
                {
                  LoadIt(file, MAK_PIC);
                }
   
              if( op_code == 4)
                {
                  LoadParms(file);
                }
	
	           break;
		   
	case CANCEL:
	
	             break;
		     
	case QUIT: 
	
	           break;
		   
	case PANIC:
	
	            break;
      }


    do_Pointer(FirstWindow);
    ClearPointer(file_window);
    SetPointer(file_window,Pointer,16,16,0,0);

    if(op_code == 1 || op_code == 2)
    {
      OnGadget(&gadget_load,file_window,NULL);
      OnGadget(&gadget_delete,file_window,NULL);
    }
    
    if(op_code == 3 || op_code == 4)
    {
      OnGadget(&gadget_save,file_window,NULL);
      OnGadget(&gadget_delete,file_window,NULL);
    }
    
    if(op_code == 5 || op_code == 6)
    {
      OnGadget(&gadget_save,file_window,NULL);
      OnGadget(&gadget_load,file_window,NULL);
    } 
    
    if(file_window)
    CloseWindow(file_window);
    	
    return(TRUE);

  } /**** Close off file_manager ****/
  
  

USHORT File_Man( title, extension, x, y, total_file_name, op_code )
STRPTR title;
STRPTR extension;
SHORT  x, y;
STRPTR total_file_name;
SHORT op_code;
{
  int temp1;
  int file_count;

  ULONG class; 
  USHORT code; 
  APTR address;

  int position;

  BOOL working;     
  BOOL fix_display;

  STRPTR string_pointer; 
  struct file_info *pointer;

  USHORT operation; 
  

  file_lock=FALSE; 
  more_files=FALSE; 


  
  prop_info.VertBody=0xFFFF;
  prop_info.HorizBody=0;
  prop_info.VertPot=0;
  prop_info.HorizPot=0;
  
 
  strcpy(extension_name, extension);

 
  if(*extension_name != '\0')
    text_extension.FrontPen=3; 
  else
    text_extension.FrontPen=1;


 
  new_file_window.LeftEdge=x;
  new_file_window.TopEdge=y;
  new_file_window.Title=title;
  new_file_window.Screen=FirstScreen;  
  
  if((file_window=(struct Window *)OpenWindow(&new_file_window)) == NULL)
  {
   
    return(PANIC);
  }
   DrawBorder(file_window->RPort, &border_big_box, 0, 0);
   ClearPointer(file_window);
   SetPointer(file_window,Pointer,16,16,0,0);

  
  if((file_info=(struct FileInfoBlock *)
    AllocMem(sizeof(struct FileInfoBlock), MEMF_PUBLIC|MEMF_CLEAR))==NULL)
  {
    /* Could not allocate memory for the FileInfoBlock! */
    /* Inform the user about the problem, and leave. */
    request_ok("NOT enough memory!");
    return(PANIC);
  }

  if(op_code == 1 || op_code == 2)
    {
      OffGadget(&gadget_load,file_window,NULL);
      OffGadget(&gadget_delete,file_window,NULL);
    }
    
  if(op_code == 3 || op_code == 4)
    {
      OffGadget(&gadget_save,file_window,NULL);
      OffGadget(&gadget_delete,file_window,NULL);
    }
    
  if(op_code == 5 || op_code == 6)
    {
      OffGadget(&gadget_save,file_window,NULL);
      OffGadget(&gadget_load,file_window,NULL);
    } 
    
  if(*total_file_name != '\0')
  {
    
    if((lock=Lock(total_file_name, ACCESS_READ))==NULL)
    {
      /* If it falls through to this there are problems */
      /* File/directory/device did NOT exist! */
    }
    else
    {
      
      file_lock=TRUE;
  
      if((Examine(lock, file_info))==NULL)
      {
       
        request_ok("ERROR reading file/directory!");
      }
      else
      {
        
        if(directory(file_info))
        {
          /* It is a directory! */

          *file_name='\0'; /* Clear file_name string. */
          /* Copy total_file_name into drawer_name string: */
          strcpy(drawer_name, total_file_name);

          /* Since it is a directory, we will look for more files: */
          more_files=TRUE;
        }
        else
        {
          /* It is a file! */
          
          /* Separate the file name from the path: */
          if(string_pointer=right_pos(total_file_name, '/'))
          {
            /* Copy the file name into file_name string: */
            strcpy(file_name, string_pointer+1);
            *string_pointer='\0';
          }
          else
          {
            if(string_pointer=right_pos(total_file_name, ':'))
            {
              /* Copy the file name into file_name string: */
              strcpy(file_name, string_pointer+1);
              *(string_pointer+1)='\0';
            }
            else
            {
              strcpy(file_name, total_file_name);        
              *drawer_name='\0';
              *total_file_name='\0';
            }
          }
          strcpy(drawer_name, total_file_name);
         

        } /* directory? */

      } /* examine object */

    } /* "lock" file/directory? */

  } /* Anything in total_file_name string? */

  adjust_string_gadgets();


  new_drawer(); 

  position=0;       
  fix_display=FALSE;
  first_file=TRUE;  
  file_count=0;    


  working=TRUE;
  do
  {
   
    if(more_files==FALSE)
      Wait(1 << file_window->UserPort->mp_SigBit);

    while(my_gadget_message = (struct IntuiMessage *)
      GetMsg(file_window->UserPort))
    {
      class = my_gadget_message->Class;
      code = my_gadget_message->Code;
      address = my_gadget_message->IAddress;

      ReplyMsg((struct Message *)my_gadget_message);

      switch(class)
      {
        case MOUSEMOVE:
         
          fix_display=TRUE;
          break;

        case CLOSEWINDOW:
         
          connect_dir_file(total_file_name);
          working=FALSE;
          operation=QUIT;
          break;

        case GADGETDOWN:
           
           for(temp1=0; temp1 < 8; temp1++)
           {
             if(address == (APTR)&gadget_display[temp1])
             {
              
               pick_file(temp1+position);
             }
           }
           break;



        case GADGETUP:
          
           if(address == (APTR)&gadget_load)
           {
             if(last_check(total_file_name))
             {
               working=FALSE;
               operation=LOAD;
             }
             break;
           }


           /* SAVE */
           if(address == (APTR)&gadget_save)
           {
             if(last_check(total_file_name))
             {
               working=FALSE;
               operation=SAVE;
             }
             break;
           }


           /* DELETE */
           if(address == (APTR)&gadget_delete)
           {
             delete_file_dir(total_file_name);
             break;
           }


           /* CANCEL */
           if(address == (APTR)&gadget_cancel)
           {
             connect_dir_file(total_file_name);
             working=FALSE;
             operation=CANCEL;
             break;
           }


           /* df0: */
           if(address == (APTR)&gadget_df0)
           {
             change_device("df0:");
             break;
           }


           /* df1: */
           if(address == (APTR)&gadget_df1)
           {
             change_device("df1:");
             break;
           }


           /* dh0: */
           if(address == (APTR)&gadget_dh0)
           {
             change_device("dh0:");
             break;
           }


           /* DRAWER: */
           if(address == (APTR)&gadget_drawer)
           {
             new_drawer();
             break;
           }


           /* EXTENSION: */
           if(address == (APTR)&gadget_extension)
           {
            
             if(*extension_name != '\0')
               text_extension.FrontPen=3; 
             else
               text_extension.FrontPen=1; 

             RefreshGadgets(&gadget_extension, file_window, NULL);
             new_drawer();
             break;
           }


           /* PARENT: "<" */
           if(address == (APTR)&gadget_parent)
           {
             parent();
             break;
           }


           /* PROPORTIONAL */
           if(address == (APTR)&gadget_proportional)
           {
             fix_display=TRUE;
             break;
           }
      }
    }

    if(fix_display)
    {
      fix_display=FALSE;
      if(file_count > 8)
        position=(int) prop_info.VertPot/(float) 0xFFFF*(file_count-8);
      else
        position=0;
      display_list(position);
    }


    if(more_files)
    {   
      if(ExNext(lock, file_info))
      {
       
        if(stricmp(extension_name, (file_info->fib_FileName+
           strlen(file_info->fib_FileName)-strlen(extension_name)))==0 ||
           directory(file_info) )
        {
          if(first_file)
          {
            first_pointer=(struct file_info *) save_file_info(file_info);
            
            if(first_pointer != NULL)
            { 
              first_pointer->next=NULL; 
              first_file=FALSE;
            }
            file_count=1;
            position=1;
          }
          else
          {
           pointer=(struct file_info *) save_file_info(file_info);
           
            if(pointer !=NULL)
            {
              put_in(first_pointer, pointer);       
              file_count++;
            }
          }
        
          if(file_count > 8)
          {
            ModifyProp
            (
              &gadget_proportional,      
              file_window,              
              NULL,                     
              prop_info.Flags,          
              0,                        
              prop_info.VertPot,        
              0,                         
              (ULONG) 0xFFFF*8/file_count
            );            
            position=(int) prop_info.VertPot/(float) 0xFFFF*(file_count-8);
          }
          else
           position=0;
          display_list(position);
        }
      }
      else
      {       
        more_files=FALSE; 
        if(IoErr() != ERROR_NO_MORE_ENTRIES)
	{
          request_ok("ERROR reading file/directory!");
        }
      }
    }
  } while(working);

  while( (my_gadget_message = (struct IntuiMessage *)
           GetMsg(file_window->UserPort)) )
  {
    ReplyMsg((struct Message *)my_gadget_message);
  }

  deallocate_file_info();

  if(file_lock)
  {
    UnLock(lock);
    file_lock=FALSE;
  }
  
  if(file_info) FreeMem(file_info, sizeof(struct FileInfoBlock));

  
  
  return(operation);
}

void deallocate_file_info()
{
  struct file_info *pointer, *temp_pointer;
   
  if(first_pointer)
  {
    pointer=first_pointer->next;
    
    FreeMem( first_pointer, sizeof(struct file_info));

    while(pointer)
    {    
      temp_pointer=pointer->next;
      
      FreeMem( pointer, sizeof(struct file_info));
      pointer=temp_pointer;
    }
  }
  
  first_pointer=NULL;

  first_file=TRUE;
}

APTR save_file_info(info)
struct FileInfoBlock *info;
{
  struct file_info *pointer;

  if((pointer=(struct file_info *)
    AllocMem(sizeof(struct file_info), MEMF_PUBLIC|MEMF_CLEAR))==NULL)
  {
    request_ok("NOT enough memory!"); 
    more_files=FALSE;
    return(NULL);
  }
  else
  {
    if(strlen(info->fib_FileName) < 28)
      strcpy(pointer->name, info->fib_FileName);
    else
    {
      if( directory(info))
        request_ok("Directory name too long!");
      else    
        request_ok("File name too long!"); 

      FreeMem( pointer, sizeof(struct file_info));
      return(NULL);
    }

    if( directory(info))
      pointer->directory=TRUE; /* It is a directory. */
    else    
      pointer->directory=FALSE; /* It is a file. */
  }
  
  return( (APTR) pointer);
}

BOOL directory(info)
struct FileInfoBlock *info;
{
  if(info->fib_DirEntryType < 0)
    return(FALSE);
  else
    return(TRUE);
}

void put_in(a_pointer, pointer)
struct file_info *a_pointer, *pointer;
{
  struct file_info *old_pointer=NULL;

  while( a_pointer && file_comp(a_pointer->name, pointer->name) )
  {
    old_pointer=a_pointer;
    a_pointer=a_pointer->next;
  }

  if(a_pointer)
  {
    if(old_pointer)
    {
      pointer->next=old_pointer->next;
      old_pointer->next=pointer;
    }
    else
    {
      pointer->next=first_pointer;
      first_pointer=pointer;
    }
  }
  else
  {
    old_pointer->next=pointer;
    pointer->next=NULL;
  }
}

BOOL file_comp(a_pointer, pointer)
struct file_info *a_pointer, *pointer;
{
  if(a_pointer->directory == FALSE && pointer->directory)
    return(FALSE);
    
  if(a_pointer->directory == pointer->directory)
  {
    if(stricmp(a_pointer->name, pointer->name) <= 0 )
      return(TRUE);
    else
      return(FALSE);
  } 
  return(TRUE);
}

STRPTR right_pos(string, sign)
STRPTR string;
char sign;
{
  STRPTR start_pos;
  
  start_pos=string;
  
  while(*string != '\0')
    string++;

  while(*string != sign && string > start_pos)
    string--;
    
  if(*string==sign)
    return(string);

  return(NULL);
}

void change_device(device)
STRPTR device;
{
  strcpy(drawer_name, device);

  adjust_string_gadgets(); 

  new_drawer();
}

BOOL new_drawer()
{
  STRPTR string_pointer;

  /* Unlock: */
  if(file_lock)
  {
    UnLock(lock);
    file_lock=FALSE;
  }
   
  deallocate_file_info();

  ModifyProp
  (
    &gadget_proportional, 
    file_window,         
    NULL,               
    prop_info.Flags,   
    0,                  
    0,                  
    0,                   
    (ULONG) 0xFFFF     
  );

  display_list(0);

  more_files=FALSE;

  if((lock=Lock(drawer_name, ACCESS_READ))==NULL)
  {
    string_pointer=drawer_name+strlen(drawer_name)-1;
    if(*string_pointer==':')
      request_ok("Device NOT found!");
    else
      request_ok("Device/Directory NOT found!");

    return(FALSE); /* ERROR */
  }
  else
  {
    file_lock=TRUE;
  }

  if((Examine(lock, file_info))==NULL)
  {
    request_ok("ERROR reading file/directory!"); 

    return(FALSE); 
  }

  if(directory(file_info))
  {
    more_files=TRUE;
  }
  else
  {
    request_ok("NOT a valid directory name!"); 
    return(FALSE);
  }  
  return(TRUE);
}

void parent()
{
  STRPTR string_pointer;

  if(string_pointer=right_pos(drawer_name, '/'))
  {
    *string_pointer='\0';
  }
  else
  {
    if(string_pointer=right_pos(drawer_name, ':'))
    {
      *(string_pointer+1)='\0';
    }
    else
    {
      *drawer_name='\0';
    }
  }
  
  adjust_string_gadgets();
  
 
  new_drawer();
}

void request_ok(message)
STRPTR message;
{
  text_request.IText=message;
  
  AutoRequest
  (
    file_window,  
    &text_request,
    NULL,        
    &ok_request, 
    NULL,         
    NULL,        
    320,        
    72         
  );
}

BOOL request_ask(message, option1, option2)
STRPTR message, option1, option2;
{
  text_request.IText=message;
  option1_request.IText=option1;
  option2_request.IText=option2;
  
  
  return( (BOOL) AutoRequest
  (
    file_window,     
    &text_request,   
    &option1_request, 
    &option2_request, 
    NULL,             
    NULL,           
    320,            
    72         
  ));
}

void display_list(start_pos)
int start_pos;
{
  struct file_info *pointer;
  int pos, temp1;
  char empty_name[]= "                                 ";
  
  STRPTR string_pointer;
  BOOL clear;
  
  pos=0;
 
  if(first_pointer)
  {
    pointer=first_pointer;

    while(pointer && pos < start_pos)
    {
      pos++;
      pointer=pointer->next;
    }
    
    pos=0;
    while(pointer && pos < 8)
    {
      strcpy(display_text[pos], pointer->name);
      
      clear=FALSE;
      temp1=0;
      string_pointer=display_text[pos];

      if(pointer->directory)
      {
        text_list[pos].FrontPen=3; 
        while(temp1 < 28)
        {
          if(*string_pointer=='\0')
            clear=TRUE;
          if(clear)
            *string_pointer=' ';
          string_pointer++;
          temp1++;
        }
        *string_pointer='\0';
        strcat(display_text[pos], "(Dir)");
      }
      else
      {
        text_list[pos].FrontPen=1;
        while(temp1 < 33)
        {
          if(*string_pointer=='\0')
            clear=TRUE;
          if(clear)
            *string_pointer=' ';
          string_pointer++;
          temp1++;
        }
        *string_pointer='\0';
      }      
      pos++;
      pointer=pointer->next; 
    }
  }

  while(pos < 8)
  {
    strcpy(display_text[pos], empty_name);
    pos++;
  }
  
  PrintIText(file_window->RPort, text_list, 13+3, 53+1);
}

BOOL pick_file(file_pos)
int file_pos;
{
  struct file_info *pointer=NULL;
  STRPTR string_pointer;
  int pos=0;
  
  if(first_pointer)
  {
    pointer=first_pointer;
    
    while(pointer && pos < file_pos)
    {
      pos++;
      pointer=pointer->next;
    }
  }

  if(pointer)
  {
    if(pointer->directory)
    {
      if((strlen(pointer->name)+strlen(drawer_name)+2) <= DRAWER_LENGTH)
      {
        string_pointer=drawer_name+strlen(drawer_name)-1;
        if(*string_pointer==':'  || *string_pointer=='\0' )
          strcat(drawer_name, pointer->name);
        else
        {
          strcat(drawer_name, "/");
          strcat(drawer_name, pointer->name);
        }
   
        adjust_string_gadgets();
      }
      else
      {
        request_ok("Too long drawer string");
        return(FALSE); 
      }
      new_drawer();
      return(TRUE);
    }
    else
    {
      if((strlen(pointer->name)+1) <= FILE_LENGTH)
      {
        strcpy(file_name, pointer->name);
        adjust_string_gadgets();
      }
      else
      {
     
        request_ok("File name too long!"); 
        return(FALSE);
      }
      return(TRUE);
    }
  }
}

void adjust_string_gadgets()
{
  int length;

  length=strlen(file_name);        

  if(length > 28)
    string_file.DispPos=length-28;
  else
    string_file.DispPos=0;

  string_file.BufferPos=string_file.DispPos;
  

  length=strlen(drawer_name);        

  if(length > 22)
    string_drawer.DispPos=length-22;
  else
    string_drawer.DispPos=0;

  string_drawer.BufferPos=string_drawer.DispPos;

  RefreshGadgets(&gadget_file, file_window, NULL);
}

BOOL last_check(name)
STRPTR name;
{
  if(*file_name == '\0')
  {
    request_ok("NO filename selected!");
    return(FALSE);
  }
  else
  {
    connect_dir_file(name);
  }
  return(TRUE);
}

void connect_dir_file(name)
STRPTR name;
{
  STRPTR string_pointer;
         
  strcpy(name, drawer_name);

  if(*file_name != '\0')
  {
    string_pointer=drawer_name+strlen(drawer_name)-1;
    if(*string_pointer==':'  || *string_pointer=='\0' )
    {
      strcat(name, file_name); 
    }
    else
    {
      strcat(name, "/"); 
      strcat(name, file_name);
    }
  }
}

void delete_file_dir(total_file_name)
STRPTR total_file_name;
{
  BOOL delete_it;

  delete_it=FALSE;
  
  if(*file_name == '\0' && *drawer_name != '\0')
  {
   
    if( *(drawer_name+strlen(drawer_name)-1) ==':')
    {
      request_ok("You can NOT delete a device!");
    }
    else
    {
      delete_it=request_ask("OK to delete directory?","DELETE","CANCEL");
                   
      if(delete_it)
      {
        if(file_lock)
        {
          UnLock(lock);
          file_lock=FALSE;
        }
      }
    }
  }
  else
  {
    if(*file_name != '\0')
    {
      delete_it=request_ask("OK to delete file?","DELETE","CANCEL");
    }
    else
    {
      request_ok("NO file/directory selected!");
    }
  }
  
  if(delete_it)
  {
    connect_dir_file(total_file_name);
  
    if(DeleteFile(total_file_name))
    {
     if(*file_name != '\0')
      {
        *file_name='\0'; 
        adjust_string_gadgets();
        new_drawer(); 
      }
      else
      {
        parent(); 
      }
    }
    else
    {
      if(*file_name != '\0')
        request_ok("Could NOT delete the file!");
      else
        request_ok("Could NOT delete directory!");
      new_drawer();
    }
  }
}


