#ifndef AVIFILE_AVIREADSTREAM_H
#define AVIFILE_AVIREADSTREAM_H

#include "avifile.h"
#include "ReadHandlers.h"

class AviReadFile;

class AviReadStream : public IAviReadStream
{
    friend class AviReadFile;

protected:
    IMediaReadStream* m_pIStream;
    AVIStreamHeader m_header;
    streamid_t m_id;
    char* m_format;
    unsigned int m_format_size;
    Unsigned m_ch_off;//chunk offset for streams with fixed sample size
    int m_iEof;
    char* rem_buffer;
    size_t rem_size;
    size_t rem_limit;
    StreamType m_StreamType;
public:
    //AviReadStream-specific
    AviReadStream(streamid_t id, IMediaReadStream* stream);
    ~AviReadStream();
    //Generic     const AVIStreamHeader&
    virtual StreamType GetType() const;
    virtual HRESULT GetHeader(void* pheader, size_t n) const;
    virtual HRESULT GetAudioFormatInfo(void* bi, char** ext) const;
    virtual HRESULT GetVideoFormatInfo(void* bi, size_t size) const;
    virtual IVideoDecoder* GetDecoder() const;
    //Size of stream and one frame
    virtual framepos_t GetLength() const { return m_header.dwLength; }
    virtual double GetLengthTime() const;
    virtual HRESULT GetFrameFlags(int* flags) const;
    virtual double GetFrameTime() const { return (double)m_header.dwScale / m_header.dwRate; }
    virtual framepos_t GetPos() const;
    virtual StreamInfo* GetStreamInfo() const;
    virtual double GetTime(framepos_t frame = ERR) const;
    //Positioning in stream
    virtual HRESULT Seek(framepos_t pos);
    virtual HRESULT SeekTime(double pos);
    virtual framepos_t SeekToKeyFrame(framepos_t pos);
    virtual double SeekTimeToKeyFrame(double pos);
    virtual HRESULT SkipFrame();
    virtual HRESULT SkipTo(double pos);
    virtual bool DropFrame() const;

    //Reading decompressed data
    virtual HRESULT SetDirection(bool d){return -1;}
    virtual HRESULT SetOutputFormat(void* bi, size_t size);
    virtual HRESULT ReadFrame(bool render = true);
    virtual CImage* GetFrame(bool readframe = false);
    virtual unsigned int GetFrameSize() const;

    HRESULT ReadFrames(void* buffer, size_t bufsize, size_t samples,
		       size_t& samples_read, size_t& bytes_read);
    HRESULT ReadDirect(void* buffer, size_t bufsize, size_t samples,
		       size_t& samples_read, size_t& bytes_read);

    virtual framepos_t GetNextKeyFrame(framepos_t frame = ERR) const;
    virtual framepos_t GetPrevKeyFrame(framepos_t frame = ERR) const;

    virtual framepos_t SeekToNextKeyFrame();
    virtual framepos_t SeekToPrevKeyFrame();

    virtual bool Eof() const;

    virtual double CacheSize() const {return m_pIStream->CacheSize();}
};

#endif
