// DUiMan.h: interface for the CDUiMan class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_DUiMan_H__EEE02245_D467_11D4_B688_004033A4E3E4__INCLUDED_)
#define AFX_DUiMan_H__EEE02245_D467_11D4_B688_004033A4E3E4__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <windows.h>

#ifdef DUIMAN_EXPORTS
    #define DUIMAN_API __declspec(dllexport)
#else 
    #define DUIMAN_API __declspec(dllimport)
#endif
    
class CDUiMan;
class CDUiObject;
class CDUiListBox;
class CDUiEditBox;
class CDUiButton;
class CDUiWindow;
class CDUiText;
class CDUiObjectList;
class CDUiWave;
class CDUiFont;
class CDUiGraphic;

struct IDirectDraw;
struct IDirectDrawSurface;
struct IDirectSound;
struct IDirectSoundBuffer;

#define _565(_r,_g,_b) ((((_r)&0x1f)<<11)|(((_g)&0x3f)<<5)|((_b)&0x1f))
#define _555(_r,_g,_b) ((((_r)&0x1f)<<10)|(((_g)&0x1f)<<5)|((_b)&0x1f))

typedef enum _DUIOBJECT_TYPES
{
    DUI_OBJECT,
    DUI_WINDOW,
    DUI_LISTBOX,
    DUI_EDITBOX,
    DUI_GRAPHIC,
    DUI_BUTTON,
    DUI_TEXT,
    DUI_WAVE,
    DUI_FONT
} DUIOBJECT_TYPES;

// Message defines
#ifndef DUI_MESSAGE_BASE
#define DUI_MESSAGE_BASE (WM_USER+400)
#endif

#define DUIM_ENTER                      (DUI_MESSAGE_BASE + 1)
#define DUIM_LISTBOX_SELCHANGE          (DUI_MESSAGE_BASE + 101)

// MACRO wrappers
#define HANDLE_DUIM_ENTER(a,b)              if (wParam == (DWORD)a) { b(); }
#define HANDLE_DUIM_LISTBOX_SELCHANGE(a,b)  if (wParam == (DWORD)a) { b(); }

// Style defines
#define DUIS_LISTBOX_ALLOW_CLEAR        0x00000001

BOOL DUIMAN_API IsPrintable(UINT nChar);
// dwFadeAmount can be from 1 to 31
DWORD DUIMAN_API GetFadeColor(DWORD dwSourceColor, DWORD dwFadeAmount);
DWORD DUIMAN_API ColorToColorRef(DWORD dwSourceColor);
BOOL  DUIMAN_API GetOutlineRect(CDUiObject *pObject, RECT *pRect);

extern CDUiMan *g_pDUiManager;

class DUIMAN_API CDUiMan  
{
public:
	CDUiMan();
	virtual ~CDUiMan();

    DWORD   Initialize(HINSTANCE hInstance, HWND hWnd);

    void    UpdateFrame();

    void    DisplayDebugErrorf(WCHAR *wszMessage, ...);
    void    DisplayDebugDataf(WCHAR *wszMessage, ...);

    DWORD   GetLastError() { return m_dwLastError; };


    CDUiWave *CreateDUiWave(WCHAR *wszWaveName, WCHAR *wszFileName, DWORD dwMode);
    CDUiFont *CreateDUiFont(WCHAR *wszName, DWORD dwMode);

    CDUiWindow *CreateDUiWindow(WCHAR *wszWindowName, DWORD x, DWORD y, DWORD dwWidth, 
            DWORD dwHeight, DWORD dwStyle);
    BOOL SelectWindow(WCHAR *wszName);
    BOOL SelectWindow(CDUiWindow *pWindow);
    BOOL SelectLastWindow();

