#include "filedoor_structs_defines.h"
#include "filedoor_protos.h"
#include <strings.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <proto/exec.h>
#include <proto/dos.h>

struct RawDir {
  char name[40];
  ULONG siz;
  BOOL dir;
};

struct RawDir __far rawdir[500];
int rawdirentries;
char __far rawpath[200];
int topraw;
int cursorraw;

/* Sammenlign to directory entries til brug for sortering */
CompareRawFiles(struct RawDir *a,struct RawDir *b)
{
  if(a->dir==b->dir)
  /* Hvis begge er dir eller begge er fil, sorter alfabetisk */
  {
    return(stricmp(a->name,b->name));
  }
  else
  /* Hvis ene er dir og anden fil, kommer dir først */
  {
    if(a->dir) return(-1); else return(1);
  }
}

/* Hent og sorter et directory */
int GetRawDir(char *path)
{
struct FileInfoBlock *fib;
BPTR dirlock;

  topraw=0;
  cursorraw=0;
  rawdirentries=0;
  if(fib=AllocDosObject(DOS_FIB,NULL))
  {
    if(dirlock=Lock(path,ACCESS_READ))
    {
      if(Examine(dirlock,fib))
      {
        while(ExNext(dirlock,fib))
        {
          strcpy(rawdir[rawdirentries].name,fib->fib_FileName);
          rawdir[rawdirentries].siz=fib->fib_Size;
          if(fib->fib_DirEntryType>0)
          {
            rawdir[rawdirentries].dir=TRUE;
          }
          else
          {
            rawdir[rawdirentries].dir=FALSE;
          }
          rawdirentries++;
        }
      }
      UnLock(dirlock);
    }
    FreeDosObject(DOS_FIB,fib);
  }
  if(rawdirentries>1)
  {
    qsort(rawdir,rawdirentries,sizeof(struct RawDir),CompareRawFiles);
  }
  return(rawdirentries);
}

/* Vis rå filer menuen */
void RawMenu(BOOL refreshmenu,BOOL refreshfiles)
{
char text[80];
int i;

  if(refreshmenu)
  {
    ClearMenuWindow("Raw download");
    msg("\n");
    msg(RI KNAP"<RETURN>"MENU" Enter dir/download\n");
    msg(RI KNAP"     (Q)"MENU" Quit back to filememu\n");
    msg(RI KNAP"     (P)"MENU" Parent directory\n");
    msg(RI KNAP"     (R)"MENU" Read ASCII file\n");
  }
  if(refreshfiles)
  {
    ClearBottomWindow();
    if(topraw)
    {
      msgc("(MORE FILES ABOVE)",FG1,FG7);
    }
    else
    {
      msgc("",FG1,FG7);
    }
    msg("\n");
    for(i=topraw;i<topraw+visiblelines && i<rawdirentries;i++)
    {
      if(rawdir[i].dir)
      {
        sprintf(text,RI FG7" %-40.40s    (DIR)\n",rawdir[i].name);
      }
      else
      {
        sprintf(text,RI FG7" %-40.40s %7i\n",rawdir[i].name,rawdir[i].siz);
      }
      msg(text);
    }
    MoveCrsr(1,TOPLINE+visiblelines);
    if(topraw+visiblelines<rawdirentries)
    {
      msgc("(MORE FILES BELOW)",FG1,FG7);
    }
    else
    {
      msgc("",FG1,FG7);
    }
  }
}

/* Klip en streng af, sådan at sidste dir i pathen forsvinder incl. "/" */
/* Fx: "c:dir/" -> "c:"                                                 */
/*     "c:" -> "c:"                                                     */
/*     "c:dir/dir" -> "c:dir"                                           */
/* Funker ikke ordentligt på relative stier                             */
void CropToParent(char *path)
{
int i;

  i=strlen(path)-1;
  if(path[i]=='/') path[i]=0;
  while(path[i]!='/' && i>0) i--;
  if(i>0)
  {
    path[i]=0;
  }
  else
  {
    while(path[i]!=':' && path[i]!=0) i++;
    if(path[i]==':') path[i+1]=0;
  }
}


