#ifndef MISC_COMPAT_H
#define MISC_COMPAT_H

//
//Put all cross platform compatiablity macros in here
//

#include <stdlib.h> // needed for porting to openBSD
#include <sys/types.h> //needed for porting to openBSDy
#if defined(__WIN32__) || defined(WIN32) || defined(_WIN32)
#define _WINDOZE_
#pragma warning(disable:4127)
#pragma warning(disable:4100)
#define WIN32_LEAN_AND_MEAN

#define bzero(p, l) memset(p, 0, l)
#define bcopy(s, t, l) memmove(t, s, l)

#define strcasecmp(x, y) _stricmp(x, y)
#else
#endif
#if defined(__CYGWIN32__) || defined(__CYGWIN__)
#define _CYGWIN_
#endif

#if !defined(_WINDOZE_) && !defined(_CYGWIN_)
#define _UNIX_
#endif

#define _(x) (x)
#define N_(x) (x)


//typedefs for exactly sized datatypes
#ifdef _WINDOZE_
	typedef _int8 int8;
	typedef _int16 int16;
	typedef _int32 int32;
	typedef _int64 int64;
	typedef unsigned _int8 uint8;
	typedef unsigned _int16 uint16;
	typedef unsigned _int32 uint32;
	typedef unsigned _int64 uint64;
#else
	typedef char int8;
	typedef short int16;
	typedef int int32;
	typedef long long int64;
	typedef unsigned char uint8;
	typedef unsigned short uint16;
	typedef unsigned int uint32;
	typedef unsigned long long uint64;
#endif

#ifndef TRUE
#define TRUE -1
#endif
#ifndef FALSE
#define FALSE 0
#endif

#if !defined(_WINDOZE_) && !defined(_CYGWIN_)
#define PATHSEPERATOR "/"
#define PATHSEPERATORCHAR '/'
#else
#define PATHSEPERATOR "\\"
#define PATHSEPERATORCHAR '\\'
#endif

#if defined(_WINDOZE_) || defined(_CYGWIN_)
#define LITTLE__ENDIAN
#else
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__MACH__) || defined(__NetBSD__)
#include <machine/endian.h>
#if BYTE_ORDER == LITTLE_ENDIAN
#define LITTLE__ENDIAN
#else
#define BIG__ENDIAN
#endif
#else
#include <endian.h>
//#if defined(__BIG_ENDIAN) && defined(__BYTE_ORDER)
#ifndef BIG__ENDIAN
#ifndef LITTLE__ENDIAN
#ifdef __BIG_ENDIAN
#ifdef __BYTE_ORDER
//
#if __BIG_ENDIAN == __BYTE_ORDER
#define BIG__ENDIAN
#else
#define LITTLE__ENDIAN
#endif
#endif // #if defined(__FreeBSD__)
//
#endif
#endif
#endif
#endif
	//#else 
	//#if defined(BIG_ENDIAN) && defined(BYTE_ORDER)
#ifndef BIG__ENDIAN
#ifndef LITTLE__ENDIAN
#ifdef BIG_ENDIAN
#ifdef BYTE_ORDER
//
#if BIG_ENDIAN == BYTE_ORDER
#define BIG__ENDIAN
#else
#define LITTLE__ENDIAN
#endif
//
#endif
#endif
#endif
#endif
//
#endif

//default to little endian if none of the above worked.
//#if !defined(BIG__ENDIAN) && !defined(LITTLE__ENDIAN)
#ifndef BIG__ENDIAN
#ifndef LITTLE__ENDIAN
#define LITTLE__ENDIAN
#endif
#endif


#define ENDIANSWAP16(x) ( ((x & 0xff00) >> 8) | ((x & 0x00ff) << 8) )
#define ENDIANSWAP32(x) ( ((x & 0xff000000) >> 24) | ((x & 0x00ff0000) >> 8) | ((x & 0x0000ff00) << 8) | ((x & 0x000000ff) << 24) )


//converts an array of 32bit ints form one endian to another.
#define ENDIAN_ARRAY32(x, y) {int I; for(I = 0; I < y; I++) {x[I] = ENDIANSWAP32(x[I]);}}

//change an array to the endianess of this platform.
#ifdef BIG__ENDIAN
#define MY_ENDIAN_ARRAY32(x, y) ENDIAN_ARRAY32(x, y)
#else
#define MY_ENDIAN_ARRAY32(x, y)
#endif

#endif //MISC_COMPAT_H
