/*------------------------------------------------------------------------
  A busy flag module for SICS. 

  Mark Koennecke, July 2002
-------------------------------------------------------------------------*/
#include <stdlib.h>
#include <assert.h>
#include "fortify.h"
#include "sics.h"

/*----------------------------------------------------------------------*/
typedef struct BUSY__ {
  pObjectDescriptor pDes;
  int iBusy;
  }Busy;
/*---------------------------------------------------------------------*/
busyPtr makeBusy(void){
  busyPtr result = NULL;

  result = (busyPtr)malloc(sizeof(Busy));
  if(!result){
    return NULL;
  }
  result->pDes = CreateDescriptor("BusyFlag");
  if(!result->pDes){
    free(result);
    return NULL;
  }
  result->iBusy = 0;
  return result;
}
/*---------------------------------------------------------------------*/
void killBusy(void *self){
  busyPtr busy;
  if(self != NULL){
    busy = (busyPtr)self;
    if(busy->pDes != NULL){
      DeleteDescriptor(busy->pDes);
    }
    free(busy);
  }
}
/*---------------------------------------------------------------------*/
void incrementBusy(busyPtr self){
  assert(self != NULL);
  self->iBusy++;
}
/*--------------------------------------------------------------------*/
void decrementBusy(busyPtr self){
  assert(self != NULL);
  self->iBusy--;
  if(self->iBusy < 0){
    self->iBusy = 0;
  }
}
/*--------------------------------------------------------------------*/
void clearBusy(busyPtr self){
  assert(self != NULL);
  self->iBusy = 0;
}
/*--------------------------------------------------------------------*/
void setBusy(busyPtr self, int val){
  assert(self != NULL);
  self->iBusy = val;
}
/*--------------------------------------------------------------------*/
int isBusy(busyPtr self){
  assert(self != NULL);
  return self->iBusy;
}
/*--------------------------------------------------------------------*/
int BusyAction(SConnection *pCon,SicsInterp *pSics, void *pData,
	       int argc, char *argv[]){
  busyPtr self = NULL;
  char pBuffer[80];

  self = (busyPtr)pData;
  assert(self != NULL);

  if(argc > 1){
    strtolower(argv[1]);
    if(usUser < SCGetRights(pCon)){
      SCWrite(pCon,"ERROR: no privilege to manipulate busy flag",eError);
      return 0;
    }
    if(strcmp(argv[1],"incr") == 0){
      incrementBusy(self);
      SCSendOK(pCon);
      return 1;
    } else if(strcmp(argv[1],"decr") == 0){
      decrementBusy(self);
      SCSendOK(pCon);
      return 1;
    } else if(strcmp(argv[1],"clear") == 0){
      clearBusy(self);
      SCSendOK(pCon);
      return 1;
    }
  }
  
  sprintf(pBuffer,"Busy = %d", isBusy(self));
  SCWrite(pCon,pBuffer,eValue);
  return 1;
}
/*---------------------------------------------------------------------*/
busyPtr findBusy(SicsInterp *pInter){
  CommandList *pCom = NULL;

  pCom = FindCommand(pInter,"busy");
  if(pCom != NULL){
    return (busyPtr)pCom->pData;
  }
}