    DWORD GetDefaultPrimaryColor() { return m_dwDefaultPrimaryColor; };
    DWORD GetDefaultBackgroundColor() { return m_dwDefaultBackgroundColor; };
    void  GetDefaultFontName(WCHAR *wszFontName) { wcsncpy(wszFontName,m_wszDefaultFontName,31); };
    DWORD GetDefaultFontColor() { return m_dwDefaultFontColor; };
    DWORD GetDefaultSelectOutlineColor() { return m_dwDefaultSelectOutlineColor; };
    DWORD GetDefaultSelectedFontColor() { return m_dwDefaultSelectedFontColor; };
    CDUiFont *GetDefaultFont();
    DWORD GetZOrderCounter() { return m_dwZOrderCounter; };
    
    void  SetDefaultPrimaryColor(DWORD dwDefaultPrimaryColor) { m_dwDefaultPrimaryColor = dwDefaultPrimaryColor; };
    void  SetDefaultBackgroundColor(DWORD dwDefaultBackgroundColor) { m_dwDefaultBackgroundColor = dwDefaultBackgroundColor; };
    void  SetDefaultFontName(WCHAR *wszFontName) { wcsncpy(m_wszDefaultFontName,wszFontName,31); };
    void  SetDefaultFontColor(DWORD dwDefaultFontColor) { m_dwDefaultFontColor = dwDefaultFontColor; };
    void  SetDefaultSelectOutlineColor(DWORD dwDefaultSelectOutlineColor) { m_dwDefaultSelectOutlineColor = dwDefaultSelectOutlineColor; };
    void  SetDefaultSelectedFontColor(DWORD dwSelectedFontColor) { m_dwDefaultSelectedFontColor = dwSelectedFontColor; };
    void  SetZOrderCounter(DWORD dwZOrderCounter) { m_dwZOrderCounter = dwZOrderCounter; };

    BOOL GetNamedObject(WCHAR *wszName, CDUiObject **pObject);

    HWND GetAppHWnd() { return m_hWnd; };
    HINSTANCE GetAppHInstance() { return m_hParentInstance; };
    BOOL GetDC(HDC *phDC);
    IDirectDraw *GetDirectDraw() { return m_pDirectDraw; };
    BOOL IsFontAvailable(WCHAR *wszFontName);
    BOOL GetFirstAvailableFont(WCHAR *wszFontName);

    LRESULT WndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam);

    static int CALLBACK _EnumFontsFunc(LOGFONT *pLogFont, TEXTMETRIC *pMetric, DWORD dwType, LPARAM lpData);
    int EnumFontsFunc(LOGFONT *pLogFont, TEXTMETRIC *pMetric, DWORD dwType);
protected:
    void    SetLastError(DWORD dwErrCode) { m_dwLastError = dwErrCode; };

    BOOL DrawScene();
    void FlipBuffers();

    DWORD m_dwDefaultPrimaryColor;
    DWORD m_dwDefaultBackgroundColor;

    WCHAR m_wszDefaultFontName[32];
    DWORD m_dwDefaultFontColor;
    DWORD m_dwDefaultSelectOutlineColor;
    DWORD m_dwDefaultSelectedFontColor;
    CDUiFont *m_pDefaultFont;

    DWORD m_dwZOrderCounter;


    HINSTANCE           m_hParentInstance;
    HWND                m_hWnd;
    HDC                 m_hDC;

    DWORD               m_dwLastError;

    IDirectDraw         *m_pDirectDraw;
    IDirectDrawSurface  *m_pddsPrimary;
    IDirectDrawSurface  *m_pddsBack;

    IDirectSound        *m_pDirectSound;
    DWORD               m_dwDDSDescriptionCount;

    CDUiObjectList      *m_pWindowList;
    CDUiWindow          *m_pSelectedWindow;

    WCHAR               m_wszLastSelectedWindowName[40];
    BOOL                m_bShowDebugWindow;
    CDUiWindow          *m_pErrorWindow;
    CDUiListBox         *m_pErrorDataList;
    CDUiListBox         *m_pErrorMessageList;

    DWORD               m_dwFontCount;
    WCHAR               m_wszFontNameArray[32][32];
};

class DUIMAN_API CDUiObject  
{
friend CDUiWindow;
friend CDUiMan;
public:
	CDUiObject();
	virtual ~CDUiObject();

