#ifndef INCLUDED_BOBCAT_SHAREDBUF_
#define INCLUDED_BOBCAT_SHAREDBUF_

#include <ios>
#include <streambuf>

#include <bobcat/sharedmemory>
#include <bobcat/sharedcondition>

namespace FBB
{

class SharedBuf: public std::streambuf, public virtual SharedEnum__
{
    std::ios::openmode d_openMode;
    std::ios::openmode d_currentMode;       // initially openMode, thereafter
                                            // either ::in or ::out
    SharedMemory d_memory;

    public:
        SharedBuf();                                      // 1

        SharedBuf(
                size_t maxSize, SizeUnit sizeUnit,              // 2
                std::ios::openmode openMode = std::ios::in | std::ios::out,
                size_t access = 0600);

        SharedBuf(                                        // 3
                int id,
                std::ios::openmode openMode = std::ios::in | std::ios::out);

        void clear();                   // clear all existing data and reduce
                                        // until only the segment at 
                                        // d_sharedData

        int id() const;                 // id of the shared Memory segment

        void kill();                    // kill all shared segments w/o locks
                                        // the object is unusable hereafter

        void memInfo(std::ostream &out) const;

        void remove();                  // remove all shared segments.
                                        // the object is unusable hereafter

        void setMemory(SharedMemory &&tmp);

    protected:
        SharedCondition attachSharedCondition(std::ios::off_type offset = 0,
                        std::ios::seekdir way = std::ios::beg);
        SharedCondition createSharedCondition();
        void setOpenMode(std::ios::openmode openMode);        
        SharedMemory &sharedMemory();
        
    private:
        bool mode(std::ios::openmode flag);

        int pbackfail(int ch) override;
        std::streamsize showmanyc() override;
        int underflow() override;
        std::streamsize xsgetn(char *buf, std::streamsize n) override;
  
        int overflow(int c) override;
        std::streamsize xsputn(char const *buf, std::streamsize n) override;

        std::ios::pos_type seekoff(
            std::ios::off_type offset, 
            std::ios::seekdir way = std::ios::beg,
            std::ios::openmode mode = std::ios::in | std::ios::out) override;

        std::ios::pos_type seekpos(
            std::ios::pos_type offset, 
            std::ios::openmode mode = std::ios::in | std::ios::out) override;
};

#include "clear.f"
#include "id.f"
#include "kill.f"
#include "meminfo.f"
#include "remove.f"
#include "setmemory.f"
#include "setopenmode.f"
#include "sharedmemory.f"

} // FBB        
#endif
