/*************************************************************
Multicast Dissemination Protocol version 2 (MDPv2)

This source code is part of the prototype NRL MDPv2 release
and was written and developed by Brian Adamson and Joe Macker.
This is presently experimental code and therefore use it at your 
own risk.  Please include this notice and provide credit to the 
authors and NRL if this program or parts of it are used for any 
purpose.

We would appreciate receiving any contributed enhancements 
or modifications to this code release. Please contact the developers 
with comments/questions regarding this code release.  Feedback on
use of this code can help continue support for further development.

Joe Macker                          Brian Adamson
Email: <macker@itd.nrl.navy.mil>    <adamson@newlink.net>
Telephone: +1-202-767-2001          +1-202-404-1194
Naval Research Laboratory           Newlink Global Engineering Corp.
Information Technology Division     6506 Loisdale Road Suite 209
4555 Overlook Avenue                Springfield VA 22150
Washington DC 20375                 <http://www.ngec.com>
**************************************************************/

#ifndef _SYS_DEFS
#define _SYS_DEFS

/*************************************************************
 * This header file provides definitions of some commonly
 * used macros and functions which aren't universally provided
 * by all systems.
 */

#ifdef UNIX
#include <sys/types.h> // must include this first to make SGI's compiler happy
#include <sys/time.h>  // for UNIX gettimeofday(), etc
#include <stdio.h>     // for cuserid()
#include <limits.h>    // for PATH_MAX
#include <assert.h>
#include <stdlib.h>
#ifndef PATH_MAX
#define PATH_MAX _POSIX_PATH_MAX
#endif // PATH_MAX
#ifdef IRIX
#include <sys/param.h>  // for SGI MAX/MIN defs
#endif // IRIX
#ifdef SUNOS
#define RAND_MAX 32767
#endif // SUNOS
#ifndef NULL
#define NULL 0
#endif
const char DIR_DELIMITER = '/';

#if !defined(NS2) && !defined(OPNET)
inline int GetSystemTime(struct timeval *tv)
{
    struct timezone tz;
    return gettimeofday(tv, &tz);
}
#endif // !NS2

#endif // UNIX

#ifdef WIN32
// Hack to provide gettimeofday() for WIN32 ( no better than 1 msec resolution)
#include <sys/types.h>
#include <sys/timeb.h>
#include <time.h>  // for mktime()
#include <basetsd.h>  // for UINT32/INT32 types
#include <winsock2.h>  // for struct timeval definition

#if !defined(NS2) && !defined(OPNET)
inline int GetSystemTime(struct timeval *tv)
{
    SYSTEMTIME st;
    GetLocalTime(&st);
    struct tm tm;
    tm.tm_sec = st.wSecond;
    tm.tm_min = st.wMinute;
    tm.tm_hour = st.wHour;
    tm.tm_mday = st.wDay;
    tm.tm_mon = st.wMonth - 1;
    tm.tm_year = st.wYear - 1900;
    tm.tm_isdst = -1;
    time_t t = mktime(&tm);
    tv->tv_sec = t;
    tv->tv_usec = st.wMilliseconds * 1000;
    return 0; 
}
#endif // !NS2

#define PATH_MAX MAX_PATH
#define O_WRONLY _O_WRONLY
#define O_RDONLY _O_RDONLY
const char DIR_DELIMITER = '\\';
#endif // WIN32

#ifdef NS2
#include "scheduler.h"
inline int GetSystemTime(struct timeval *tv)
{
    double current_time = Scheduler::instance().clock();
    tv->tv_sec = (unsigned long)(current_time);
    tv->tv_usec = (unsigned long)((current_time - tv->tv_sec) * 1.0e06);
    return 0;
}
#endif // NS2

#ifdef OPNET
#include "opnet.h"
inline int GetSystemTime(struct timeval *tv)
{
    double current_time = op_sim_time();
    tv->tv_sec = (unsigned long)(current_time);
    tv->tv_usec = (unsigned long)((current_time - tv->tv_sec) * 1.0e06);
    return 0;
}
extern void OpnetBreak(char* text);
#endif // OPNET

#ifndef MAX
#define MAX(X, Y) ((X>Y) ? X : Y)
#endif // !MAX`
#ifndef MIN
#define MIN(X, Y) ((X<Y) ? X : Y)
#endif // !MIN

// (TBD) Add a compile-time error check on these variable sizes
#ifndef WIN32
typedef long INT32;
typedef unsigned long UINT32;
#endif // !WIN32
typedef signed char INT8;
typedef unsigned char UINT8;
typedef short INT16;
typedef unsigned short UINT16;

#endif // _SYS_DEFS

