#ifndef _NODE_H_
#define _NODE_H_

#include <stdlib.h>
#include <time.h>
#include <math.h>


#define MACLEN	6

/* Types of calibrated records */
#define C_SIGNAL	0x1
#define C_RADIUS	0x2
#define C_TXYZ		0x4
#define C_RXYZ		0x8
#define C_NPOW		0x10
#define C_KPOW          0x20
#define C_C2C1C0	0x40
#define C_RADIUS_CALC	0x80


typedef union {
	unsigned char str[MACLEN];
	unsigned long long adr;
} Mac;

typedef struct{
	Mac mac;
	float X;
	float Y;
	float Z;
	unsigned short Gain; /* antenna gain */
} WifiNode;


#define MAX_S_NUM    20

typedef struct{
  unsigned char type;	/* type of the calirated record */
  WifiNode rx;		/* receiver */
  WifiNode tx;		/* transmitter */
  long time;		/* timestamp */
  float S;		/* mean/calibrated signal strength in dBm */
  unsigned short numS;	/* number of measurements of S */
  float sigmaS;         /* deviation of S */
  float R; 		/* calibrated distance */
  unsigned short numR;	/* number of mesurements of R */
  float sigmaR;         /* deviation of R */
  float Rcalc; 		/* mean calculated distance */
  unsigned short numRcalc;	/* number of calculations of R from S */
  float sigmaRcalc;         /* actual deviation of calculated R */
  float sigmaRproj;         /* projected deviation of calculated R */

  float nPow;		/* calibrated n power */
  float nS0;   /* calibrated signal at 1m distance from source */
  float sigmaN;
  float sigmaNS0;

  float kPow; /* calibrated k power */
  float kS0;   /* calibrated signal at 1m distance from source */ 
  float sigmaK;
  float sigmaKS0;

  float C2;
  float C1;
  float C0;
  float sigmaC0;
  float sigmaC1;
  float sigmaC2;

  /* */
  float Sarr[MAX_S_NUM];
  float Rarr[MAX_S_NUM];
  int posS;

} WifiPair;

/* Create a hash index from transmitter MAC */
unsigned char getTxHashFn(const void* ps);

/* Create a hash index from receiver MAC */
unsigned char getRxHashFn(const void* ps);

/* Checks if transmitters' MACs are equal */
int isEqTx(const void* pt, const void* ps);

/* Checks if receivers' MACs are equal */
int isEqRx(const void* pt, const void* ps);

/* Checks if both MACs are equal */
int isEqTxRx(const void* pt, const void* ps);

/* Checks if receivers' MACs are equal */
/* and types of ps present in pt */
int isEqRxType(const void* pt, const void* ps);

/* Checks if transmitters' MACs are equal */
/* and types of ps present in pt */
int isEqTxType(const void* pt, const void* ps);

/* Checks if transmitters' MACs and time stamps are equal. */
/* It's used for calibrated hash, where multiple records with
   same MAC, but duffernet time stamps may be present. */
int isEqTxTime(const void* pt, const void* ps);

/* Checks if transmitters' MACs and time stamps are equal. */
/* It's used for calibrated hash, where multiple records with
   same MACs, but duffernet time stamps may be present. */
int isEqTxRxTime(const void* pt, const void* ps);

/* Checks if transmitters' MACs and time stamps are equal. */
/* It's used for calibrated hash, where multiple records with
   same MAC, but duffernet time stamps may be present. */
int isEqRxTime(const void* pt, const void* ps);

/* Checks if types of ps present in pt*/
int isEqType(const void* pt, const void* ps);

/* Checks for the same type but different unique key: tx.mac, rx.mac, time */
int isEqTypeNoSelf(const void* pt, const void* ps);

/* Operator new for WifiPair */
void* newWifiPair();

/* Operator new for WifiPair for use with ctor...Cur*/
void* newWifiPairCur();

/* Copy constructor for WifiPairs in the current hash. */
void ctorWifiPair(void* pt, const void* ps);

/* Copy constructor for WifiPairs in the current hash. */
/* It calculates mean S, too. */
void ctorWifiPairCur(void* pt, const void* ps);

/* Copy constructor for WifiPairs being used for the initial load
   of the calibrated and current hash. */
/* It calculates R from Rx xyz and Tx xyz */
void ctorWifiPairLoad(void* pt, const void* ps);

#endif
