#ifndef	V_CONFIG_H
#define	V_CONFIG_H

/*
 * Disable implementation - specific extensions.
 */
#define	STRICT_ANSI

/*
 * Determine platform and bitness.
 */
#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || \
	defined(_WIN64) || defined(__WIN64__) || defined(WIN64) || \
	defined(_MSC_VER) || defined(__BORLANDC__) || \
	defined(__CYGWIN32__) || defined(__CYGWIN64__) || \
	defined(__WATCOMC__)
#ifndef __WINAPI__
#define __WINAPI__
#endif
#elif   defined(__ELF__) || defined(__linux) || defined(unix) || \
		defined(UNIX) || defined(__UNIX__) /* || defined(__FreeBSD__) FIXME: needs inclusion of sys/param.h */
#ifndef __UNIX__
#define __UNIX__
#endif
#else
#error Unsupported platform.
#endif

#ifdef	__LIBV64__
#error	Macro __LIBV64__ was defined somewhere else!
#endif

#ifdef	__LIBV32__
#error	Macro __LIBV32__ was defined somewhere else!
#endif

#ifdef _MSC_VER
#ifdef _WIN64
#define	__LIBV64__
typedef	signed __int64		s64_t;
typedef	unsigned __int64	u64_t;
#else
#define	__LIBV32__
#endif
#elif defined(__WATCOMC__)
#define	__LIBV32__
#elif defined(__GNUC__) /* also works with clang */
#ifdef __x86_64__
#define	__LIBV64__
typedef	signed long long	s64_t;
typedef	unsigned long long	u64_t;
#else
#define	__LIBV32__
#endif
#else
/* Unknown compiler: assume 32 bit */
#define	__LIBV32__
#endif

/*
 * -----------------------------------------------------------------------
 * Platform-specific config switches
 */
#ifdef	__WINAPI__

/*
 *	Uncomment next line if you *HATE* MustDie9x (i hate it ... )
 *	Note: this will make LibV COMPLETELY unusable on 95 / 98;
 *	WindowsME not tested :)
#define	CONFIG_NT_ONLY
 */

/*
 * Uncomment next line to enable NT console API.
 * Note: console API seems to be broken under MustDie.
#define		NT_CONSOLE
 */

/*
 * Platform-specific features
 */

/*
 * Uncomment next line to enable native Win32 GDI support for metafiles.
 * Notes:
 *  - native support is several times slower than emulation (we do dirty hacks);
 *	- LibV emulates only very small subset of GDI functions;
 *  - LibV doesn't expose GDI - like functions;
 *  - if GDI emulation disabled, than under WIN32 one can get DC of
 *    metafile (metaGetHandleNP()) and pass it to any GDI function.
#define	CONFIG_USE_NATIVE_METAFILE_API
 */

/*
 * Uncomment next line to enable GDI helper object for raster data.
 * The code is portable, but not very useful under UNIX.
 */
#define	CONFIG_WIN32_DIBOBJECT

/*
 * For broken integrated sound codecs on VIA chipsets
#define	CONFIG_LARGE_WAVE_INPUT_BUFFER
 */

#elif defined(__UNIX__)

/*
 * Uncomment next line to enable EsounD sound output support.
 * The code is still experimental, buggy and uncomplete;
 * and I'm planning to get rid of it.
#define CONFIG_ESOUND
 */

#endif	/* __UNIX__ */

/*
 * Default path style and delimiter: right.
 */
#if		defined(__UNIX__) || defined(__CYGWIN32__)
#define	RIGHT_SLASHED
#endif	/* defined(__UNIX__) || defined(__CYGWIN32__) */

/*
 * Under linux, prevent including ANSI - incompliant asm/io.h
 * FIXME: is this correct ?
 */
#ifdef		__linux
#define		_ASM_IO_H
#endif		/* __linux */

/*
 * 'Endian' macros.
 * Most UN*Ces (but not NT:) defines it.
 */
#ifndef		__BIG_ENDIAN
#define		__BIG_ENDIAN	4321
#endif		/* __BIG_ENDIAN */
#ifndef		__LITTLE_ENDIAN
#define		__LITTLE_ENDIAN	1234
#endif		/* __LITTLE_ENDIAN */

/*
 * BUGBUG TODO
 */
#ifndef		__BYTE_ORDER
#define		__BYTE_ORDER	__LITTLE_ENDIAN
#endif		/* __BYTE_ORDER */

/*
 * Default calling convention is 'stdcall' for NT, 'cdecl' for UNIX | GNUC
 */
#if		defined(__WINAPI__) && !defined(__GNUC__)
#define	V_CALL	__stdcall
#else	/* __GNUC__ || !__WINAPI__ */
#define	V_CALL	/* default calling convention */
#endif	/* __GNUC__ */

/*
 * Assumed calling convention for libc routines
 */
#if		defined(__WINAPI__) && !defined(__GNUC__)
#define	LIBC_CALL	__cdecl
#else	/* __GNUC__ || !__WINAPI__ */
#define	LIBC_CALL	/* default calling convention */
#endif	/* __GNUC__ */

