/**************************************************************
 *
 * userprog/ksyscall.h
 *
 * Kernel interface for systemcalls 
 *
 * by Marcus Voelp  (c) Universitaet Karlsruhe
 *
 **************************************************************/

#ifndef __USERPROG_KSYSCALL_H__ 
#define __USERPROG_KSYSCALL_H__ 

#define INT_BUF_LENGTH 13

#include "kernel.h"

#include "synchconsole.h"


void SysHalt()
{
  kernel->interrupt->Halt();
}

int SysAdd(int op1, int op2)
{
  return op1 + op2;
}

int SysCreate(char *filename)
{
  // return value
  // 1: success
  // 0: failed
  return kernel->interrupt->CreateFile(filename);
}

void SysPrintInt(int value) {
  static char zero[2] = "0";

  if (value == 0) {
    kernel->synchConsoleOut->PutString(zero);
    return;
  }

  char outputBuf[INT_BUF_LENGTH];
  bool isNeg = false;
  int curPos = INT_BUF_LENGTH;
  outputBuf[--curPos] = '\0';
  outputBuf[--curPos] = '\n';
  
  if (value < 0) {
    isNeg = true;
    value = -value;
  }

  while (value > 0) {
    outputBuf[--curPos] = '0' + (value % 10);
    value /= 10;
  }

  if (isNeg)
    outputBuf[--curPos] = '-';

  kernel->synchConsoleOut->PutString(&outputBuf[curPos]);
}

OpenFileId SysOpen(char *name) {
  OpenFileId id = -1;
  for (int i = 0; i < 20; i++)
    if (kernel->fileSystem->fileDescriptorTable[i] == NULL) {
      id = i;
      kernel->fileSystem->fileDescriptorTable[i] 
        = kernel->fileSystem->Open(name);
      if (kernel->fileSystem->fileDescriptorTable[i] == NULL)
        return -1;
      break;
    }
  return id;
}

int SysWrite(char *buffer, int size, OpenFileId id) {
  if (id < 0 || id >= 20 || kernel->fileSystem->fileDescriptorTable[id] == NULL)
    return -1;
  return kernel->fileSystem->fileDescriptorTable[id]->Write(buffer, size);
}

int SysRead(char *buffer, int size, OpenFileId id) {
  if (id < 0 || id >= 20 || kernel->fileSystem->fileDescriptorTable[id] == NULL)
    return -1;
  return kernel->fileSystem->fileDescriptorTable[id]->Read(buffer, size);
}

int SysClose(OpenFileId id) {
  if (id < 0 || id >= 20 || kernel->fileSystem->fileDescriptorTable[id] == NULL)
    return 0;
  delete kernel->fileSystem->fileDescriptorTable[id];
  kernel->fileSystem->fileDescriptorTable[id] = NULL;
  return 1;
}


#endif /* ! __USERPROG_KSYSCALL_H__ */
