import java.util.*;
import java.io.*;

/* This class keeps track of all files currently open.
 *A byte array called bitmap tells whether the specified index has a file open.
 *A fileDescriptor array fdArray contains FD objects.
 *Each FD object is an instance of the class FileDescriptor that maintains
 *information about the specified file.
 */
class FileTable 
{
  public static final int MAX_FILES = 21; 
  public int bitmap[];
  public FileDescriptor[] fdArray;
    
  public FileTable()
  {
    fdArray = new FileDescriptor[MAX_FILES];
    bitmap = new int[MAX_FILES];
    for(int i=0; i < MAX_FILES; i++)
      bitmap[i] = 0;
  }
    
  public int allocate()                 //returns the index in the file table
  {
    for(int i=0; i < MAX_FILES; i++)
      if(bitmap[i] == 0)
        return i;
    System.out.println("Cannot open file... filetable is full.");
    return -1; //filetable is full already.
  }
    
  public int add(Inode inode, int inumber, int fd)
  {
    if(bitmap[fd] != 0)
      return -1;
    bitmap[fd] = 1;
    fdArray[fd] = new FileDescriptor(inode, inumber);
    return 0;  
  }
    

  public void free(int fd)
  {
    bitmap[fd] = 0;
  }

  public boolean isValid(int fd)       //returns true if it is valid
  {
    if (fd < 0 || fd >= MAX_FILES) 
    {
      System.out.println("ERROR: Invalid file descriptor " + fd);
      return false;
    }
    else if (bitmap[fd] > 0)
      return true;
    else
      return false;
  }

  public Inode getInode(int fd)
  {
    if (bitmap[fd] == 0) return null;
    return fdArray[fd].inode;
  }

  public int getInumber(int fd)
  {
    if (bitmap[fd] == 0) return 0;        //ERROR, if invalid
    return fdArray[fd].inumber;
  }

  public int getSeekPointer(int fd)
  {
    if (bitmap[fd] == 0) return 0;        //invalid
    return fdArray[fd].seekPtr;
  }

  public int setSeekPointer(int fd, int newPointer) 
  {
    if (bitmap[fd] == 0) return 0;        //invalid
    fdArray[fd].seekPtr = newPointer;
    return 1;  
  }

  public int setFileSize(int fd, int newFileSize)
  {
    if (bitmap[fd] == 0) return 0;       //invalid
    fdArray[fd].setFileSize(newFileSize);
    return 1;
  }  

  public int getFDfromInumber(int inumber)
  {       
    for (int i=0; i < MAX_FILES; i++)
      if(bitmap[i] == 1)
	if (fdArray[i].inumber == inumber)
		    return i;
    return -1;
  }

  public String toString()
  {
    String s = "";
    for (int i=0; i<MAX_FILES; i++)      // loop over all file descriptors
      if (bitmap[i] != 0)
        s += fdArray[i].toString();
    return(s);
  }
}


