#include <unistd.h>
#include <vector>
#include <list>
#ifndef BUFFEREDFILE_H
/**
 * Include Symbol
 */
#define BUFFEREDFILE_H
/**
 * used to set wait
 * or to set read or write status
 */
#define BUFFER_READ 0
/**
 * used to set wait
 * or to set read or write status
 */
#define BUFFER_WRITE 1
/**
 * A String associated with a size and an index of the data already read.
 */
struct CharAndSize {
	char * data;
	int size;
	int alreadyRead;
} typedef CharAndSize;

/**
 * The BufferedFile class acts like a stack buffered file.
 * You can push data back onto the stack and consecutive reads will read it.
 * BufferedFiles are created from BufferedFileFactories so that the factory can detect if the file descriptor
 * can read or written to.
 */
class BufferedFile {
	public:
	/**
	 * Make a new BufferedFile using fdesc as the file descriptor
	 * */
	BufferedFile(int fdesc);
	/**
	 * Default constructor.
	 * */
	BufferedFile();
	/**
	 * Destructor, closes the file if nessecary.
	 * */
	~BufferedFile();
	/**
	 * Reads size bytes into data from the file
	 * */
	int Read(char * data, int size);
	/**
	 * Writes size bytes from data to the file
	 * */
	int Write(const char * data, int size);
	/**
	 * returns the file handle of the BufferedFile
	 * */
	int getFileHandle();
	/**
	 * close the file descriptor.
	 * */
	void Close();
	/**
	 * Push size bytes of data back onto the BufferedFile stack.
	 * */
	void pushBack(char * data, int size);
	/**
	 * Can we read without blocking?
	 * */
	bool readReady();
	/**
	 * Can we write without blocking?
	 * */
	bool writeReady();
	/**
	 * sets the current wait for the ready call
	 * */
	void setWait(int w);
	/**
	 * gets the current wait value
	 * */
	int getWait();
	/**
	 * Blocks for wait time checking if the file is readable or writable
	 * */
	bool ready(int rw);
	/**
	 * sets the files status for nonblocking writes
	 * */
	void setWriteReady(bool b);
	/**
	 * sets the files status for nonblocking reads.
	 * */
	void setReadReady(bool b);
	/**
	 * sets the BufferedFileFactory parent that will be called on destruction
	 * */
	void setBufferedFileFactory(void * parent);
	/**
	 * sets the file to writeonly, informs parent factory.
	 * */
	void setWriteOnly();
	/**
	 * sets the file to readonly, informs parent factory.
	 * */
	void setReadOnly();
	/**
	 * sets the file to read and write, informs parent factory.
	 * */
	void setReadWrite();
	/**
	 * Has the file been written to since the last the last setWriteReady
	 * */
	bool hasBeenWritten();
	/**
	 * Has the file been read to since the last the last setReadReady
	 * */
	bool hasBeenRead();
	/**
	 * Can this file write? (notnessecarily now).
	 * */
	bool doesWrite();
	/**
	 * Can this file read? (notnessecarily now).
	 * */
	bool doesRead();
	/**
	 * Has this file been closed?
	 * */
	bool isClosed();
	private:
	void setParentRW();
	bool reading;
	bool writing;
	int timeToWait; //This is in microseconds
	int fd;
	list<CharAndSize *> pushBackBlocks;
	//Don't destroy tell parent to remove
	void * parent;
	bool preadReady;
	bool pwriteReady;
	bool hasWritten;
	bool hasRead;
};
#endif
