///////////////////////////////////////////////////////////////////////////////
/// @file deMachine.hpp
///
/// @brief System configuration analyzer header
///
/// @author Lightning
///
/// This file is the intellectual property of Novus Delta, LLC.. Usage of the
/// contents of this file is subject to the Destiny3D Member License which
/// can be found at http://www.destiny3d.com.  Any other usage is prohibited.
///
/// This file is distributed "AS IS" without warranty of any kind.  Novus
/// Delta, LLC. does not guarantee the fitness of the contents of this file
/// for any particular purpose.
///
/// Copyright (C) 2001-2003 Novus Delta, LLC. All Rights Reserved.
///
/// <hr>
///                                 Change History
/// <hr>
///
/// @date Nov 2001
/// @author Lightning
/// @remarks Creation
///
///////////////////////////////////////////////////////////////////////////////

#ifndef DEMACHINE_HPP
#define DEMACHINE_HPP
#ifdef _MSC_VER
//=================================================================================
// Includes
//=================================================================================

#include "deGlobalTypes.hpp"
#include "deInternalValues.hpp"
#include "deArray.hpp"

//=================================================================================
// DLL Import/Export Defines
//=================================================================================

#if defined(DEMACHINE_DLL_EXPORTS) || defined(DESTINY3D_EXPORT_ALL)
#	define DEMACHINE_API extern "C" DEDLL_EXPORT
#elif defined(DESTINY3D_STATIC_LINK)
#	define DEMACHINE_API extern "C"
#else
#	define DEMACHINE_API extern "C" DEDLL_IMPORT
#endif

#ifdef USING_DESTINY3D
#ifdef _DEBUG
#	ifdef DESTINY3D_STATIC_LINK
#		pragma comment(lib, "deMachine_sd")
#	else
#		pragma comment(lib, "deMachined")
#	endif //DESTINY3D_STATIC_LINK
#else
#	ifdef DESTINY3D_STATIC_LINK
#		pragma comment(lib, "deMachine_s")
#	else
#		pragma comment(lib, "deMachine")
#	endif //DESTINY3D_STATIC_LINK
#endif //_DEBUG
#endif //USING_DESTINY3D



//=================================================================================
// Machine Conguration Structures
//=================================================================================

/// information about a computer's CPU architecture
struct deCPUInfo
{
	enum deCPUType
	{
		DECPUTYPE_UNKNOWN=0,
		DECPUTYPE_INTEL,	///< Intel CPU
		DECPUTYPE_AMD,		///< AMD CPU
		DECPUTYPE_32BIT = 0x7fffffff
		// note from Assassin: I think this should be generalized to architectures
		// such as x86, A64, PPC, etc, then having a union of info regarding each architecture
	};
	deCPUType CPUType;		///< Type of CPU
	long  CPUCount;         ///< Number of CPUs in the system
	char  Name[48];         ///< String name of CPU
	char  Vendor[13];       ///< Vendor string
	float Mhz;              ///< Mhz speed of chip
	float Freq;             ///< Performance frequency
	char  ProcessorType;    ///< Processor type, 0 = OEM cpu. on Intel chips, 1 = OverDrive, 2 = dual processor
	char  Family;           ///< Processor family
	char  Model;            ///< Processor model
	char  Stepping;         ///< Processor stepping	
	char  ExtendedFamily;   ///< Extended family value
	long  Cache[8];         ///< 0 to 3 for cache entries

	deBoolean FPU;          ///< Floating-Point unit on chip
	deBoolean VME;          ///< Virtual Mode Extension
	deBoolean DE;           ///< Debugging Extension
	deBoolean PSE;          ///< Page Size Extension
	deBoolean TSC;          ///< Time Stamp Counter
	deBoolean MSR;          ///< Model Specific Registers
	deBoolean MCE;          ///< Machine Check Exception
	deBoolean CX8;          ///< CMPXCHG8 Instruction
	deBoolean APIC;         ///< Software-accessible local APIC on Chip
	deBoolean SEP;          ///< Fast System Call
	deBoolean MTRR;         ///< Memory Type Range Registers
	deBoolean PGE;          ///< Page Global Enable
	deBoolean MCA;          ///< Machine Check Architecture
	deBoolean CMOV;         ///< Conditional Move Instruction
	deBoolean PAT;          ///< Page Attribute Table
	deBoolean PSE36;        ///< 36-bit Page Size Extension
	deBoolean MMX;          ///< MMX technology
	deBoolean FXSR;         ///< Fast Floating Point Save and Restore
	deBoolean SSE;          ///< Streaming SIMD Extension
	deBoolean PAE;          ///< Physical Address Extension

