/*****************************************************************************
 * $Id: eng_funcs.hh,v 1.18 2006/10/24 02:05:24 devel Exp $
 * @file
 * @author	Jim E. Brooks  http://www.jimbrooks.org
 * @brief	Various small functions: function macros, inline functions, template functions.
 *          Writing "inline" in template functions does increase speed (gcc 3.4).
 *//*
 * LEGAL:	COPYRIGHT (C) 2004 JIM E. BROOKS
 *          THIS SOURCE CODE IS RELEASED UNDER THE TERMS
 *          OF THE GNU GENERAL PUBLIC LICENSE (GPL).
 *****************************************************************************/

#ifndef ENG_FUNCS_HH
#define ENG_FUNCS_HH 1

////////////////////////////////////////////////////////////////////////////////
/////////////////////////// function macros ////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

// Abstraction of the sign of Z axis in eye space.
// Remember to use these to test if a vertex is facing the viewpoint.
// The line-of-sight does extend thru negative Z.
#define Z_FACING (-1)
#define IS_Z_FACING( Z ) ((Z) < 0)
// An eye Z coordinate can be used as distance from viewplane (not viewpoint).
#define Z_TO_DISTANCE( EXPR ) (-(EXPR))

// Another layer of graphics system abstraction (over gfx/src/gfx).
#if GFXSYS_OPENGL
// OpenGL:
#define GfxsysInit( PARGC, ARGV, STRUCT )		OpenglInit( (PARGC), (ARGV), (STRUCT) )
#define GfxsysRun()								OpenglRun()
#define GfxsysDisplayPreFrame()					OpenglDisplayPreFrame()
#define GfxsysDisplayPostFrame()				OpenglDisplayPostFrame()
#define GfxsysProject							OpenglProject
#define GfxsysFog()								OpenglFog()
// (x,y) specifies lower-left corner. (x,y,w/h) are all positive.
#define GfxsysSetViewportGeom					OpenglSetViewportGeom
#define GfxsysDrawVertexArray					OpenglDrawVertexArray
#define GfxsysSetFrustum                        OpenglSetFrustum
#else
#error
#endif

////////////////////////////////////////////////////////////////////////////////
/////////////////////////// inline functions ///////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

// +1 or -1 if true or false
static inline int
PLUS_MINUS_1( bool plus )
{
	return plus ? 1 : -1;
}

/// @brief Reset a countdown variable related to time.
/// @verbatim
/// Compensates for program running slowly.
/// For example, in a timer handler, an action is done every second:
///    milsecOneSecond -= milsec;
///    if ( milsecOneSecond <= 0 )
///    {
///        [..]
///        RESET_COUNTDOWN( milsecOneSecond, 1000 );
///    }
/// Notice that a countdown variable is reset
/// by adding, not re-assigning, its reset value
/// in order to account for any remainder of time.
/// But what if the program is running slowly in the example
/// and 3 seconds (milsec=3000) has elapsed?
/// RESET_COUNTDOWN() mitigates by limiting the reset value.
/// @endverbatim
static inline void
RESET_COUNTDOWN( int& countdown, // value passed must be <= 0
                 const int resetValue )
{
ASSERT( countdown <= 0 ); // the passed countdown should be <= 0
	countdown += resetValue; // add, not assign, reset value to account for remainder of time
	countdown = Max( countdown, -resetValue ); // limit reset value in case program running slowly
}

////////////////////////////////////////////////////////////////////////////////
///////////////////////// template functions ///////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

#endif // ENG_FUNCS_HH
