#ifndef _D3D9_RENDERER_IMPL_H_
#define _D3D9_RENDERER_IMPL_H_

#ifdef WIN32

#include "Renderer_Impl.h"

#include "D3D9_Common.h"
#include "D3D9_Overlay.h"

namespace videonext { namespace media {

class D3D9_Render_Impl : public Renderer_Impl
{
public:
    
    D3D9_Render_Impl();

    virtual ~D3D9_Render_Impl(void);


public: // redefined virtual functions from Renderer_Impl

    virtual int init(void* window_handle);

    virtual VN_PLAYER_PIXEL_FORMAT get_preferred_pixel_format() const;
    
    virtual int process(const vn_player_frame_t *frame);
    
    virtual int draw(Image_Fill_Mode mode, Image_Calibration *ic, Image_Pan_Zoom *pz);
    
private:
    HRESULT get_present_params(D3DPRESENT_PARAMETERS* params, BOOL bWindowed);

    HRESULT create_resources();

    HRESULT destroy_resources();

    HRESULT setup_matrices();

    HRESULT create_render_target();
    
    HRESULT check_format_conversion(D3DFORMAT format) const;

    HRESULT create_video_surface(int width, int height);

    HRESULT fill_buffer(BYTE* pY, BYTE* pV, BYTE* pU);

    HRESULT check_device();

    HRESULT create_scene();

    HRESULT present();

    HRESULT apply_world_view_proj(LPCSTR matrixName);

    HRESULT set_pixel_shader(int pixelShaderName, LPCSTR entryPoint, LPCSTR shaderModel, LPSTR* ppError);

    HRESULT set_pixel_shader(DWORD* buffer);

    HRESULT set_pixel_shader_constant(LPCSTR name, LPVOID value, UINT size);
        
    HRESULT set_pixel_shader_vector(D3DXVECTOR4* vector, LPCSTR name);

    HRESULT set_pixel_shader_matrix(D3DXMATRIX* matrix, LPCSTR name);

    
    HRESULT set_vertex_shader(int vertexShaderName, LPCSTR entryPoint, LPCSTR shaderModel, LPSTR* ppError);

    HRESULT set_vertex_shader(DWORD* buffer);

    HRESULT set_vertex_shader_constant(LPCSTR name, LPVOID value, UINT size);

    HRESULT set_vertex_shader_vector(D3DXVECTOR4* vector, LPCSTR name);

    HRESULT set_vertex_shader_matrix(D3DXMATRIX* matrix, LPCSTR name);

    void apply_aspect_ratio(RECT& rendertTargetArea, FLOAT frameWidth, FLOAT frameHeight);

    void parse_metadata(const vn_player_frame_t *frame);
    
    void destroy();
    
private:
    HWND hwnd_;

    LPDIRECT3D9             d3d9_;
    LPDIRECT3DDEVICE9       device_;
    LPDIRECT3DSURFACE9      offscreen_surface_;
    unsigned char *         offscreen_surface_mem_;
    LPDIRECT3DSURFACE9      texture_surface_;
    LPDIRECT3DTEXTURE9      texture_;
    LPDIRECT3DVERTEXBUFFER9 vertex_buffer_;
    LPDIRECT3DVERTEXSHADER9 vertex_shader_;
    LPDIRECT3DPIXELSHADER9  pixel_shader_;

    ID3DXConstantTable      *vertex_constant_table_;
    ID3DXConstantTable      *pixel_constant_table_;

    D3DDISPLAYMODE display_mode_;
    int video_width_;
    int video_width_visible_;
    int video_height_;
    int window_width_;
    int window_height_;
    D3DFORMAT pixel_format_;
    
    Image_Fill_Mode fill_mode_;
    D3DPRESENT_PARAMETERS present_params_;

    Image_Calibration ic_;
    Image_Pan_Zoom pz_;

    D3D9_Overlay_Store overlays_;

};

}}

#endif /* WIN32 */

#endif /* _D3D9_RENDERER_IMPL_H_ */

