//
//  Copyright © 2001 - 2002, RESON Inc. All Rights Reserved.
//
//  No part of this file may be reproduced or transmitted in any form or by
//  any means, electronic or mechanical, including photocopy, recording, or
//  information storage or retrieval system, without permission in writing
//  from RESON Inc.
//
//  Filename:   Utils.h
//
//  Project:    6046
//
//  Author(s):  W. Arcus
//
//  Purpose:    Defines general defintions for the project.
//
//  Notes:
//

#ifndef UTILS_H
#define UTILS_H

// Exports.

#pragma warning( disable : 4275 )                       // Safe to ignore warning's per Microsoft documentation.
#pragma warning( disable : 4251 )

#ifndef EXPORT_DLL
#ifdef _USRDLL
#define EXPORT_DLL  __declspec( dllexport )
#else
#define EXPORT_DLL
#endif
#else
#define EXPORT_DLL
#endif

#pragma warning( push, 3 )                              // Microsoft's STL implementation is dirty @ warning level 4.
#include <memory>                                       // Support for STL smart auto pointer.
#include <list>                                         // Support for STL's linked list container.
#pragma warning( pop )

///////////////////////////////////////////////////////////////////////////////
// Macros.

#define DimOf_m( a )            ( sizeof( (a) ) / sizeof( ((a)[ 0 ]) ) )

#ifdef _USRDLL
#ifndef ManageDllState_m
#define ManageDllState_m()      AFX_MANAGE_STATE( AfxGetStaticModuleState() )
#else
#define ManageDllState_m()
#endif
#else
#define ManageDllState_m()
#endif

// Macros originally from Jeffery Ricter's MSJ article for use with the 
// pragma statment for compile time messaging.
// Example: #pragma CompileMessage_m( "My message required here" )

#define chSTR(x)                #x
#define chSTR2(x)               chSTR(x)
#define CompileMessage_m(desc)  message( __FILE__ "(" chSTR2(__LINE__) ") : " desc )

#define ThrowMessage_m( a )     TRACE( _T( "File: " __FILE__ ", Line: %d: " a "\n" ), __LINE__ );   \
                                throw _T( (a) );
//                                ASSERT( false );                                                    \
//                                throw _T( (a) );

// Macros emulating MSVC's __try{...}__finally{...} construct using C++ thus supporting object unwinding.

#define __TRY                   try { try
#define __FINALLY               catch ( ... )     { TRACE( _T( "Exception caught in __TRY block, line: %d, file: %s\n" ), __LINE__, __FILE__ );     } {
#define __ENDFINALLY            } } catch ( ... ) { TRACE( _T( "Exception caught in __FINALLY block, line: %d, file: %s\n" ), __LINE__, __FILE__ ); }

// Support for common critical section usage within a __TRY/__FINALLY block.

#define __ENTERCRITICAL(a)      __TRY { (a).Enter();
#define __LEAVECRITICAL(a)      } __FINALLY{ (a).Leave(); }__ENDFINALLY

// Template functions.

template <class T>
inline T Clip( const T &rInitialValue, const T &rLower, const T &rUpper )
{
    T ClippedValue = rInitialValue;

    if ( ClippedValue < rLower )
    {
        ClippedValue = rLower;
    }

    if ( ClippedValue > rUpper )
    {
        ClippedValue = rUpper;
    }

    return ClippedValue;
}

template <typename tObject>
void DestroyAutoPointer( std::auto_ptr<tObject> &rpObject )
{
    if ( rpObject.get() != NULL )
    {
        delete ( rpObject.release() );
        rpObject = std::auto_ptr<tObject>( NULL );
    }

    ASSERT( rpObject.get() == NULL );
}

///////////////////////////////////////////////////////////////////////////////
// Helper macros for Endian byte conversion.

#define Swap32_m( data )        \
{                               \
    __asm mov eax, data         \
    __asm bswap eax             \
    __asm mov data, eax         \
}

#define Swap16_m(data)          \
    __asm ror data, 8


#endif      // #ifndef UTILS_H