    DWORD GetXPosition() { return m_xPos; };
    DWORD GetYPosition() { return m_yPos; };
    DWORD GetHeight() { return m_dwHeight; };
    DWORD GetWidth() { return m_dwWidth; };
    DWORD GetTabOrder() { return m_dwTabOrder; };
    DWORD GetObjectType() { return m_dwObjectType; };
    BOOL  GetVisible() { return m_bVisible; };
    DWORD GetPrimaryColor() { return m_dwPrimaryColor; };
    DWORD GetBackgroundColor() { return m_dwBackgroundColor; };
    DWORD GetTransparency() { return m_dwTransparency; };
    DWORD GetSelectOutlineColor() { return m_dwSelectOutlineColor; };
    CDUiObject *GetParent() { return m_pParent; };
    void  GetName(WCHAR *wszName) { wcsncpy(wszName,m_wszName,19); };
    DWORD GetZOrder() { return m_dwZOrder; };
    DWORD GetStyle() { return m_dwStyle; };

    void SetXPosition(DWORD x) { m_xPos = x; };
    void SetYPosition(DWORD y) { m_yPos = y; };
    void SetHeight(DWORD dwHeight) { m_dwHeight = dwHeight; };
    void SetWidth(DWORD dwWidth) { m_dwWidth = dwWidth; };
    void SetTabOrder(DWORD dwTabOrder) { m_dwTabOrder = dwTabOrder; };
    void SetObjectType(DWORD dwObjectType) { m_dwObjectType = dwObjectType; };
    void SetVisible(BOOL  bVisible) { m_bVisible = bVisible; };
    void SetPrimaryColor(DWORD dwPrimaryColor) { m_dwPrimaryColor = dwPrimaryColor; };
    void SetBackgroundColor(DWORD dwBackgroundColor) { m_dwBackgroundColor = dwBackgroundColor; };
    void SetTransparency(DWORD dwTransparency) { m_dwTransparency = dwTransparency; };
    void SetSelectOutlineColor(DWORD dwSelectOutlineColor) { m_dwSelectOutlineColor = dwSelectOutlineColor; };
    void SetParent(CDUiObject *pParent) { m_pParent = pParent; };
    void SetName(WCHAR *wszName) { wcsncpy(m_wszName,wszName,39); };
    void SetZOrder(DWORD dwZOrder) { m_dwZOrder = dwZOrder; };
    void SetStyle(DWORD dwStyle) { m_dwStyle = dwStyle; };

    virtual DWORD Display(BOOL bRefresh = TRUE);
    virtual DWORD DisplayText(BOOL bRefresh = TRUE);
    virtual DWORD OnKey(UINT nChar, UINT nFlags);
    virtual DWORD OnChar(UINT nChar, UINT nFlags);
    virtual DWORD Initialize();
    virtual DWORD DoFocusChange();
protected:

    DWORD m_xPos;
    DWORD m_yPos;
    DWORD m_dwHeight;
    DWORD m_dwWidth;
    DWORD m_dwTabOrder;
    DWORD m_dwZOrder;

    DWORD m_dwObjectType;

    BOOL  m_bVisible;
    DWORD m_dwPrimaryColor;
    DWORD m_dwBackgroundColor;
    DWORD m_dwTransparency;
    DWORD m_dwSelectOutlineColor;

    DWORD m_dwStyle;

    CDUiObject *m_pParent;
    WCHAR m_wszName[40];

    IDirectDrawSurface *m_pddsMain;
};

class DUIMAN_API CDUiObjectList  
{
friend CDUiMan;
public:
	CDUiObjectList();
	virtual ~CDUiObjectList();

    DWORD AddObject(CDUiObject *pObject);
    DWORD FindObject(CDUiObject *pObject);
    DWORD RemoveObject(CDUiObject *pObject);

    DWORD GetObjectCount() { return m_dwDUiObjectCount; };

