/*******************************************/
/* Subroutine to get a filename from disk  */
/* written by: Christian Wolf              */
/*             Matthias-Claudius-Weg 58    */
/*             2190 Cuxhaven 1             */
/*             04721/24269                 */
/*******************************************/

struct NewWindow NewSpecialWindow = {
       170,25,300,150,0,1,
       GADGETUP|GADGETDOWN|DISKINSERTED,
       ACTIVATE,
       NULL,NULL,
       NULL,
       NULL,NULL,
       640,200,640,200,
       WBENCHSCREEN };

struct IntuiText SubTextLoad = {1,0,JAM1,11,2,NULL,"Load",NULL };
struct IntuiText SubTextCancel = {1,0,JAM1,3,2,NULL,"Cancel",NULL };
struct IntuiText TextDf0 = {1,0,JAM1,11,2,NULL,"df0:",NULL };
struct IntuiText TextDf1 = {1,0,JAM1,11,2,NULL,"df1:",NULL };
struct IntuiText TextHd0 = {1,0,JAM1,11,2,NULL,"dh0:",NULL };
struct IntuiText TextDrawer = {1,0,JAM1,12,98,NULL,"Drawer",NULL };
struct IntuiText TextFile = {1,0,JAM1,12,111,NULL,"File",&TextDrawer };
struct IntuiText TextFileName = {1,0,JAM2,0,0,NULL,NULL,NULL };

USHORT SubLinesCancel[] = { 0,0,55,0,55,10,0,10,0,0 };
USHORT LinesMyUp[] = { 0,0,19,0,19,14,0,14,0,0 };
USHORT LinesDrawer[] = { 0,0,281,0,281,10,0,10,0,0 };
USHORT LinesMyCursorUp[] = { 6,12,13,12,13,7,16,7,10,2,9,2,3,7,6,7,6,12 };
USHORT LinesMyCursorDown[] = { 6,2,13,2,13,7,16,7,10,12,9,12,3,7,6,7,6,2 };

struct Border BorderMyCancel = { 0,0,1,3,JAM1,5,SubLinesCancel,NULL };
struct Border BorderMyCursorUp = { 0,0,1,3,JAM1,9,LinesMyCursorUp,NULL };
struct Border BorderMyCursorDown = { 0,0,1,3,JAM1,9,LinesMyCursorDown,NULL };
struct Border BorderMyUp = { 0,0,1,3,JAM1,5,LinesMyUp,&BorderMyCursorUp };
struct Border BorderMyDown = { 0,0,1,3,JAM1,5,LinesMyUp,&BorderMyCursorDown };
struct Border BorderDrawer = { -58,-2,1,3,JAM1,5,LinesDrawer,NULL };

char BufferDrawer[108]="df0:";
char BufferFileName[108]="";

struct PropInfo MyPropInfo;
struct Image MyPropImage;
struct StringInfo DrawerInfo = { BufferDrawer,0,0,40,0,0,0,0,10,27,0,0,0};
struct StringInfo FileNameInfo = { BufferFileName,0,0,40,0,0,0,0,10,27,0,0,0};

#define LOAD 1
struct Gadget GGSubLoad = { NULL,80,136,56,11,GADGHCOMP,GADGIMMEDIATE|RELVERIFY,
                         BOOLGADGET,&BorderMyCancel,0,&SubTextLoad,0,0,LOAD,0};
#define CANCEL 2
struct Gadget GGSubCancel = { &GGSubLoad,164,136,56,11,GADGHCOMP,GADGIMMEDIATE|RELVERIFY,
                         BOOLGADGET,&BorderMyCancel,0,&SubTextCancel,0,0,CANCEL,0};
#define UP 3
struct Gadget GGSubUp = { &GGSubCancel,270,3,20,15,GADGHCOMP,GADGIMMEDIATE|RELVERIFY,
                         BOOLGADGET,&BorderMyUp,0,NULL,0,0,UP,0};
