#ifndef __AVIPLAYERC_H__
#define __AVIPLAYERC_H__

#include <windows.h>
#include <vfw.h>	// video for windows
#include "PajaTypes.h"


#define	AP_MAKEFOURCC( a, b, c, d ) ( ((PajaTypes::uint32)a) | (((PajaTypes::uint32)b) << 8) | \
									(((PajaTypes::uint32)c) << 16) | (((PajaTypes::uint32)d) << 24)  )

#define AP_FOURCC2Str( fcc, s ) \
{	s[0] = (fcc      ) & 0xFF; \
	s[1] = (fcc >>  8) & 0xFF; \
	s[2] = (fcc >> 16) & 0xFF; \
	s[3] = (fcc >> 24) & 0xFF; \
	s[4] = 0; }

#define RIFF_TAG AP_MAKEFOURCC('R','I','F','F')
#define LIST_TAG AP_MAKEFOURCC('L','I','S','T')
#define AVI_TAG  AP_MAKEFOURCC('A','V','I',' ')
#define AVIH_TAG AP_MAKEFOURCC('a','v','i','h')
#define STRL_TAG AP_MAKEFOURCC('s','t','r','l')
#define STRH_TAG AP_MAKEFOURCC('s','t','r','h')
#define STRF_TAG AP_MAKEFOURCC('s','t','r','f')
#define VIDS_TAG AP_MAKEFOURCC('v','i','d','s')
#define AUDS_TAG AP_MAKEFOURCC('a','u','d','s')
#define DMLH_TAG AP_MAKEFOURCC('d','m','l','h')
#define MOVI_TAG AP_MAKEFOURCC('m','o','v','i')
#define HDRL_TAG AP_MAKEFOURCC('h','d','r','l')
#define IDX1_TAG AP_MAKEFOURCC('i','d','x','1')

#define _00DB_TAG AP_MAKEFOURCC('0','0','d','b')
#define _00IV_TAG AP_MAKEFOURCC('0','0','i','v')
#define _00DC_TAG AP_MAKEFOURCC('0','0','d','c')
#define _01WB_TAG AP_MAKEFOURCC('0','1','w','b')


#define	INDEX_KEYFRAME	0x10


#pragma pack( 1 )	// make sure the structures are the size they've set.

typedef struct {
	DWORD	dwMicroSecPerFrame;
	DWORD	dwMaxBytesPerSec;
	DWORD	dwReserved1;
	DWORD	dwFlags;
	DWORD	dwTotalFrames;
	DWORD	dwInitialFrames;
	DWORD	dwStreams;
	DWORD	dwSuggestedBufferSize;
	DWORD	dwWidth;
	DWORD	dwHeight;
	DWORD	dwReserved[4];
} AVIMainHeaderS;

typedef struct {
    FOURCC	fccType;
    FOURCC	fccHandler;
    DWORD	dwFlags;
    DWORD	dwPriority;
    DWORD	dwInitialFrames;
    DWORD	dwScale;
    DWORD	dwRate;
    DWORD	dwStart;
    DWORD	dwLength;
    DWORD	dwSuggestedBufferSize;
    DWORD	dwQuality;
    DWORD	dwSampleSize;
    RECT	rcFrame;
} AVIStreamHeaderS;

typedef struct {
	DWORD	dwFlags;
	DWORD	dwPos;
	DWORD	dwLength;
} FrameIndexS;

#pragma pack()



class AVIPlayerC
{
public:
	AVIPlayerC();
	virtual ~AVIPlayerC();

	bool	parse_file( PajaTypes::uint8* pData, PajaTypes::uint32 ui32DataSize );

	PajaTypes::uint8*	decompress_frame( PajaTypes::int32 i32Frame );

	PajaTypes::int32	get_width() const;
	PajaTypes::int32	get_height() const;
	PajaTypes::int32	get_bpp() const;
	PajaTypes::int32	get_frames() const;
	PajaTypes::float32	get_fps() const;
	PajaTypes::uint8*	get_data();

private:

	enum DataSeekE {
		DATA_SEEK_SET,
		DATA_SEEK_END,
		DATA_SEEK_CUR
	};

	void	init_read( PajaTypes::uint8* pData, PajaTypes::uint32 ui32DataSize );
	bool	read( void* pBuffer, PajaTypes::int32 i32Size );
	void	seek( PajaTypes::int32 i32Offset, DataSeekE eSeek );
	PajaTypes::int32	get_pos();

	bool	read_chunk_head( PajaTypes::uint32* pID, PajaTypes::uint32* pSize );
	bool	handle_hdrl( AVIMainHeaderS* pMainHdr, AVIStreamHeaderS* pStreamHdr, BITMAPINFOHEADER** pStreamFormat,
							int chunksize, bool& hasvideo );

    AVIMainHeaderS		m_rMainHdr;
	AVIStreamHeaderS	m_rStreamHeader;
    BITMAPINFOHEADER*	m_pStreamFormat;
	BITMAPINFOHEADER*	m_pTargetFormat;
    FrameIndexS*		m_pFrameIndices;

	HIC					m_hIC;

	PajaTypes::uint8*	m_pFrameBuffer;

	PajaTypes::int32	m_i32Width;
	PajaTypes::int32	m_i32Height;
	PajaTypes::int32	m_i32BPP;

	PajaTypes::uint8*	m_pData;
	PajaTypes::uint32	m_ui32DataSize;
	PajaTypes::int32	m_i32DataPointer;

	PajaTypes::int32	m_i32CurFrame;
};


#endif // __AVIPLAYERC_H__