    void Reset();
    CDUiObject *GetObject(DWORD dwPos);
    CDUiObject *GetNextObject();

protected:
    CDUiObject **m_pDUiObjects;
    DWORD m_dwDUiObjectCount;
    DWORD m_dwDUiObjectArraySize;

    DWORD m_dwCurrentIndex;
};

class DUIMAN_API CDUiWindow : public CDUiObject  
{
friend CDUiMan;
public:
	CDUiWindow();
	virtual ~CDUiWindow();

    CDUiObject *CreateDUiObject(DWORD dwObjectType, WCHAR *wszWindowName, DWORD x, DWORD y, DWORD dwWidth, 
            DWORD dwHeight, DWORD dwStyle);

    CDUiObject *GetSelectedObject() { return m_pSelectedObject; };

    BOOL GetNamedObject(WCHAR *wszName, CDUiObject **pObject);

    virtual DWORD Display(BOOL bRefresh = TRUE);
    virtual DWORD DisplayText(BOOL bRefresh = TRUE);
    virtual DWORD OnKey(UINT nChar, UINT nFlags);
    virtual DWORD OnChar(UINT nChar, UINT nFlags);
    virtual DWORD DoFocusChange();
protected:
    CDUiObjectList      *m_pObjectList;

    CDUiObject          *m_pSelectedObject;

    DWORD               m_dwNextTabOrder;
};

class DUIMAN_API CDUiListBox : public CDUiObject  
{
friend CDUiMan;
public:
	CDUiListBox();
	virtual ~CDUiListBox();

    DWORD GetFontColor() { return m_dwFontColor; };
    DWORD GetSelectedFontColor() { return m_dwSelectedFontColor; };

    void  SetDUiFont(CDUiFont *pFont) { m_pFont = pFont; };
    void  SetFontColor(DWORD dwFontColor) { m_dwFontColor = dwFontColor; };
    void  SetSelectedFontColor(DWORD dwSelectedFontColor) { m_dwSelectedFontColor = dwSelectedFontColor; };

    DWORD AddString(WCHAR *wszString, DWORD dwData = 0);
    BOOL  GetString(DWORD dwIndex, WCHAR *wszString);
    BOOL  GetData(DWORD dwIndex, DWORD *pdwData);
    DWORD GetSelectedString() { return m_dwSelectedString; };
    void  SetSelectedString(DWORD dwSelectedString) { m_dwSelectedString = dwSelectedString; };
    BOOL  RemoveString(DWORD dwIndex);
    DWORD GetStringCount() { return m_dwStringCount; };

    BOOL  Reset();

    virtual DWORD Display(BOOL bRefresh = TRUE);
    virtual DWORD DisplayText(BOOL bRefresh = TRUE);
    virtual DWORD OnKey(UINT nChar, UINT nFlags);
    virtual DWORD OnChar(UINT nChar, UINT nFlags);
    virtual DWORD Initialize();
protected:

    typedef struct _STRINGINFO
    {
        WCHAR *wszString;
        DWORD dwStringSize;
        DWORD dwData;
    } STRINGINFO;

    STRINGINFO *m_pStrings;
    DWORD m_dwStringCount;
    DWORD m_dwStringArraySize;

    DWORD m_dwFirstVisibleString;
    DWORD m_dwSelectedString;
    DWORD m_dwLineCount;

    DWORD m_dwFontColor;
    DWORD m_dwSelectedFontColor;
    DWORD m_dwFontWidth;
    DWORD m_dwFontHeight;

    CDUiFont *m_pFont;
};

class DUIMAN_API CDUiText  : public CDUiObject
{
friend CDUiMan;
public:
	CDUiText();
	virtual ~CDUiText();

    void  GetText(WCHAR *wszText);
    DWORD GetFontColor() { return m_dwFontColor; };
    DWORD GetSelectedFontColor() { return m_dwSelectedFontColor; };

