
/* Local.c By Kamran Karimi 
   Part of EasyAmiga source.
*/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include <time.h>
#include <dos.h>

#include <clib/dos_protos.h>

#include "ErrCodes.h"

#define FIBB_HIDDEN    7
#define FIBF_HIDDEN    (1 << FIBB_HIDDEN)

extern long NumDone;
extern USHORT FileNum[2];
extern struct FInfo *First[2];


struct FInfo  {
 struct FInfo *next,*prev;
 byte Selected,type;
 char name[32];
 char data[MAXAMINFOLEN + 10];
};


VOID GetAMInfo(struct FileInfoBlock *info, struct FInfo *finfo)
{
 long ft,len;
 char tstr[26],month[4];

 strncpy(finfo->name,info->fib_FileName,31);
 finfo->name[31] = NULL;
 if(info->fib_DirEntryType > 0) finfo->type = DIRTYPE;
 else finfo->type = FILETYPE;
 if(finfo->type == FILETYPE)
  sprintf(finfo->data,"%8lu %-31.31s ",info->fib_Size, info->fib_FileName);
 else
  sprintf(finfo->data,"         %-31.31s ",info->fib_FileName);
 if(info->fib_Protection & FIBF_HIDDEN) strcat(finfo->data,"H");
 else strcat(finfo->data,"-");
 if(info->fib_Protection & FIBF_SCRIPT) strcat(finfo->data,"S");
 else strcat(finfo->data,"-");
 if(info->fib_Protection & FIBF_PURE) strcat(finfo->data,"P");
 else strcat(finfo->data,"-");
 if(info->fib_Protection & FIBF_ARCHIVE) strcat(finfo->data,"A");
 else strcat(finfo->data,"-");
 if(!(info->fib_Protection & FIBF_READ)) strcat(finfo->data,"R");
 else strcat(finfo->data,"-");
 if(!(info->fib_Protection & FIBF_WRITE)) strcat(finfo->data,"W");
 else strcat(finfo->data,"-");
 if(!(info->fib_Protection & FIBF_EXECUTE)) strcat(finfo->data,"E");
 else strcat(finfo->data,"-");
 if(!(info->fib_Protection & FIBF_DELETE)) strcat(finfo->data,"D ");
 else strcat(finfo->data,"- ");

 ft = getft(info->fib_FileName);
 if(ft == -1) strcat(finfo->data,"No Date Available ");
 else
 {
  strcpy(tstr,ctime(&ft));
  len = strlen(finfo->data);
  strncat(finfo->data,&tstr[8],2);
  finfo->data[len + 2] = NULL;
  strncpy(month,&tstr[4],3);
  month[3] = NULL;
       if(!strcmp(month,"Jan")) strcat(finfo->data,"/01/");
  else if(!strcmp(month,"Feb")) strcat(finfo->data,"/02/");
  else if(!strcmp(month,"Mar")) strcat(finfo->data,"/03/");
  else if(!strcmp(month,"Apr")) strcat(finfo->data,"/04/");
  else if(!strcmp(month,"May")) strcat(finfo->data,"/05/");
  else if(!strcmp(month,"Jun")) strcat(finfo->data,"/06/");
  else if(!strcmp(month,"Jul")) strcat(finfo->data,"/07/");
  else if(!strcmp(month,"Aug")) strcat(finfo->data,"/08/");
  else if(!strcmp(month,"Sep")) strcat(finfo->data,"/09/");
  else if(!strcmp(month,"Oct")) strcat(finfo->data,"/10/");
  else if(!strcmp(month,"Nov")) strcat(finfo->data,"/11/");
  else if(!strcmp(month,"Dec")) strcat(finfo->data,"/12/");
  strcat(finfo->data,&tstr[20]);
  finfo->data[strlen(finfo->data) - 1] = ' ';
  strcat(finfo->data,&tstr[11]);
  finfo->data[strlen(finfo->data) - 5] = NULL;
 }
}


VOID AddToList(struct FInfo *finfo,int list)
{
 struct FInfo *tempinfo,*PrevLast = NULL;
 
 tempinfo = First[list];
 while(tempinfo)
 {
  if(tempinfo->next == NULL) PrevLast = tempinfo;
  if(stricmp(finfo->name,tempinfo->name) <= 0) /* first below second */
  { 
   if( (finfo->type == DIRTYPE) && (tempinfo->type == FILETYPE) )
    tempinfo = tempinfo->next;
   else
   {
    finfo->next = tempinfo;
    finfo->prev = tempinfo->prev;
    if(tempinfo->prev) (tempinfo->prev)->next = finfo;
    tempinfo->prev = finfo;
    finfo->Selected = FALSE;
    if(First[list] == tempinfo) First[list] = finfo;
    break;
   }
  }
  else if( (finfo->type == FILETYPE) && (tempinfo->type == DIRTYPE))
  {
   finfo->next = tempinfo;
   finfo->prev = tempinfo->prev;
   if(tempinfo->prev) (tempinfo->prev)->next = finfo;
   tempinfo->prev = finfo;
   finfo->Selected = FALSE;
   if(First[list] == tempinfo) First[list] = finfo;
   break;
  }
  else tempinfo = tempinfo->next;
 }
 if(!tempinfo) /* add to end of list */
 {
  if(PrevLast)
  {
   finfo->next = NULL;
   finfo->prev = PrevLast;
   PrevLast->next = finfo;
   finfo->Selected = FALSE;
  }
  else /* nothing on list */
  {
   finfo->next = NULL;
   finfo->prev = NULL;
   finfo->Selected = FALSE;
   First[list] = finfo;
  }
 }
}


LONG LocalDir(VOID)
{ 
 __aligned
 struct FileInfoBlock info;
 struct FInfo *finfo;

 NumDone = 0;
 if(dfind(&info,"#?",1)) return NO_ERROR;
 finfo = malloc(sizeof(struct FInfo));
 if(!finfo) return ERROR_NOMEM;
 GetAMInfo(&info,finfo);
 AddToList(finfo,AM);
 FileNum[AM] = 1;
 while(!dnext(&info))
 {
  finfo = malloc(sizeof(struct FInfo));
  if(!finfo) return ERROR_NOMEM;
  GetAMInfo(&info,finfo);
  AddToList(finfo,AM);
  FileNum[AM]++;
 }
 NumDone = 1;
 return NO_ERROR;
}


LONG LocalDel(VOID)
{
 struct FInfo *tmp;

 NumDone = 0;
 for(tmp = First[AM]; tmp; tmp = tmp->next)
 {
  if(tmp->Selected)
  {
   if(tmp->type == FILETYPE) 
   { if(remove(tmp->name)) return ERROR_LocFDelete; }
   else
   { if(rmdir(tmp->name)) return ERROR_LocDDelete; }
   NumDone++;
  } 
 }
 return NO_ERROR;
}

LONG LocalMKDir(char *Name)
{
 NumDone = 0;
 if(mkdir(Name)) return ERROR_LocMKDir;
 NumDone = 1;
 return NO_ERROR;
}

#define BUFFLEN 255 /* from ser.h */

LONG LocalCd(char *Path)
{
 NumDone = 0;
 if(chdir(Path))
 {
  getcwd(Path,BUFFLEN);
  return ERROR_LocCHDir;
 }
 getcwd(Path,BUFFLEN);
 NumDone = 1;
 return NO_ERROR;
}
