#ifndef AVIFILE_AVIMEDIAREADSTREAM_H
#define AVIFILE_AVIMEDIAREADSTREAM_H

#include "Cache.h"
#include <ReadHandlers.h>
#include <cstring>

class AviMediaReadHandler;

class AviMediaReadStream : public IMediaReadStream
{
friend class AviMediaReadHandler;
protected:
    AVIStreamHeader m_Header;
    AviMediaReadHandler* m_pParent;
    mutable StreamInfo m_StreamInfo;
    std::vector<AVIINDEXENTRY2> m_Index;
    char* m_pcFormat;
    size_t m_uiFormatSize;
    int m_iId;
    framepos_t m_uiPosition;
    framepos_t m_uiChunk;
    framepos_t m_uiReadPosition;
    AviMediaReadStream(AviMediaReadHandler* parent);
    framepos_t find(framepos_t iSample) const;
public:
    AviMediaReadStream() :m_pcFormat(0){}//for vector
    AviMediaReadStream(const AviMediaReadStream& c);
    virtual ~AviMediaReadStream();

    AviMediaReadStream& operator=(const AviMediaReadStream& c)
    {
	m_Header = c.m_Header;
	m_pParent = c.m_pParent;
	m_Index = c.m_Index;
	delete[] m_pcFormat;
	m_pcFormat = 0;
	if (c.m_pcFormat)
	{
	    m_pcFormat = new char[c.m_uiFormatSize];
	    m_uiFormatSize = c.m_uiFormatSize;
	    std::memcpy(m_pcFormat, c.m_pcFormat, m_uiFormatSize);
	}
	m_iId = c.m_iId;
	m_uiPosition = c.m_uiPosition;
	m_uiReadPosition = c.m_uiReadPosition;
	m_uiChunk = c.m_uiChunk;
        return *this;
    }

    virtual double CacheSize() const;
    virtual void ClearCache();

    //virtual HRESULT GetHeader(AVIStreamHeader* pheader) const;
    virtual HRESULT GetHeader(void* pheader, size_t size) const;
//    virtual HRESULT Info(AVISTREAMINFO *pasi, int lSize) const;
    virtual framepos_t GetPos() const;
    virtual framepos_t GetPrevKeyFrame(framepos_t lFrame = ERR) const;
    virtual framepos_t GetNextKeyFrame(framepos_t lFrame = ERR) const;
    virtual framepos_t GetNearestKeyFrame(framepos_t lFrame = ERR) const;
    virtual unsigned int GetLength() const;
    virtual double GetLengthTime() const;
    virtual StreamInfo* GetStreamInfo() const;

    virtual double GetSampleTime(framepos_t lSample = ERR) const;
    virtual size_t GetSampleSize() const { return m_Header.dwSampleSize; }
    virtual fourcc_t GetFourCC() const { return m_Header.fccType; }
    virtual HRESULT GetFormatSize(size_t *plSize) const;
    virtual HRESULT GetFormat(void *pFormat, size_t *plSize) const;
    virtual bool IsKeyFrame(framepos_t lFrame = ERR) const;
    virtual HRESULT Read(size_t lSamples, void *lpBuffer, size_t cbBuffer,
			 size_t *plBytes, size_t *plSamples);
    virtual HRESULT Seek(framepos_t pos);
    virtual HRESULT SeekTime(double time);
    virtual HRESULT SeekToPrevKeyFrame() { return Seek(GetPrevKeyFrame()); }
    virtual HRESULT SkipFrame() { return Seek(GetPos()+1); }
    virtual HRESULT SkipTo(double pos) { return SeekTime(pos); }
};

#endif // AVIFILE_AVIMEDIAREADSTREAM_H
