#pragma once

#ifndef _MSC_VER			// fixme: ok?
#include <stdint.h>			// uintptr_t, ...
#endif

#include <stddef.h>			// size_t, ...

#ifndef _MSC_VER
typedef int8_t				int8;
typedef uint8_t				uint8;
typedef int16_t				int16;
typedef uint16_t			uint16;
typedef int32_t				int32;
typedef uint32_t			uint32;
typedef int64_t				int64;
typedef uint64_t			uint64;
typedef unsigned char		boolean;      // stupid jpeglib
#else
typedef signed __int8		int8;
typedef unsigned __int8		uint8;
typedef signed __int16		int16;
typedef unsigned __int16	uint16;
typedef signed __int32		int32;
typedef unsigned __int32	uint32;
typedef signed __int64		int64;
typedef unsigned __int64	uint64;

typedef signed __int8		int8_t;
typedef unsigned __int8		uint8_t;
typedef signed __int16		int16_t;
typedef unsigned __int16	uint16_t;
typedef signed __int32		int32_t;
typedef unsigned __int32	uint32_t;
typedef signed __int64		int64_t;
typedef unsigned __int64	uint64_t;
#endif

typedef float				float32;
typedef double				float64;
typedef wchar_t				wchar;
typedef int32				unichar;

// probably more useful aliases
typedef int8				i8;
typedef uint8				u8;
typedef int16				i16;
typedef uint16				u16;
typedef int32				i32;
typedef uint32				u32;
typedef int64				i64;
typedef uint64				u64;
typedef float32				f32;
typedef float64				f64;

const double pi = 3.1415926535897932384626433832795;
const double degToRad = 3.1415926535897932384626433832795 / 180.0;		// constant to convert degrees to radians
const double radToDeg = 180.0 / 3.1415926535897932384626433832795;		// constant to convert radians to degrees

#ifdef __cplusplus

template < class T > T abs( const T &x )
{
    return x < 0 ? -x : x;
}

/*template < class T > T max( const T &x, const T &y )
{
	return x < y ? y : x;
}

template < class T > T min( const T &x, const T &y )
{
	return x < y ? x : y;
}
*/

template < class T > T clamp( const T &a, const T &x, const T &y )
{
    if ( x < y )
    {
        return a < x ? x : ( y < a ? y : a );

    }
    else
    {
        // y >= x
        return a < y ? y : ( x < a ? x : a );
    }
}

// clamp to (unsigned)byte range
template < class T > T clampb( const T &a )
{
    return a < (T)0 ? (T)0 : (T)255 < a ? (T)255 : a;
}

// floating-point linear interpolation
template < class T > T flerp( const T &a, const T &x, const T &y )
{
    return x + a * ( y - x );
}

#if defined(DEBUG) || defined(_DEBUG)
#include <assert.h>
#define ASSERT(x) assert(x)
#else
#define ASSERT(x)
#endif
#define STATIC_ASSERT(x)

#endif
