#ifndef _BUFFER_H_
#define _BUFFER_H_

#include <string.h>

typedef unsigned int addr_t;


class Buffer
{

public:

	//provide Buffer parameters to the Buffer constructor
	
	Buffer(){}
	~Buffer(){};

	void reset()
	{
		base_address = 0xFFFFFFFF;
		rstDirty();
		rstData();
		rstValid();
	}

	void init(unsigned int size)
	{
		buffer_size		= size;
		data			= new int[size];
		reset();
	}

	int getBaseAddress()
	{
		return base_address;
	}

	void setBaseAddress(addr_t baseAddress)
	{
		base_address = baseAddress;
	}

	bool lookup(addr_t address)
	//check if address is in buffer
	{
		addr_t aligned_address = address - address %(sizeof(int)*buffer_size);
		return (base_address == aligned_address);
	}

	int * getData()
	//get the address of first value in Buffer
	{
		return data;
	}

	int * rData(addr_t address)
	//read Buffer at a specific address
	{
		//get index of block in set
		int index = getIndex(address);
		return (data + index);
	}

	void wData(int * new_data, bool _dirty)
	//Replace the whole Buffer
	{
		memcpy(data, new_data, buffer_size*sizeof(int));
		dirty = _dirty;
	}
	
	void rstData()
		//set all data to 0
	{
		memset(data, 0x0, buffer_size*sizeof(int)); 
	}

	void rstDirty()
		//reset dirty
	{
		dirty = false; 
	}

	void rstValid()
		//reset dirty
	{
		valid = false; 
	}

	void setDirty()
		//set dirty
	{
		dirty = true;
	}

	void setValid(bool v)
		//set dirty
	{
		valid = v;
	}

	bool isDirty()
		//return dirty
	{
		return dirty;
	}

	bool isValid()
		//return dirty
	{
		return valid;
	}
	


protected :

	addr_t base_address;	
	int * data;
	bool dirty;
	bool valid;	
	unsigned int buffer_size;


	unsigned int getIndex(addr_t address)
	{
		return ((address % (buffer_size*sizeof(int)))/sizeof(int));
	}

};

#endif
