//===========================================================================//
// File:	style.hh                                                            //
// Project: MUNGA           Brick: None assigned - coding styles, etc.       //
// Contents: Base information used by all MUNGA source files                 //
//---------------------------------------------------------------------------//
//   Date    Who  Modification                                               //
// --------  ---  ---------------------------------------------------------- //
// 10/14/94  JMA  Initial coding.                                            //
// 11/03/94  ECH  Made compatible with BC4.0                                 //
//---------------------------------------------------------------------------//
// Copyright (C) 1994-1995, Virtual World Entertainment, Inc.					  //
//                      PROPRIETARY AND CONFIDENTIAL                         //
//===========================================================================//

#pragma once

#include "Stuff.hpp"

namespace Stuff {

	extern int ArmorLevel;

	enum {SNAN_NEGATIVE_LONG=0xffb1ffb1};

	#if !defined(Verify)
		#if !defined(_ARMOR)
			#include "ArmorOff.hpp"
		#else
			#include "ArmorOn.hpp"
		#endif
	#endif

	#define Register_Pointer(p) Check_Pointer(p)
	#define Unregister_Pointer(p) Check_Pointer(p)
	#define Register_Object(p) Check_Object(p)
	#define Unregister_Object(p) Check_Object(p)

	void
		Flood_Memory_With_NAN(
			void *where,
			size_t how_much
		);

	#define Test_Assumption(c)\
		while (!(c)) {SPEW((GROUP_STUFF_TEST, #c" failed!")); return false;}

	#define Test_Message(m) SPEW((GROUP_STUFF_TEST, m));

	#if defined(_ARMOR)
		class MemoryRegister;

		class Signature
		{
			friend class MemoryRegister;

		private:
			enum Mark
			{
				Valid=0x7B135795L,
				Destroyed=0x4FED1231L
			} mark;

		protected:
			Signature();
			~Signature();

		public:
			friend void Is_Signature_Bad(const volatile Signature *p);

			bool IsMarkedValid() {return mark==Valid;}
		};

		inline void
			Is_Signature_Bad(const volatile void* p)
				{Check_Pointer(p);}
	#endif

	//##########~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	//# MACROS #
	//##########

	#define ELEMENTS(Array)	(sizeof(Array)/sizeof(*Array))

	#if defined(__sgi__)
		#define _stricmp(s1, s2)			(strcasecmp(s1, s2))
		#define _strnicmp(s1, s2, n)		(strncasecmp(s1, s2, n))
	#endif

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Spews
	//
	#if !defined(Spew)
		inline void
			Spew(
				const char* group,
				int value
			)
				{SPEW((group, "%d+", value));}

		inline void
			Spew(
				const char* group,
				float value
			)
				{SPEW((group, "%f+", value));}

		inline void
			Spew(
				const char* group,
				const char* value
			)
				{SPEW((group, "%s+", value));}
	#endif

	//#############~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	//# TEMPLATES #
	//#############

	extern float SMALL;

	#define Abs(value) ((value>0) ? value : -value)
	#define Clamp(v,f,c) if (v<f) v=f; else if (v>c) v=c; else (void)0
	#define Max_Clamp(v,c) if (v>c) v=c; else (void)0
	#define Is_Many_Bits(value) (Lowbit(value)^value)
	#define Low_Bit(value) (value & (-value))
	#define Min_Clamp(v,f) if (v<f) v=f; else (void)0
	#define Max(a,b) ((a>b) ? a : b)
	#define Min(a,b) ((a<b) ? a : b)
	#define Sgn(value) ((value<-SMALL) ? -1 : value>SMALL)

	//############~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	//# TYPEDEFS #
	//############

	enum {INT_BITS=32};

}

inline void*
	_cdecl operator new(size_t size, void* where)
		{Check_Pointer(where); return where;}