/* Lad bruger bevæge sig rundt i og lave rå download fra et dir */
void RawAccess(char *path)
{
char key;
char keys[10];
BOOL refmenu=TRUE;
BOOL reffile=TRUE;
BOOL done=FALSE;
static __far char file[200];
static __far char archive[80];
static __far char tempstr[250];
char *StrPtr;

  strcpy(rawpath,path);
  if(GetRawDir(rawpath))
  {
    while(!done)
    {
      RawMenu(refmenu,reffile);
      refmenu=reffile=FALSE;
      PutCursor(cursorraw-topraw);
      hotkey("",keys);
      key=keys[0];
      if(hetwittedus) break;
      if(key=='\x1b')
      {
        hotkey("",keys);
        if(keys[0]=='[')
        hotkey("",keys);
        while(keys[0]>='0' && keys[0]<='9')
        {
          hotkey("",keys);
          if(hetwittedus) break;
        }
        key=keys[0];
      }
      ZapCursor(cursorraw-topraw);
      switch(key)
      {
        /* Quit */
        case 'Q':
        case 'q':
        done=TRUE;
        break;

        /* Crsr op */
        case 'A':
        case '8':
        if(cursorraw==topraw)
        {
          if(topraw)
          {
            topraw-=visiblelines;
            cursorraw=topraw+visiblelines-1;
            reffile=TRUE;
          }
        }
        else
        {
          cursorraw-=1;
        }
        break;

        /* Crsr ned */
        case 'B':
        case '2':
        if(cursorraw==topraw+visiblelines-1)
        {
          if(topraw+visiblelines<rawdirentries)
          {
            topraw+=visiblelines;
            cursorraw=topraw;
            reffile=TRUE;
          }
        }
        else
        {
          if(cursorraw!=rawdirentries-1)
          {
            cursorraw+=1;
          }
        }
        break;

        /* return - download */
        case '\xd':
        if(rawdir[cursorraw].dir)
        {
          AddPart(rawpath,rawdir[cursorraw].name,200);
          if(GetRawDir(rawpath))
          {
            reffile=refmenu=TRUE;
          }
          else
          {
            CropToParent(rawpath);
            GetRawDir(rawpath);
            reffile=refmenu=TRUE;
          }
        }
        else
        {
          ClearMenuWindow("Raw download");
          msg("\n"RI KNAP"(d)"MENU" Download or "KNAP"(A)"MENU" Abort");
          hotkey("",keys);
          if(toupper(keys[0])=='D')
          {
            msg("\xc"FG1"Making archive and downloading..\n");
            strcpy(file,rawpath);
            AddPart(file,rawdir[cursorraw].name,200);
            strcpy(archive,"cydaltemp:");
            strcat(archive,rawdir[cursorraw].name);
            strcat(archive,".lha");
            DeleteFile(archive);
            sprintf(tempstr,"lha a %s %s",archive,file);
            Execute(tempstr,NULL,NULL);
            StrPtr=&archive[0];
            DoXprDl(1,&StrPtr);
            DeleteFile(archive);
          }
          reffile=refmenu=TRUE;
        }
        break;

        /* r - read ASCII */
        case 'R':
        case 'r':
        if(!rawdir[cursorraw].dir)
        {
          strcpy(file,rawpath);
          AddPart(file,rawdir[cursorraw].name,200);
          msg("\xc");
          CopyFile(file,"cydaltemp:tempascii");
          showfile("cydaltemp:tempascii");
          AnyKey();
          msg("\xc");
          reffile=refmenu=TRUE;
        }
        break;

        /* parent */
        case 'P':
        case 'p':
        CropToParent(rawpath);
        GetRawDir(rawpath);
        reffile=refmenu=TRUE;
        break;

        /* Refresh */
        case ' ':
        reffile=refmenu=TRUE;
        break;

        /* hvorfor spilder jeg tiden med disse? ingen ved det.. */
        default:
        break;
      }
    }
  }
}

/* Kaldes med navnet på et arkiv - lader bruger DL fra indeni arkivet */
void Archive(char *file)
{
static char ending[10];
static char cmdline[200];
static char devicename[40];

  strcpy(ending,file+strlen(file)-4);
  if(!stricmp(".dms",ending))
  {
    msg("Decompressing DMS archive. Wait a few secs..\n");
    sprintf(cmdline,"dms write %s to ff%c: noverify",file,line_number);
    Execute(cmdline,NULL,NULL);
    sprintf(devicename,"ff%c:",line_number);
    RawAccess(devicename);
  }
  if(!stricmp(".lzh",ending) || !stricmp(".lha",ending))
  {
    msg("Preparing LHA archive. Wait a few secs..\n");
    sprintf(cmdline,"mountarchive %s",file);
    Execute(cmdline,NULL,NULL);
    strcpy(devicename,FilePart(file));
    strcpy(devicename+strlen(devicename)-4,":"); /* Replace ".lha" ending with ":" */
    RawAccess(devicename);
    sprintf(cmdline,"unmount %s",devicename);
    Execute(cmdline,NULL,NULL);
  }
}