	deBoolean INTEL_PN;     ///< Processor Number
	deBoolean INTEL_CLFSH;  ///< CLFlush command support
	deBoolean INTEL_DS;     ///< Debug Store
	deBoolean INTEL_ACPI;   ///< ACPI Preprocessor Performance Modulation Registers
	deBoolean INTEL_SSE2;   ///< SSE2
	deBoolean INTEL_SS;     ///< Self Snoop
	deBoolean INTEL_TM;     ///< Thermal Monitor

	deBoolean AMD_AMIE;     ///< AMD Multimedia Instructions Extensions
	deBoolean AMD_3DNOWEXT; ///< AMD 3DNOW! Extensions
	deBoolean AMD_3DNOW;    ///< AMD 3DNOW! Technology
	deBoolean AMD_MPCAPABLE;///< AMD Multiprocessing Capable (some older MP chips return false)
};

/// information regarding a computer operating system
struct deOSInfo
{
	/// Various known operating systems
	enum deOSType
	{
		DEOSTYPE_UNKNOWN=0,		///< Unknown Operating System
		DEOSTYPE_WINDOWS95,		///< Microsoft Windows 95
		DEOSTYPE_WINDOWS98,		///< Microsoft Windows 98
		DEOSTYPE_WINDOWSME,		///< Microsoft Windows ME
		DEOSTYPE_WINDOWSNT,		///< Microsoft Windows NT
		DEOSTYPE_WINDOWS2000,	///< Microsoft Windows 2000
		DEOSTYPE_WINDOWSXP,		///< Microsoft Windows XP
		DEOSTYPE_32BIT = 0x7fffffff
	};
	deOSType OSType;			///< Type of operating system currently running
	float Version;				///< Version of the operating system
	int Build;					///< Build number of the operating system
	char AdditionalInfo[128];	///< More specific information about the OS
};


/// information regarding a computer's memory
struct deMemoryInfo
{
	unsigned int MemoryLoad; 
	u64 TotalPhysical;
	u64 AvailablePhysical;
	u64 TotalPageFile;
	u64 AvailablePageFile;
	u64 TotalVirtual;
	u64 AvailableVirtual;
	u64 AvailableExtendedVirtual;
};

/// infomation regarding Microsoft DirectX
struct deDXInfo
{
	long MajorVersion;	///<major version of DirectX
	long MinorVersion;	///<minor version of DirectX
	long StepVersion;	///<stepping version of DirectX
};


struct deDriveInfo
{
	enum deDriveType
	{
		DEDRIVE_UNKNOWN=0,
		DEDRIVE_NO_ROOT_DIR,
		DEDRIVE_REMOVABLE,
		DEDRIVE_FIXED,
		DEDRIVE_REMOTE,
		DEDRIVE_CDROM,
		DEDRIVE_RAMDISK,
		DEDRIVE_32BIT = 0x7fffffff
	};
	u64 TotalSize;	///<total size of the drive
	u64 FreeSize;	///<free space on drive
	char Drive[4];		///<Drive letter
	deDriveType Type;	///<Type of drive
};

/// information regarding a whole computer system
struct deSystemInfo
{
	deCPUInfo CPUInfo;			///< CPU Information
	deOSInfo OSInfo;			///< Operating System Information
	deMemoryInfo MemoryInfo;	///< Memory Information
	deDXInfo DXInfo;			///< DirectX Information
//	deTArray < deTWrapper<deDriveInfo> > DriveInfo;
	deTArray < deDriveInfo > DriveInfo;	///< Drive Information
};



//=================================================================================
// IdeMachine Class
//
// System Configuration Analyzer Interface Base Class
//=================================================================================

/// an interface for querying the hardware specifics of a computer system
//class IdeMachine
DE3D_INTERFACE_(IdeMachine)
{
public:
   virtual ~IdeMachine()  {};

   virtual deBoolean GetCreationResult(void) = 0;
   /// retrieve filled information struct regarding the computer system
   virtual const deSystemInfo * GetSystemInfo() = 0;
};



//=================================================================================
// Destiny System Configuration Analyzer Interface Factory
//=================================================================================

	DEMACHINE_API IdeMachine *GetIdeMachineInterface();
typedef IdeMachine* (*fGetIdeMachineInterface)();


#endif
#endif  //End DEMACHINE_HPP