#define DOWN 4
struct Gadget GGSubDown = { &GGSubUp,270,79,20,15,GADGHCOMP,GADGIMMEDIATE|RELVERIFY,
                         BOOLGADGET,&BorderMyDown,0,NULL,0,0,DOWN,0};
#define DF0 5
struct Gadget GGdf0 = { &GGSubDown,40,123,56,11,GADGHCOMP,GADGIMMEDIATE|RELVERIFY,
                         BOOLGADGET,&BorderMyCancel,0,&TextDf0,0,0,DF0,0};
#define DF1 6
struct Gadget GGdf1 = { &GGdf0,122,123,56,11,GADGHCOMP,GADGIMMEDIATE|RELVERIFY,
                         BOOLGADGET,&BorderMyCancel,0,&TextDf1,0,0,DF1,0};
#define HD0 7
struct Gadget GGhd0 = { &GGdf1,204,123,56,11,GADGHCOMP,GADGIMMEDIATE|RELVERIFY,
                         BOOLGADGET,&BorderMyCancel,0,&TextHd0,0,0,HD0,0};
#define MYPROP 8
struct Gadget GGMyProp = { &GGhd0,270,20,20,57,GADGHCOMP,
                           RELVERIFY|GADGIMMEDIATE,PROPGADGET,
                           &MyPropImage,0,NULL,0,&MyPropInfo,MYPROP,0};
#define DRAWER 9
struct Gadget GGDrawer = { &GGMyProp,66,98,220,10,GADGHCOMP,
                             RELVERIFY|STRINGCENTER,STRGADGET,
                             &BorderDrawer,0,NULL,0,&DrawerInfo,DRAWER,0};
#define FILENAME 10
struct Gadget GGFileName = { &GGDrawer,66,111,220,10,GADGHCOMP,
                             RELVERIFY|STRINGCENTER,STRGADGET,
                             &BorderDrawer,0,NULL,0,&FileNameInfo,FILENAME,0};
#define FILESELECT 11
struct Gadget GGFileSelect[9];

#define A_DIRECTORY 1
#define NOT_A_DIRECTORY 0
#define PARENTDIR -1

struct MemHeader MyMemHeader;
struct MemChunk *MyMemChunk;
APTR MyBlock;
struct Name { char *EntryName;
              BOOL dir;
              struct Name *NextOne; };


extern struct FileInfoBlock *FileInfoBlock;
struct RastPort *SpecialRastPort;
struct Window *SpecialWindow;
SHORT Number_of_Files;
struct Name *MyFindName();
char StringName[108];
char CurrentDirectory[108]="df0:";
UBYTE Depth=0;
char parentdir[] = "parent";
BOOL GetFileName();
ULONG MyLock;

BOOL GetFileName(FileName,Mode)

 char *FileName,*Mode;

