// Copyright 1999
// College of Computer Science
// Northeastern University Boston MA 02115

// This software may be used for educational purposes as long as this copyright
// notice is retained at the top of all files

// Should this software be modified, the words "Modified from Original" must be
// included as a comment below this notice

// All publication rights are retained.  This software or its documentation may
// not be published in any media either in whole or in part.

///////////////////////////////////////////////////////////////////////////////
//	Platform.h
//  Define platform specific macros
///////////////////////////////////////////////////////////////////////////////


#ifndef PLATFORM_H_
#define PLATFORM_H_

#include <SelectPlatform.h>

// sanity check platform macro -- users must define exactly one platform macro
// this avoids conflict between SelectPlatform.h and compiler settings

#if  defined(CORE_PLATFORM_MACOS) &&  defined(CORE_PLATFORM_WIN32)
#error "PLATFORM.H - you defined more than one platform!"
#endif

#if !defined(CORE_PLATFORM_MACOS) && !defined(CORE_PLATFORM_WIN32)
#error "PLATFORM.H - you must define a platform!"
#endif


// introduce typedef for byte type for all other files
typedef unsigned char byte;


///////////////////////////////////////////////////////////////////////
//                   BEGIN PLATFORM DEPENDENT CODE                   //

#if defined(CORE_PLATFORM_WIN32)

#pragma message("Using CORE_PLATFORM_WIN32\n")

// eliminate stupid compiler warnings on exported template classes

#pragma warning(disable: 4231)
#pragma warning(disable: 4251)
#pragma warning(disable: 4275)

// reduce compile time for Microsoft header files
#define VC_EXTRALEAN
#define WIN32_EXTRA_LEAN
#define WIN32_LEAN_AND_MEAN


// if EXPORT is not defined already then
// define EXPORT for the DLL calling convention
// must be __declspec(dllexport) for compiling Core Tools as DLL
// must be __declspec(dllimport) for compiling user code


#ifndef EXPORT

#ifdef  CORETOOLS

#pragma message("Compiling Core Tools as DLL")

#define EXPORT __declspec(dllexport)

#define TEMPLATE_PREFIX

#else

#pragma message("Compiling User Code")

#define EXPORT __declspec(dllimport)

#define TEMPLATE_PREFIX extern

#endif // CORETOOLS

#endif // EXPORT


#undef min
#undef max


// include the basic Windows API definitions

#include <windows.h>		// standard WIN32 stuff
#include <commdlg.h>		// common dialog box stuff

// introduce type for native window pointer

typedef HWND NativeWindowPtr;

#endif // end Win32 specific


#if defined(CORE_PLATFORM_MACOS)

#pragma message("Using CORE_PLATFORM_MACOS\n")

// Mac-version defines EXPORT as nothing

#define EXPORT
#define TEMPLATE_PREFIX

// introduce type for native window pointer

typedef CWindowPtr NativeWindowPtr;

#endif // end MacOS specific


// debugging support

#if defined(CORE_PLATFORM_WIN32)

/* Debugging support for Windows
 * Much like the MFC trace macros, except that the function is overloaded
 * to use 0, 1, 2, or 3 arguments. If you need more arguments, it should
 * be obvious how to add another overload.
 *
 * Using templates allows for type checking, but remember we're just passing
 * the arguments on to sprintf, which is type-clueless, so you will have
 * undefined behavior if your format specification fields are incorrect.
 *
 * Output will only be visible through the debug output window in MSVC
 *
 * These might be useful later, so maybe we can do a Mac version and
 * keep them in for student use.
 */

template<class DebugString>
void Trace(const DebugString& sz)
{
	OutputDebugString(sz);
}

template<class DebugString, class Arg1Type>
void Trace(const DebugString& sz,
		   const Arg1Type& arg1)
{
	char buf[1024];
	sprintf(buf, sz, arg1);
	OutputDebugString(buf);
}

template<class DebugString, class Arg1Type, class Arg2Type>
void Trace(const DebugString& sz,
		   const Arg1Type& arg1,
		   const Arg2Type& arg2)
{
	char buf[1024];
	sprintf(buf, sz, arg1, arg2);
	OutputDebugString(buf);
}

template<class DebugString, class Arg1Type, class Arg2Type, class Arg3Type>
void Trace(const DebugString& sz,
		   const Arg1Type& arg1,
		   const Arg2Type& arg2,
		   const Arg3Type& arg3)
{
	char buf[1024];
	sprintf(buf, sz, arg1, arg2, arg3);
	OutputDebugString(buf);
}

#endif // end Win32 specific

// end debugging support

//                    END PLATFORM DEPENDENT CODE                    //
///////////////////////////////////////////////////////////////////////


#endif // PLATFORM_H_