// C++ code Copyright (C) David R. Evans G4AMJ/NQ0I

#ifndef DEFS_WINH
#define DEFS_WINH

// These are put here because the idiotic Mac has its own idea of
// the meaning of "true" and "false".
#define false	0
#define true	1
#define forever while(true)

#define PI 3.14159265
#define INTEL

// the following is extracted directly from systypes.h. It is put here
// simply to save opening yet another file

#define __SYSTYPES_H

typedef signed char int8;
typedef signed short int16;
typedef signed long int32;

typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned long uint32;

// end of systypes.h

#define uint unsigned int

// byte inversion routines. These swap in place
extern void _invert(uint16&);
//extern void invert(int32&);

// The Borland compiler has a bug in that two identical typedefs are
// flagged as an error, so we have to include the whole mess here. Argh!
#include <stdio.h>

// Borland have the brilliant notion that one doesn't need to perform
// floating point operations unless one is calling fp functions. The
// following is supposed to fix that idiocy
#pragma extref _floatconvert

// the full definition (not just the declaration) of template functions
// need to be visible in the header file
template <class T> inline int SIGN(T x)
  { return ((x < 0) ? -1 : ((x > 0) ? 1 : 0)) }

template <class T> inline T MAX(T x, T y)
  { return ((x > y) ? x : y); }

template <class T> inline T MIN(T x, T y)
  { return ((x < y) ? x : y); }

template <class T> inline T SQR(T x)
  { return (x * x); }

template <class T> void invert(T& x)
{ if (ODD(sizeof(T))) then
    return;
  uint16* temp = (uint16*)&x;
  for (int n = 0; n < sizeof(T) / 2; n++)
    _invert(temp[n]);
}

// invert each element of an array
template <class T> void invert(T* x, const int n)
{ for (int m = 0; m < n; m++)
  { T* t = &(x[m]);
    invert(t);
  }
}

template <class T> size_t read_binary(FILE* fp, T& var)
{ const size_t status = fread(&var, sizeof(T), 1, fp);
  if (EVEN(sizeof(T))) then
    invert(var);
  return status;
}

template <class T> size_t read_binary(FILE* fp, T* var, int n)
{ const size_t status = fread((char*)var, sizeof(T), n, fp);
  if (EVEN(sizeof(T))) then
  { for (int k = 0; k < n; k++)
      invert(var[k]);
  }
  return status;
}

template <class T> int write_binary(FILE* fp, T& var)
{ if (sizeof(T) > 1) then
    invert(var);
  return(fwrite(&var, sizeof(T), 1, fp));
}

template <class T> void destroy(T* pointer)
{ if (pointer) then
    delete pointer;
  pointer = 0;
}

template <class T> void destroy_array(T* pointer)
{ if (pointer) then
    delete [] pointer;
  pointer = 0;
}

template <class T> void START(T& obj)
{ fseek((FILE*)obj, 0, 0); }

template <class T> void END(T& obj)
{ fseek((FILE*)obj, 0, 2); }

// if two values are not identical, abort with a message. This is
// a "better" assert.
template <class T> void _TST(T obj1, T obj2, char* msg,
			     char* filename, int line_nr)
{ if (!(obj1 == obj2)) then    // == more likely to be defined than !=
    _FE(msg, filename, line_nr);
}

extern void _CST(const unsigned long, const unsigned long, const char*, const int);

void yield(void);

#endif