/*
 * Structure packing macro for GNUC, stub for other compilers.
 * For non-GCC's, packing must be handled in pack0.h / ppack.h.
 */
#ifndef	ATTRIBUTE_PACKED
#ifndef	__GNUC__
#define	ATTRIBUTE_PACKED
#else	/* __GNUC__ */
#define	ATTRIBUTE_PACKED	__attribute__((packed))
#endif	/* __GNUC__ */
#endif	/* !ATTRIBUTE_PACKED */

/*
 * Macro prefix to export functions.
 * NOTE: dynamic linking currently supported only under Win32.
 */
#ifdef		BUILD_DLL
#define		EXPORT				__declspec(dllexport)
#else		/* !BUILD_DLL */
#define		EXPORT
#endif		/* !BUILD_DLL */

#define		V_LOCAL			static
#define		V_GLOBAL		EXPORT	V_CALL

/*
 * CBuilder refuses to import function with variable set of parameters
 * if such function declared with 'stdcall' calling convention.
 */
#if			defined(BCB_COMPAT) || defined(__BORLANDC__)
#define		V_GLOBAL_VA		EXPORT	__cdecl
#else		/* !BCB_COMPAT */
#define		V_GLOBAL_VA		V_GLOBAL
#endif		/* BCB_COMPAT */

/*
 * Workaround for MS cl.exe + Borland tlink32.exe.
 * FIXME: is this still needed ?
 */
#if		defined(BUILD_DLL) && defined(BCB_COMPAT) && !defined(__BORLANDC__)
#define	conPrintf	_conPrintf
#define	conlPrintf	_conlPrintf
#define	filePrintf	_filePrintf
#define	vglPrintf	_vglPrintf
#endif

/*
 * This hack allows us to use UNIX Makefile with CYGWIN32.
 * FIXME
 */
#if	defined(__CYGWIN32__) || defined(__CYGWIN64__)

#ifdef	__UNIX__
#undef	__UNIX__
#endif	/* __UNIX__ */

#ifndef	__WINAPI__
#define	__WINAPI__
#endif	/* !__WIN32__ */

#endif	/* __CYGWIN32__ */

/*
 * ANSI version of some functions HAS underscores; but GNU libc and
 * all Win32 RTLs (except MS Visual C RTL) uses functions without them.
 */
#ifndef		_MSC_VER
#define		_stricmp	strcmpi
#define		_chdir		chdir
#define 	_mkdir      mkdir
#define		_getcwd		getcwd
#endif		/* !_MSC_VER */

/*
 * GNU libc has strncasecmp(); MS RTL has strnicmp.
 * For WATCOM / BORLAND C we implement strncasecmp() in TAL/string.c.
 *
 * FIXME: is this a right place for this ???
 *
 * TODO: here must be snprintf() also !
 */
#if			defined(__WATCOMC__) || defined (__BORLANDC__)
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
	int	LIBC_CALL strcasecmp(const char *s1,const char *s2);
	int LIBC_CALL strncasecmp(const char *s1,const char *s2,unsigned n);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#elif 		defined(_MSC_VER) /* !__WATCOMC__ && !__BORLANDC__ */
#define		strcasecmp		_stricmp
#define		strncasecmp		_strnicmp
#endif		/* _MSC_VER */

/*
 * -----------------------------------------------------------------------
 * Data type switches
 */
/*
 * Uncomment next line to set base floating point type to 'double'
 */
/*
*/
#define CONFIG_DOUBLEVEC

/*
 * -----------------------------------------------------------------------
 * Basic features
 */

/*
 * Uncomment next line, if you want LibV to:
 *  - perform a lot of validity checks;
 *  - emit error descriptions, warnings, diagnostic and trace messages
 *    to console.
 * FIXME: to be honest, you CAN NOT currently compile LibV without
 * CHECKED_BUILD defined (moreover, and i've never tried to do that).
 */
#define	CHECKED_BUILD

/*
 * Uncomment next line to turn on hash-based dictionary for tracking
 * memory allocations; this slows allocation code down about 1.5 times.
 */
#define	MALLOC_DEBUG

/*
 * -----------------------------------------------------------------------
 * Code generation
 */

/*
 * No macros for math & base algorithms: generate code instead.
 *
 * TODO: rename these stuff, test implementation of macros, etc.
 */
/*
#define	FIFO_NO_MACRO
#define	STACK_NO_MACRO
#define	MATH_NO_MACRO
#define	VECTOR_NO_MACRO
#define	MATRIX_NO_MACRO
#define	PLANE_NO_MACRO
*/

/* #define	MATH_NO_MACRO */

/*
 * -----------------------------------------------------------------------
 * Abstract data types
 * (currently config defines ignored, TODO)
 */
#define	CONFIG_U8_STACK
#define	CONFIG_VP_STACK
#define	CONFIG_BLOCK_STACK
#define	CONFIG_U8_FIFO
#define	CONFIG_BLOCK_FIFO
#define	CONFIG_BINARY_TREE
#define	CONFIG_NWAY_TREE
#define	CONFIG_LINUX_LIST

