#pragma once

#include <windows.h>

#include <d3d8.h>
#include <d3dx8.h>
#include <dsound.h>

#include <map>
#include <set>

#include "TextureSection.h"
#include "GameState.h"
#include "LDTypes.h"
#include "OggDSound.h"



class LDApp
{

  public:

    typedef std::map<char,tTextureSection>    tMapLetters;


    IDirect3D8*           m_pd3d;

    IDirect3DDevice8*     m_pd3dDevice;

    IDirect3DTexture8*    m_pTextureFont;
    IDirect3DTexture8*    m_pTextureFX;
    IDirect3DTexture8*    m_pTextureMetal;
    IDirect3DTexture8*    m_pTextureUnits;
    IDirect3DTexture8*    m_pTexturePipette;
    IDirect3DTexture8*    m_pTextureTitle;

    std::set<IDirect3DTexture8*>    m_LoadedTextures;

    ID3DXFont*            m_pFont;

    IDirectSound*         m_pDirectSound;

    IDirectSoundBuffer*   m_pSound[LD::SOUND_LAST_ENTRY];

    D3DPRESENT_PARAMETERS m_d3dPP;

    tMapLetters           m_mapLetters;

    HWND                  m_hWnd;

    HICON                 m_hIcon;

    DWORD                 m_dwLastTicks;

    tTextureSection       m_TexSec[LD::TEX_LAST_ENTRY];

    CGameState*           m_pCurrentGameState;

    CGameState*           m_pNextState;

    CDirectSoundOgg       m_Music;

    bool                  m_bKeyPressed[256];
    bool                  m_bKeyReleased[256];

    float                 m_fWavyTextTimeCount;

    int                   m_MouseX;
    int                   m_MouseY;
    int                   m_MouseButtons;

    bool                  m_FullScreen;

    WINDOWPLACEMENT       m_WPLWindowed;
    POINT                 m_WindowPosWindowed;


    LDApp();
    ~LDApp();


    void                  RenderTextureSection2d( int iX, int iY,
                                                const tTextureSection& TexSection,
                                                DWORD dwColor = 0xffffffff,
                                                DWORD dwColor2 = 0,
                                                DWORD dwColor3 = 0,
                                                DWORD dwColor4 = 0,
                                                int iWidth = -1, int iHeight = -1,
                                                DWORD dwAlternativeFlags = 0 );
    void                  RenderTextureSectionAsTile2d( int iX, int iY,
                                                      const tTextureSection& TexSection,
                                                      DWORD dwColor = 0xffffffff );
    void                  RenderTextureSectionRotated2d( int iX, int iY,
                                                       const tTextureSection& TexSection,
                                                       float fAngle,
                                                       DWORD dwColor = 0xffffffff,
                                                       DWORD dwColor2 = 0,
                                                       DWORD dwColor3 = 0,
                                                       DWORD dwColor4 = 0,
                                                       int iWidth = -1, int iHeight = -1,
                                                       DWORD dwAlternativeFlags = 0 );
    void                  RenderQuad2d( int iX, int iY, int iWidth, int iHeight,
                                      float fTU1, float fTV1,
                                      float fTU2, float fTV2,
                                      float fTU3, float fTV3,
                                      float fTU4, float fTV4,
                                      DWORD dwColor,
                                      DWORD dwColor2 = 0,
                                      DWORD dwColor3 = 0,
                                      DWORD dwColor4 = 0 );
    void                  RenderQuad2d( int iX, int iY, int iWidth, int iHeight,
                                      DWORD dwColor,
                                      DWORD dwColor2 = 0,
                                      DWORD dwColor3 = 0,
                                      DWORD dwColor4 = 0 );
    void                  RenderQuadRotated2d( int iX, int iY, int iWidth, int iHeight,
                                             float fTU1, float fTV1,
                                             float fTU2, float fTV2,
                                             float fTU3, float fTV3,
                                             float fTU4, float fTV4,
                                             float fAngle,
                                             DWORD dwColor,
                                             DWORD dwColor2 = 0,
                                             DWORD dwColor3 = 0,
                                             DWORD dwColor4 = 0 );

    void                  RenderQuad( const D3DXVECTOR3& V1,
                                      const D3DXVECTOR3& V2,
                                      const D3DXVECTOR3& V3,
                                      const D3DXVECTOR3& V4,
                                      float fTU1, float fTV1,
                                      float fTU2, float fTV2,
                                      float fTU3, float fTV3,
                                      float fTU4, float fTV4,
                                      DWORD dwColor,
                                      DWORD dwColor2 = 0,
                                      DWORD dwColor3 = 0,
                                      DWORD dwColor4 = 0 );
    void                  RenderTextureSection( const D3DXVECTOR3& V1,
                                                const D3DXVECTOR3& V2,
                                                const D3DXVECTOR3& V3,
                                                const D3DXVECTOR3& V4,
                                                const tTextureSection& TexSection,
                                                DWORD dwColor,
                                                DWORD dwColor2 = 0,
                                                DWORD dwColor3 = 0,
                                                DWORD dwColor4 = 0 );

    void                  Print( int iX, int iY, const char* szText, DWORD dwColor = 0xffffffff );
    void                  PrintNice( int iX, int iY, const char* szText, DWORD dwColor = 0xffffffff );
    void                  PrintNiceCentered( int iX, int iY, const char* szText, DWORD dwColor = 0xffffffff, bool bWavy = false );
    void                  PrintNiceRightAligned( int iX, int iY, const char* szText, DWORD dwColor = 0xffffffff );
    void                  PrintNiceCenteredWavy( int iX, int iY, const char* szText, DWORD dwColor = 0xffffffff );

    IDirect3DTexture8*    LoadTexture( const char* szFileName, DWORD dwColorKey = 0 );
    IDirectSoundBuffer*   LoadWave( const char* szFileName );

    static LRESULT        StaticWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
    LRESULT               WindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );

    void                  RenderFrame();
    void                  UpdateFrame( const float fElapsedTime );

    void                  NextState( CGameState* pNewState );

    void                  Run();

    void                  LoadResources();
    void                  UnloadResources();
    void                  Load3dResources();
    void                  Unload3dResources();

    void                  PlaySound( LD::SoundTypes Sound );
    void                  LoopSound( LD::SoundTypes Sound );
    void                  StopSound( LD::SoundTypes Sound );

    void                  RenderButton( int X, int Y, int W, int H, LD::TextureTypes Tex1, LD::TextureTypes Tex2, LD::TextureTypes Tex3 );

    void                  ToggleWindowMode();

};


extern LDApp    theApp;