{
 struct Gadget *TempGadget;
 UBYTE Count;
 struct IntuiMessage *SpecialMessage;
 ULONG Class,ID,StringLength;
 struct Gadget *WhatGadget;
 struct Name *FirstName,*CurrentName=0,*NextName;
 SHORT Position=0,OldPosition=0;
 BOOL End=TRUE,GetNext;

 SubTextLoad.IText=Mode;
 if(!(MyBlock=AllocMem(8000,MEMF_PUBLIC|MEMF_CLEAR)))
    {
     DisplayRequest("Not enough ram to allocate list!");
     return(FALSE);
    }
 MyMemHeader.mh_Lower=MyBlock;
 MyMemHeader.mh_First=MyBlock;
 MyMemHeader.mh_Upper=MyBlock+8000;
 MyMemHeader.mh_Free=8000-sizeof(struct MemChunk);

 MyMemChunk=MyBlock;
 MyMemChunk->mc_Next=0;
 MyMemChunk->mc_Bytes=MyMemHeader.mh_Free;

 TempGadget=&GGFileName;
 for (Count=0;Count<9;Count++)
      {
       GGFileSelect[Count].NextGadget=TempGadget;
       GGFileSelect[Count].GadgetType=BOOLGADGET;
       GGFileSelect[Count].Activation=RELVERIFY;
       GGFileSelect[Count].Flags=GADGHNONE;
       GGFileSelect[Count].Width=256;
       GGFileSelect[Count].Height=10;
       GGFileSelect[Count].LeftEdge=10;
       GGFileSelect[Count].TopEdge=3+Count*10;
       GGFileSelect[Count].GadgetID=FILESELECT+Count;
       TempGadget=&GGFileSelect[Count];
      }
 MyPropInfo.Flags=FREEVERT|AUTOKNOB;
 MyPropInfo.VertPot=0;
 MyPropInfo.VertBody=65535;

 NewSpecialWindow.FirstGadget=&GGFileSelect[8];
 if (!(SpecialWindow=OpenWindow(&NewSpecialWindow))) return(FALSE);
 SpecialRastPort=SpecialWindow->RPort;
 PrintIText(SpecialRastPort,&TextFile,0,0);
 Position=0;
 while (GetMsg(SpecialWindow->UserPort));

 FOREVER
  {
   if (!(MyLock=Lock(CurrentDirectory)))
       {
        strcpy(CurrentDirectory,"df0:");
        strcpy(BufferDrawer,CurrentDirectory);
        OnlyRefresh(&GGDrawer,SpecialWindow);
        Depth=0;
       }
   if (MyLock) UnLock(MyLock);
   MyPropInfo.Flags=FREEVERT|AUTOKNOB;
   MyPropInfo.VertPot=0;
   MyPropInfo.VertBody=65535;
   OnlyRefresh(&GGMyProp,SpecialWindow);
   ClearDisplay();
   MyLock=Lock(CurrentDirectory);
   Examine(MyLock,FileInfoBlock);
   Number_of_Files=0;
   FirstName=NextName=Allocate(&MyMemHeader,sizeof(struct Name));
   if (Depth)
       {
        NextName->EntryName=Allocate(&MyMemHeader,strlen(parentdir));
        strcpy(NextName->EntryName,parentdir);
        NextName->dir=PARENTDIR;
        NextName->NextOne=Allocate(&MyMemHeader,sizeof(struct Name));
        Number_of_Files++;
        NextName=NextName->NextOne;
       }
   GetNext=TRUE;
   End=TRUE;
   while (End)
    {
     if (GetNext)
         {
          if (GetNext=ExNext(MyLock,FileInfoBlock))
              {
               Number_of_Files++;
               StringLength=strlen(FileInfoBlock->fib_FileName);
               NextName->EntryName=Allocate(&MyMemHeader,StringLength);
               strcpy(NextName->EntryName,FileInfoBlock->fib_FileName);
               if (FileInfoBlock->fib_EntryType>0) NextName->dir=A_DIRECTORY;
               else NextName->dir=NOT_A_DIRECTORY;
               NextName->NextOne=Allocate(&MyMemHeader,sizeof(struct Name));
               NextName=NextName->NextOne;
              }
         }
     else WaitPort(SpecialWindow->UserPort);
     NextName->EntryName=0;
     NextName->NextOne=0;
     if (Number_of_Files < 10) DisplayFiles(Position,FirstName);
     if ((Number_of_Files % 10)==0)
         {
          MyPropInfo.VertBody=65535/(Number_of_Files/9+1);
          OnlyRefresh(&GGMyProp,SpecialWindow);
         }
     if (SpecialMessage=GetMsg(SpecialWindow->UserPort))
      {
       Class=SpecialMessage->Class;
       ID=SpecialMessage->IAddress->GadgetID;
       switch(Class)
        {
         case DISKINSERTED:
         Position=0;
         Depth=0;
         strcpy(CurrentDirectory,"df0:");
         strcpy(BufferDrawer,CurrentDirectory);
         OnlyRefresh(&GGDrawer,SpecialWindow);
         FreeList(FirstName);
         End=FALSE;
         strcpy(BufferFileName," ");
         OnlyRefresh(&GGFileName,SpecialWindow);
         break;
         case GADGETDOWN:
         switch(ID)
          {
           case DOWN:
           do {
           if ((Position==Number_of_Files-9) || (Number_of_Files<10)) break;
           Position += 1;
           DisplayFiles(Position,FirstName);
           } while(!(64 & *((UBYTE *)0xbfe001)));
           break;
           case UP:
           do {
           if (!Position) break;
           Position -= 1;
           DisplayFiles(Position,FirstName);
           } while(!(64 & *((UBYTE *)0xbfe001)));
           break;
           case MYPROP:
           do {
           Position=MyPropInfo.VertPot*(Number_of_Files-9)/65535;
           if (Position+8>Number_of_Files) Position=Number_of_Files-9;
           if (Position<0) Position=0;
           if (OldPosition!=Position) DisplayFiles(Position,FirstName);
           OldPosition=Position;
           } while(!(64 & *((UBYTE *)0xbfe001)));
           break;
          }
         break;
         case GADGETUP:
         switch(ID)
          {
           case DRAWER:
           if (!(MyLock=Lock(BufferDrawer,FileInfoBlock)))
               {
                DisplayRequest("This drawer does not exist!");
                strcpy(BufferDrawer,CurrentDirectory);
                OnlyRefresh(&GGDrawer,SpecialWindow);
                break;
               }
           if (MyLock) UnLock(MyLock);
           strcpy(CurrentDirectory,BufferDrawer);
           if (strlen(BufferDrawer)==0 || strlen(BufferDrawer)==4)
               Depth=0;
           else {
                Depth=1;
                Count=0;
                while(BufferDrawer[Count]!=0)
                      {
                       if (BufferDrawer[Count]=='/') Depth++;
                       Count++;
                      }
               }
           FreeList(FirstName);
           End=FALSE;
           break;
           case LOAD:
           strcpy(FileName,CurrentDirectory);
           if (Depth) strcat(FileName,"/");
           strcat(FileName,BufferFileName);
           FreeMem(MyBlock,8000);
           CloseWindow(SpecialWindow);
           DisplayFreeMem();
           return(TRUE);
           break;
           case CANCEL:
           FreeMem(MyBlock,8000);
           CloseWindow(SpecialWindow);
           DisplayFreeMem();
           return(FALSE);
           break;
           case DF0:
           Position=0;
           Depth=0;
           strcpy(CurrentDirectory,"df0:");
           strcpy(BufferDrawer,CurrentDirectory);
           OnlyRefresh(&GGDrawer,SpecialWindow);
           FreeList(FirstName);
           End=FALSE;
           strcpy(BufferFileName," ");
           OnlyRefresh(&GGFileName,SpecialWindow);
           break;
           case DF1:
           Position=0;
           Depth=0;
           strcpy(CurrentDirectory,"df1:");
           strcpy(BufferDrawer,CurrentDirectory);
           OnlyRefresh(&GGDrawer,SpecialWindow);
           FreeList(FirstName);
           End=FALSE;
           strcpy(BufferFileName," ");
           OnlyRefresh(&GGFileName,SpecialWindow);
           break;
           case HD0:
           Position=0;
           Depth=0;
           strcpy(CurrentDirectory,"dh0:");
           strcpy(BufferDrawer,CurrentDirectory);
           OnlyRefresh(&GGDrawer,SpecialWindow);
           FreeList(FirstName);
           End=FALSE;
           strcpy(BufferFileName," ");
           OnlyRefresh(&GGFileName,SpecialWindow);
           break;
          }
         if ((ID>=FILESELECT) && (ID<=FILESELECT+8))
             {
              if ((ID-FILESELECT+Position)>=Number_of_Files) break;
              CurrentName=MyFindName(Position,ID-FILESELECT,FirstName);
              if (CurrentName->dir==A_DIRECTORY)
                  {
                   Position=0;
                   if (Depth) strcat(CurrentDirectory,"/");
                   Depth++;
                   strcat(CurrentDirectory,CurrentName->EntryName);
                   strcpy(BufferDrawer,CurrentDirectory);
                   OnlyRefresh(&GGDrawer,SpecialWindow);
                   FreeList(FirstName);
                   End=FALSE;
                   break;
                  }
              if (CurrentName->dir==PARENTDIR)
                  {
                   Count=strlen(CurrentDirectory)-1;
                   if (Depth>1)
                       {
                        while (CurrentDirectory[Count] != '/')
                               {
                                CurrentDirectory[Count]=0;
                                Count--;
                               }
                        CurrentDirectory[Count]=0;
                       }
                   else
                       {
                        while ((CurrentDirectory[Count] != ':') || (Count==0))
                               {
                                CurrentDirectory[Count]=0;
                                Count--;
                               }
                       }
                   Depth--;
                   Position=0;
                   strcpy(BufferDrawer,CurrentDirectory);
                   OnlyRefresh(&GGDrawer,SpecialWindow);
                   FreeList(FirstName);
                   End=FALSE;
                   break;
                  }
              strcpy(BufferFileName,CurrentName->EntryName);
              OnlyRefresh(&GGFileName,SpecialWindow);
              break;
             }
        break;
       }
    }
  }
 }
}