    void  SetDUiFont(CDUiFont *pFont) { m_pFont = pFont; };
    void  SetText(WCHAR *wszText);
    void  SetFontColor(DWORD dwFontColor) { m_dwFontColor = dwFontColor; };
    void  SetSelectedFontColor(DWORD dwSelectedFontColor) { m_dwSelectedFontColor = dwSelectedFontColor; };

    virtual DWORD Display(BOOL bRefresh = TRUE);
    virtual DWORD DisplayText(BOOL bRefresh = TRUE);
protected:
    CDUiFont *m_pFont;
    DWORD m_dwFontColor;
    DWORD m_dwSelectedFontColor;

    WCHAR *m_wszText;
    DWORD m_dwTextLength;
    DWORD m_dwTextArraySize;
};

class DUIMAN_API CDUiGraphic : public CDUiObject    
{
public:
	CDUiGraphic();
	virtual ~CDUiGraphic();

    void GetGraphicName(WCHAR *wszGraphicName) { wcsncpy(wszGraphicName,m_wszGraphicName,99); };

    void SetGraphicName(WCHAR *wszGraphicName) { wcsncpy(m_wszGraphicName,wszGraphicName,99); };
    void SetDirectDraw(IDirectDraw *pDirectDraw) { m_pDirectDraw = pDirectDraw; };

    virtual DWORD Display(BOOL bRefresh = TRUE);
    virtual DWORD DisplayText(BOOL bRefresh = TRUE);
    virtual DWORD Initialize();
protected:
    IDirectDrawSurface  *m_pDDS;
    IDirectDraw         *m_pDirectDraw;
    WCHAR               m_wszGraphicName[100];

};

class DUIMAN_API CDUiButton  : public CDUiText
{
friend CDUiMan;
public:
	CDUiButton();
	virtual ~CDUiButton();

    virtual DWORD Display(BOOL bRefresh = TRUE);
    virtual DWORD DisplayText(BOOL bRefresh = TRUE);
    virtual DWORD Initialize();
    virtual DWORD OnKey(UINT nChar, UINT nFlags);
protected:
    BOOL    m_bUseGraphic;
    CDUiGraphic *m_pGraphic;
};

class DUIMAN_API CDUiEditBox : public CDUiText //CDUiObject  
{
friend CDUiMan;
public:
	CDUiEditBox();
	virtual ~CDUiEditBox();

    virtual DWORD Display(BOOL bRefresh = TRUE);
    virtual DWORD DisplayText(BOOL bRefresh = TRUE);
    virtual DWORD OnChar(UINT nChar, UINT nFlags);
protected:
    DWORD m_dwCursorPos;
//    DWORD m_dwFontWidth;
//    DWORD m_dwFontHeight;
};

class DUIMAN_API CDUiFont  : public CDUiObject
{
friend CDUiMan;
public:
	CDUiFont();
	virtual ~CDUiFont();

    void  GetFontName(WCHAR *wszFontName) { wcsncpy(wszFontName,m_wszFontName,31); };
    HFONT GetFont() { return m_hFont; };

    void  SetFontName(WCHAR *wszFontName) { wcsncpy(m_wszFontName,wszFontName,31); };

    virtual DWORD Initialize();
protected:
    WCHAR m_wszFontName[32];
    HFONT m_hFont;
};

class DUIMAN_API CDUiWave : public CDUiObject  
{
friend CDUiMan;
public:
	CDUiWave();
	virtual ~CDUiWave();

    void GetClipName(WCHAR *wszClipName) { wcsncpy(wszClipName,m_wszClipName,99); };

    void SetClipName(WCHAR *wszClipName) { wcsncpy(m_wszClipName,wszClipName,99); };

    virtual DWORD Initialize();
    virtual DWORD Play();
    virtual DWORD Stop();
    virtual BOOL  IsPlaying();
protected:
    WCHAR m_wszClipName[100];

    IDirectSoundBuffer  *m_pSoundBuffer;
    IDirectSound        *m_pDirectSound;
};


#endif // !defined(AFX_DUiMan_H__EEE02245_D467_11D4_B688_004033A4E3E4__INCLUDED_)
