#ifndef AVIFILE_ASFNETWORKINPUTSTREAM_H
#define AVIFILE_ASFNETWORKINPUTSTREAM_H

#include "AsfInputStream.h"
#include "NetworkIterator.h"
//#include <list>
#include <pthread.h>

//class NetworkIterator; // used in template
class ASX_Reader;

enum Content
{
    Live,
    Prerecorded,
    Redirect,
    Unknown
};

class ASFNetworkInputStream: public ASFInputStream
{
friend class NetworkIterator;
    static const char* m_pcFirstRequest;
    static const char* m_pcSeekableRequest;
    static const char* m_pcLiveRequest;
protected:
    ASX_Reader* m_pReader;
    std::list<NetworkIterator*> m_Iterators;
    std::list<packet*> m_Cache;
    int64_t m_lRequest;
    pthread_t m_Thread;
    std::string m_File, m_Server, m_Filename;
    std::string m_Proxyhost;
    std::string m_Proxyport;
    bool m_bQuit;
    bool m_bHeadersValid;
    bool m_bFinished;
    bool m_bWaiting;
    mutable pthread_mutex_t m_Mutex;
    mutable pthread_cond_t m_Cond;
//    mutable pthread_mutex_t _cond_mutex;
//    mutable bool _interrupt;  //'true' interrupts any client call that is
		    // waiting for data to arrive
    int m_piPipe[2];     //message on this pipe interrupts main reading
		    // thread
    Content m_Ctype;
    int m_iTime;
    char *m_pcReadbuffer;

    int m_iRedirectSize;
public:
    ASFNetworkInputStream(const char* pszFile);
    virtual ~ASFNetworkInputStream();
    virtual const MainASFHeader& getHeader() const;
    virtual const std::vector<ASFStreamHeader>& getStreams() const;
    virtual Iterator* getIterator(int id);
//    virtual packet GetPacket(int64_t id, bool& success);
    virtual void interrupt();
    virtual double cacheSize() const;
    virtual void clear();
    virtual bool isLocal() { return false; }
    virtual bool isOpened() { return m_bHeadersValid; }
    virtual bool isValid();
    virtual bool isRedirector() { return (bool)m_pReader; }
    virtual bool getURLs(std::vector<std::string>& urls);
protected:
    static void* threadStarter(void*);
    void* threadFunc();
    int createSocket(int port = 80);
    bool checkContent(int fd, const char* request, Content& ctype);
    bool readContent(int fd);
    bool readRedirect(int fd);
    int read(int fd, void* buffer, int size);
    void recheck(); //purges stale entries from cache
    void seekInternal(int time, NetworkIterator* requester);
    void unregister(NetworkIterator* requester);
    void flushPipe();
};

#endif // AVIFILE_ASFNETWORKINPUTSTREAM_H
