// stdafx.h : include file for standard system include files,
//  or project specific include files that are used frequently,
//  but are changed infrequently
//

#pragma once


// Change these values to use different versions
#ifndef _WIN32_WINNT
#define _WIN32_WINNT    0x0500
#endif
#define _WIN32_IE       0x0400

#define __USE_COM__


#include "Tools.h"
#include "VRDefs.h"

#if _M_IX86 > 400
    #error Due to CPU detection reason this should be compiled with /G4 option
#endif


#include <ddraw.h>
#include <shellapi.h>
#include <atlbase.h>
#include <atlapp.h>


#if defined(__USE_COM__)

BIND_IID(IDirectDraw,  "6C14DB80-A733-11CE-A521-0020AF0BE560");
BIND_IID(IDirectDraw4, "9c59509a-39bd-11d1-8c4a-00c04fd930c5");
BIND_IID(IDirectDraw7, "15e65ec0-3b9c-11d2-b92f-00609797ea5b");

#endif


typedef CSimpleArray<DISPLAYINFO>   CDisplayModeList;

typedef struct
{
    DWORD features;
    DWORD ext_features;
    DWORD processor;
    char  vendor[16];
    char  namestr[48];
    DWORD cache_l1[4];
    DWORD cache_l2[4];
} CPUDETECT, *LPCPUDETECT;

typedef struct
{
    BYTE logo;
    BYTE id;
    LPCTSTR name;
} BRANDTABLE;

//class CSetupDlg;        // forward references

// We should derive CMessageLoop class in order to 
// override idle processing
class CAppMessageLoop : public CMessageLoop
{
    BOOL OnIdle(int /*nIdleCount*/)
    {
        for (int i=0; i < m_aIdleHandler.GetSize(); i++)
        {
            CIdleHandler* pIdleHandler = m_aIdleHandler[i];
            if(NULL != pIdleHandler)
                if (!pIdleHandler->OnIdle())
                    return FALSE;       // stop idle process
        }
        return TRUE;
    }
};


// You may derive a class from CAppModule and use it if you want to override
// something, but do not change the name of _Module
//
class CExeModule 
    : public CAppModule
    , public CMessageFilter
    , public CIdleHandler
{
public:
    virtual ~CExeModule();

    HRESULT LoadPreferences(void);

    HRESULT Initialize(HWND);
    HRESULT Terminate(void);
    LRESULT ProcessMessage(UINT, WPARAM, LPARAM);
    int Run(LPTSTR /*lpstrCmdLine*/ = NULL, int nCmdShow = SW_SHOWDEFAULT);
    int Setup(void);
    virtual BOOL PreTranslateMessage(MSG* pMsg);
    virtual BOOL OnIdle(void);

    DWORD GetTickCount(void);
    HRESULT Error(LPCTSTR pText, HRESULT hr);
    HRESULT Error(LPCTSTR pText);

    HRESULT GetCpuFrequency(UINT *value, bool flag = false);
    HRESULT GetCpuCaps(UINT cap, UINT *value);
    HRESULT GetDisplayModeList(void);
    DATABUNDLE& GetData(void) { return m_db; }
    LPRESULTS GetLastResult(void);
    LPRESULTS GetResults(void) { return (m_IsResults) ? m_res : NULL; }

private:
    int CpuDetectHelper(LPCPUDETECT pcd);
    void ParseIntelDescriptors(int *cache_l1, int* cache_l2);
    HRESULT DisplaySystemVersion(void);
    static HRESULT WINAPI EnumModesCallback(LPDDSURFACEDESC2, void*);
    static int SortModesCallback(const void *arg1, const void *arg2);

public:
    int m_IsSplash;
    int m_IsResource;
    int m_SelPageNum;
    int m_ScreenMode;
    int m_ModelIndex;

    static CPUDETECT m_cd;
    CDisplayModeList m_dml;         // display mode list

    UINT m_CpuFrequency;
    UINT m_IsMMX;
    UINT m_IsEMMX;
    UINT m_IsSSE;
    UINT m_IsSSE2;
    UINT m_MemTotalPhys;
    UINT m_MemAvailPhys;

    static LPTSTR m_szOsInfo;
    static LPTSTR m_szCpuInfo;

private:
    HWND m_hWnd;
    HMODULE m_hTask;
    IObject* m_TaskObject;

    bool m_IsInitialized;
    bool m_IsTestStarted;
    bool m_IsResults; 

    DATABUNDLE m_db;
    RESULTS m_res[4];
};

extern CExeModule _Module;

#define _ATL_USE_CSTRING_FLOAT

#include <atlwin.h>
#include <atldlgs.h>
#include <atlctrls.h>
#include <atlctrlx.h>
#include <atlmisc.h>
#include <fstream.h>
#include "Ddx.h"

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

