#ifndef DEFINITIONS_H
#define DEFINITIONS_H

#include <stdio.h>
#include <math.h>
#include <string.h>

namespace gengraph {

// Max line size in files
#define FBUFF_SIZE 1000000

// disable lousy VC++ warnings
#ifdef _ATL_VER_
#pragma warning(disable : 4127)
#endif //_ATL_VER_

// Verbose
#define VERBOSE_NONE 0
#define VERBOSE_SOME 1
#define VERBOSE_LOTS 2
int VERBOSE();
void SET_VERBOSE(int v);

// Random number generator
void my_srandom(int);
int my_random();
int my_binomial(double pp, int n);
double my_random01(); // (0,1]

#define MY_RAND_MAX 0x7FFFFFFF

// IPv4 address direct translation into 32-bit uint + special IP defs
typedef unsigned int ip_addr;
#define IP_NONE   0x7FFFFFFF
#define IP_STAR   0x00000000
#define IP_MYSELF 0x7F000001

// Compatibility
#ifdef _WIN32
#define strcasecmp _stricmp
#endif
//inline double round(double x) throw () { return (floor(0.5+x)); } 

// No assert
#ifndef _DEBUG
#ifndef NDEBUG
#define NDEBUG
#endif //NDEBUG
#endif //_DEBUG

// Min & Max
#ifndef min
#define defmin(type) inline type min(type a, type b) { return a<b ? a : b; }
defmin(int)
defmin(double)
defmin(unsigned long)
#endif //min
#ifndef max
#define defmax(type) inline type max(type a, type b) { return a>b ? a : b; }
defmax(int)
defmax(double)
defmax(unsigned long)
#endif //max

// Traceroute Sampling
#define MODE_USP 0
#define MODE_ASP 1
#define MODE_RSP 2

// Debug definitions
//#define PERFORMANCE_MONITOR
//#define OPT_ISOLATED

// Max Int
#ifndef MAX_INT
#define MAX_INT 0x7FFFFFFF
#endif //MAX_INT

//Edge type
typedef struct { int from; int to; } edge;

// Tag Int
#define TAG_INT 0x40000000

// Oldies ....
#define S_VECTOR_RAW

//*********************
// Routine definitions
//*********************

/* log(1+x)
inline double logp(double x) {
  if(fabs(x)<1e-6) return x+0.5*x*x+0.333333333333333*x*x*x;
  else return log(1.0+x);
}
//*/


//Fast search or replace
inline int* fast_rpl(int *m, const int a, const int b) {
  while(*m!=a) m++;
  *m = b;
  return m;
}
inline int* fast_search(int *m, const int size, const int a) {
  int *p = m+size;
  while(m != p--) if(*p == a) return p;
  return NULL;
}

// Lovely percentage print
inline void print_percent(double yo, FILE *f = stderr) {
  int arf = int(100.0*yo);
  if(double(arf)>100.0*yo) arf--;
  if(arf<100) fprintf(f," ");
  if(arf<10) fprintf(f," ");
  fprintf(f,"%d.%d%%",arf,int(1000.0*yo-double(10*arf)));
}

// Skips non-numerical chars, then numerical chars, then non-numerical chars.
inline char skip_int(char* &c) {
  while(*c<'0' || *c>'9') c++;
  while(*c>='0' && *c<='9') c++;
  while(*c!=0 && (*c<'0' || *c>'9')) c++;
  return *c;
}

// distance+1 modulo 255 for breadth-first search
inline unsigned char next_dist(const unsigned char c) { return c==255 ? 1 : c+1; }
inline unsigned char prev_dist(const unsigned char c) { return c==1 ? 255 : c-1; }

// 1/(RANDMAX+1)
#define inv_RANDMAX (1.0/(1.0+double(MY_RAND_MAX)))

// random number in ]0,1[, _very_ accurate around 0
inline double random_float() {
  int r=my_random();
  double mul=inv_RANDMAX;
  while(r<=0x7FFFFF) {
    r<<=8;
    r+=(my_random()&0xFF);
    mul*=(1.0/256.0);
  }
  return double(r)*mul;
}

// Return true with probability p. Very accurate when p is small.
#define test_proba(p) (random_float()<(p))

// Random bit generator, sparwise.
static int _random_bits_stored = 0;
static int _random_bits = 0;

inline int random_bit() {
  register int a = _random_bits;
  _random_bits = a >> 1;
  if(_random_bits_stored--) return a&0x1;
  a = my_random();
  _random_bits = a >> 1;
  _random_bits_stored = 30;
  return a&0x1;
}

// Hash Profiling (see hash.h)
void _hash_prof();

} // namespace gengraph

#endif //DEFINITIONS_H
