//CSU 480 File System Project
//2/17/06
//Ken Eimer, Brandon Schory, Brian Tobia
//filesystem.h

#ifndef _FILE_SYSTEM_
#define _FILE_SYSTEM_

#include "disk.h"

#define MAXNAMELEN  5
#define MAXNUMFILES 20

// Entry stores one filename and its index block number

typedef struct TmpEntry {
  char filename[MAXNAMELEN+1];
  int  indexBlockNumber;
} Entry;

// DirectoryBlock is the data structure enforced on a loaded directory block.
// In other words, if we read a directory block to a char[], we can cast from char[] to DirectoryBlock*
// and access its data.

typedef struct TmpDirectoryBlock {
  int nextBlockNumber;
  int numEntriesInBlock;
  Entry entriesInBlock[1];
} DirectoryBlock;

/*
FileIndex is the data structure enforced on a loaded file's index block. In other words, if we read a loaded file's index block to a char[], we can cast from char[] to FileIndex* and access it's data.
*/

typedef struct TmpFileIndex {
  int fileSize;
  int blocks[1];
} FileIndex;



// class FileSystem manages the file system.
// Assume the directory is managed by a single-linked list of blocks, starting at block 0.
// Every block, as a char*, has the following structure:
//   - first four bytes stores the block number of the next block in the list.  Use -1 to represent null.
//   - next four bytes stores the number of entries stored in this block.
//   - next sizeof(Entry) bytes stores the first entry in this block.
//   - next sizeof(Entry) bytes stores the second entry in this block, and so on.
// Besides the directory blocks, there are two types of blocks: index block and data block.
//  - index block: for every file, the block that contains pointers to data blocks.
//  - data block: the disk blocks that actually store data.

class FileSystem {
  Disk* disk;
  int blocksize;
  Entry entries[MAXNUMFILES];
  int numentries;

  //The maximum number of data blocks that can be allocated per file
  int maxfileblocks;

  //Tells whether any file is open
  //  - True: there is one open
  //  - False: there are no files open 
  bool openFile;

  //The data block of the open file that is currently being edited
  int editBlock;

  //The offset (in bytes) form the beginning of the block referenced by editBlock
  int fileOffset;

  //Stores the location of currently opened file's index block
  int fileIndexBlock;

 public:
  FileSystem( Disk* _disk, int _blocksize, bool isnew );
  ~FileSystem();

  /*
  printf( "ls: lists the existing files.\n" );
  printf( "create filename: creates a new file.\n" );
  printf( "rm filename: deletes a file.\n" );
  printf( "open filename: opens an existing file.\n" );
  printf( "seek offset: moves the file pointer to the given place.\n" );
  printf( "read numbytes: reads some bytes from the file.\n" );
  printf( "write string: writes to the file.\n" );
  printf( "size: gets the size of the file.\n" );
  printf( "close: closes the file.\n" );
  */

  void ls();
  void create( char* filename );
  void rm( char* filename );
  void open( char* filename );
  void seek( int offset );
  void read( int numbytes, char* buffer );
  void write( char* content );
  int size();
  void close();
};  

#endif
    