/*
 * -----------------------------------------------------------------------
 * Key features
 */

/*
 * Wrappers for kernel objects
 * (currently config defines ignored, TODO)
 */
#define	CONFIG_MUTEX
#define	CONFIG_THREAD
#define	CONFIG_COND
/*
 * VFS & IO
 */
#define	CONFIG_VFS	/* (currently this define ignored, TODO) */

/*
 * Mount dummy volume al vfsInit() 'see vfs/fstree.c'
 */
#define	CONFIG_VFS_ADD_DUMMY_VOLUME


#define	CONFIG_MAPPED_IO	/* NU */
#define	CONFIG_IO_USES_NATIVE_PATH	/* NU */
#define	CONFIG_VFS_DIRECTORY_ENUMERATOR	/* NU */
#define	CONFIG_LFS_DIRECTORY_ENUMERATOR	/* NU */

/*
 * CONFIG_VFS_CATFS_MAX_SECTION_SIZE
 * Maximal number of bytes of data block (in concatenated filsystem)
 * which will be entirely read in memory if FS container file can't be mmap()'ed.
 */
#define	CONFIG_VFS_CATFS_MAX_SECTION_SIZE		(4096 * 256)

/*
 * Virtual filesystem drivers
 */
#define	CONFIG_VFS_WADFS	/* Id's DOOM I/II FS (driver is buggy) */
#define	CONFIG_VFS_PAKFS	/* Id's Quake I/II FS */
#define	CONFIG_VFS_TARFS	/* UN*X Tape ARchiver */
#define	CONFIG_VFS_GOBFS	/* LEC DF/JK FS */
#define	CONFIG_VFS_GRPFS	/* Silverman's Build-engine FS (debug it !) */
#define	CONFIG_VFS_ZIPFS	/* ZIP FS (*.zip, *.pk3) */

#if		defined(__WINAPI__) && !defined(__WATCOMC__) && !defined(__CYGWIN32__) && !defined(__CYGWIN64__)
#define	CONFIG_VFS_PEFS		/* Win32 RT_USERDATA resource FS */
#endif	/* defined(__WINAPI__) ... */

/*
 * RIFF WAVE I/O
 */

/*
 * Uncomment next line to assume broken WAV files to be 16-bps
 */
#define CONFIG_WORKAROUND_ZERO_BPS

/*
 * Device drivers
 * (currently ignored, TODO)
 */
#define	CONFIG_DEV_WAVE_IN
#define	CONFIG_DEV_WAVE_OUT
#define	CONFIG_DEV_COMM


/*
 * TODO
 */

/*
 * Utility objects
 * (currently ignored, TODO)
 */

/* Flexible, multifunction scanner */
#define	CONFIG_SCANNER

/*
 *	Comment next line to exclude MP3 decompressor class.
 *	FIXME: rewrite makefiles !
 */
#define	CONFIG_AUDIO_MP3

/*
 *	Comment next line to exclude transparent .gz file decompressing
 *	FIXME: rewrite makefiles !
 */
#define	CONFIG_COMPRESSION_ZLIB

/*
 * Uncomment next line to enable native Win32 clipboard support.
 * Enabling clipboard support extends namespace of metafile
 * and bitmap output functions with predefined path '//./clipboard'.
 */
#define	CONFIG_CLIPBOARD

/*
 * -----------------------------------------------------------------------
 * Support for different data formats
 */

/*
 * Comment lines below to exclude support for corresponding
 * raster format.
 */
#define	CONFIG_RASTER_TARGA
#define	CONFIG_RASTER_BITMAP
#define	CONFIG_RASTER_JPEG

/*
 * Comment next line to exclude support for Windows 3.1
 * placeable metafiles.
 */
#define CONFIG_METAFILE

/*
 * -----------------------------------------------------------------------
 * OpenGL helper function
 */

/* Base functinality (currently ignored) */
#define CONFIG_VGL
/* Helper functions for OpenGL view tranformation (currently ignored) */
#define CONFIG_CAMERA_CONTROL

/*
 * Comment next line to exclude precompiled OpenGL font
 */
#define	CONFIG_GL_PRECOMPILED_FONT

/*
 * -----------------------------------------------------------------------
 * The rest of config file are meaningful only for LibV itself.
 */
#ifdef	__LIBV__

/*
 * Format buffer size for printf()-like functions
 * TODO: use snprintf() (or implement it);
 */
#define	MAX_FORMAT_BUFFER			4096

#ifdef	CHECKED_BUILD
/*
 * Size of buffer which is returned by some strXXX functions when
 * caller requests pointer to string which can't be obtained.
 *
 * This is hack, but many crashes can be avoided this way.
 */
#define	STRING_GUARD_SIZE			4096
#endif	/* CHECKED_BUILD */

/*
 * Force some dirty tricks for cyrillic text support
 */
#define	CONFIG_CYRILLIC_HACKS

#endif	/* __LIBV__ */

#endif	/* V_CONFIG_H */
