#include <stdlib.h>
#include <stdio.h>

#define __STDTYPES_CPP

#include <extcdecl.h>
#include <conf.h>
#include <modaut.h>

#if XVT_OS == XVT_OS_WIN || XVT_OS == XVT_OS_NT
#include <dos.h>
#include <hlapi_c.h>
#endif

#include <checks.h>
#include <isam.h>
#include <prefix.h>
#include <codeb.h>

extern isfdptr *openf;
HIDDEN long _stdlevel = 0;

// @doc INTERNAL

// @func Ritorna il livello degli archivi
long get_std_level()
{ return _stdlevel; }

// @doc INTERNAL

// @func Ritorna il numero di serie della chiave
//
// @rdesc Numero di serie della chiave
int get_serial_number()
{
#if XVT_OS == XVT_OS_WIN || XVT_OS == XVT_OS_NT
  const int status = HL_LOGIN(ModAd, DONT_CARE, REFKEY, VERKEY);
  if (status != STATUS_OK)
    return -1;
#endif           
  return getser();
}

// @doc INTERNAL

// @func Inizilizza le variabili globali
void init_global_vars()
{
  TPrefix& pref = prefix_init();
  
  pref.set("");
  _stdlevel = pref.filelevel();
  
  FileDes       d;
  CGetFile(LF_DIR, &d, _nolock, NORDIR);
  
  long maxfdir = d.EOX;
  pref.set("DEF");
  CGetFile(LF_DIR, &d, _nolock, NORDIR);
  if (d.EOD > maxfdir) maxfdir = d.EOD;

  isjournal = FALSE;
  
  openf = new isfdptr[maxfdir];
  openrec = new TRectype*[maxfdir];
  
  for (long i = 0; i < maxfdir; i++)
  {
    openf[i] = NULL;
    openrec[i] = NULL;
  }
  
#if XVT_OS == XVT_OS_SCOUNIX
  const bool muflag = CGetAut(MUAUT);
  if (SerNo && !muflag)
    fatal_box("Abnormal termination: check protection or serial number\n");
#endif
  DB_init();
}
// @doc INTERNAL

// @func Dealloca le variabili globali
void free_global_vars()
{                
#if XVT_OS == XVT_OS_WIN || XVT_OS == XVT_OS_NT
  HL_LOGOUT();
#endif
  if (openf != NULL)
  {
    delete openf;
    delete openrec;
    prefix_destroy();
  }  
  DB_exit();
}

#ifndef FOXPRO
#include <xvt.h>

// @doc EXTERNAL

// @func Operatore per la creazione di un oggetto (sostituisce operatore C++)
//
// @rdesc Ritorna il puntatore all'oggetto creato
void* operator new(size_t size)

// @comm Per maggiori informazioni fare riferimento all'omonimo comando sull'help
//   in linea del C++.
//       <nl>Questa funzione viene implementata se non si opera in ambiante FoxPro.

{ 
  void* mem = (void*)malloc(size); 
  if (mem == NULL)
    fatal_box("Out of memory: can't allocate %u bytes", size);

  return mem;
}
// @doc EXTERNAL

// @func Operatore per la distruzione di un oggetto (sostituisce operatore C++)
void operator delete(
     void* ptr) // @parm Puntatore all'oggetto da distruggere

// @comm Per maggiori informazioni fare riferimento all'omonimo comando sull'help
//   in linea del C++.
//       <nl>Nel caso venga passato un puntatore NULL viene emesso un <f CKECK>.
//       <nl>Questa funzione viene implementata se non si opera in ambiante FoxPro.

{
  CHECK(ptr, "Can't delete a NULL pointer");
  free(ptr);
}

#endif // FOXPRO