struct Name *MyFindName(Position,Offset,FirstName)

 struct Name *FirstName;
 SHORT Position,Offset;

{
 struct Name *CurrentName;
 SHORT i;

 CurrentName=FirstName;

 for (i=0;i<Position;i++) CurrentName=CurrentName->NextOne;
 for (i=Position;i<Position+Offset;i++) CurrentName=CurrentName->NextOne;
 return(CurrentName);
}

DisplayFiles(Position,FirstName)

 struct Name *FirstName;
 SHORT Position;

{
 BOOL End=FALSE;
 SHORT i=0;
 struct Name *CurrentName;

 CurrentName=FirstName;
 while (i<Position)
        {
         if (!CurrentName->EntryName)
             {
              Position=i;
              break;
             }
         CurrentName=CurrentName->NextOne;
         i++;
        }

 SetDrMd(SpecialRastPort,JAM2);
 for (i=0;i<=8;i++)
      {
       SetAPen(SpecialRastPort,0);
       if (CurrentName->NextOne)
           {
            strcpy(StringName,CurrentName->EntryName);
            if (CurrentName->dir) strcat(StringName," (dir)");
            TextFileName.IText=StringName;
            PrintIText(SpecialRastPort,&TextFileName,10,2+i*10+2);
            RectFill(SpecialRastPort,10+strlen(StringName)*8,2+i*10,256,2+i*10+9);
            CurrentName=CurrentName->NextOne;
           }
      }
}

ClearDisplay()
{
 SetDrMd(SpecialRastPort,JAM2);
 SetAPen(SpecialRastPort,0);
 RectFill(SpecialRastPort,10,3,256,92);
}

FreeList(FirstName)

 struct Name *FirstName;

{
 struct Name *NextOne;

 do {
     if (FirstName->EntryName)
         Deallocate(&MyMemHeader,FirstName->EntryName,strlen(FirstName->EntryName));
     NextOne=FirstName->NextOne;
     Deallocate(&MyMemHeader,FirstName,sizeof(struct Name));
     FirstName=NextOne;
    } while (NextOne);
}

OnlyRefresh(MyGadget,WhatWindow)

 struct Gadget *MyGadget;
 struct Window *WhatWindow;

{
 struct Gadget *TempGadget2;

 TempGadget2=MyGadget->NextGadget;
 MyGadget->NextGadget=0;
 RefreshGadgets(MyGadget,WhatWindow,0);
 MyGadget->NextGadget=TempGadget2;
}


