/* Original code (c) Acorn Computers Ltd, 1992-3 */

/* $Id: c._File 3.1 93/03/09 23:09:29 brian Exp $ */
/* #define DEBUG */
#include "FS.h"

_kernel_oserror *fsentry_file( FSEntry_File_Parameter *parm )
{
  _kernel_oserror *err = NULL;
  FileEntry *fse = NULL;
  FileDesc d;
#ifdef DEBUG
  printf( "File( %d )%s\n", parm->reason, parm->name );
#endif
  special_field = parm->special_field;
  switch ( parm->reason )
  {
  case FSEntry_File_Reason_LoadFile:
    err=FileEntry_Open( NULL, parm->name, OPENIN, &fse );
    if ( !err )
    { int pos=0,len;
      d = FileEntry_Desc( fse );
      while (pos<d.length)
      { err=FileEntry_GetBytes(fse,parm->info.load_exec.load_address,pos,d.length,&pos,&len);
        if (err) return err;
        if (!len) return ERR(mb_EOF);
      }
      parm->info = d.info;
      parm->extras.info.length = d.length;
      parm->extras.info.attributes = d.attr;
      parm->special_field = FileEntry_Name( fse );
      FileEntry_Close( fse );
    }
    break;
  case FSEntry_File_Reason_CreateFile:
    { int n = parm->extras.location.end-parm->extras.location.start;
      err = FileEntry_Open( NULL, parm->name, CREATE, &fse );
      if ( !err )
      { err = FileEntry_SetLength( fse, n );
        if ( !err )
        { FileEntry_SetInfo( fse, parm->info );
          parm->special_field = FileEntry_Name( fse );
          FileEntry_Close( fse );
        }
        else
        { FileEntry_Close( fse );
          FileEntry_Delete( NULL, parm->name, &d );
        }
      }
    }
    break;;
  case FSEntry_File_Reason_SaveFile:
    { int n = parm->extras.location.end-parm->extras.location.start;
      err = FileEntry_Open( NULL, parm->name, CREATE, &fse );
      if ( !err )
      { err = FileEntry_PutBytes( fse, parm->extras.location.start, 0, n, &n );
        if ( !err )
        { FileEntry_SetInfo( fse, parm->info );
          parm->special_field = FileEntry_Name( fse );
          FileEntry_Close( fse );
        }
        else
        { FileEntry_Close( fse );
          FileEntry_Delete( NULL, parm->name, &d );
        }
      }
    }
    break;
  case FSEntry_File_Reason_WriteCatalogueInformation:
#ifdef DEBUG
    printf( "WriteCatInfo:%p as %x/%x %x\n", fse, parm->info, parm->extras.info.attributes );
#endif
    err = FileEntry_Open( NULL, parm->name, OPENIN, &fse );
    if ( !err )
    { FileEntry_SetInfo( fse, parm->info );
      FileEntry_Close( fse );
    }
    if (!err)
      err = FileEntry_Access( NULL, parm->name, parm->extras.info.attributes );
    break;
  case FSEntry_File_Reason_WriteLoadAddress:
    err = FileEntry_Open( NULL, parm->name, OPENIN, &fse );
    if ( !err )
    { FileDesc d = FileEntry_Desc( fse );
      Information_Fields info = d.info;
      info.load_exec.load_address = parm->info.load_exec.load_address;
      err = FileEntry_SetInfo( fse, info );
      FileEntry_Close( fse );
    }
    break;
  case FSEntry_File_Reason_WriteExecutionAddress:
    err = FileEntry_Open( NULL, parm->name, OPENIN, &fse );
    if ( !err )
    { FileDesc d = FileEntry_Desc( fse );
      Information_Fields info = d.info;
      info.load_exec.execute_address = parm->info.load_exec.execute_address;
      err = FileEntry_SetInfo( fse, info );
      FileEntry_Close( fse );
    }
    break;

  case FSEntry_File_Reason_WriteAttributes:
    err = FileEntry_Access( NULL, parm->name, parm->extras.info.attributes );
    break;

  case FSEntry_File_Reason_ReadCatalogueInformationNoLength:
  case FSEntry_File_Reason_ReadCatalogueInformation:
    err = FileEntry_Find( NULL, parm->name, &d );
    if ( err )
    { parm->reason = 0;
#ifdef DEBUG
      printf("Find error %d %s\n",err->errnum,err->errmess);
#endif
    }
    else
    { parm->reason = d.type;
      parm->info = d.info;
      parm->extras.info.length = d.length;
      parm->extras.info.attributes = d.attr;
    }
    err = NULL;
    break;
  case FSEntry_File_Reason_DeleteObject:
    {
      err = FileEntry_Delete( NULL, parm->name, &d );
      parm->reason = d.type;
      parm->info = d.info;
      parm->extras.info.length = d.length;
      parm->extras.info.attributes = d.attr;
    }
    break;
  case FSEntry_File_Reason_CreateDirectory: 
    err = FileEntry_Open( NULL, parm->name, CREATEDIR, &fse );
    if (!err)
      FileEntry_Close( fse );
    break;
  default:
    err = ERR(mb_BadParameters);
    break;
  }
  return err;
}
