#ifndef _DERINGBUFFER_HPP
#define _DERINGBUFFER_HPP
/*-------------------------------------------------------------------------
 * drawElements C++ Base Library
 * -----------------------------
 *
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Ring buffer template.
 *//*--------------------------------------------------------------------*/

#include "deDefs.hpp"

namespace de
{

void RingBuffer_selfTest (void);

/** Ring buffer template. */
template <typename T>
class RingBuffer
{
public:
			RingBuffer		(int size);
			~RingBuffer		(void);

	void	clear			(void);
	void	resize			(int newSize);

	int		getSize			(void) const	{ return m_size;					}
	int		getNumElements	(void) const	{ return m_numElements;				}
	int		getNumFree		(void) const	{ return m_size - m_numElements;	}

	void	pushFront		(const T& elem);
	void	pushFront		(const T* elemBuf, int count);

	void	peekBack		(T* elemBuf, int count) const;
	T		peekBack		(int offset) const;

	T		popBack			(void);
	void	popBack			(T* elemBuf, int count) { peekBack(elemBuf, count); popBack(count); }
	void	popBack			(int count);

protected:
	int		m_numElements;
	int		m_front;
	int		m_back;

	T*		m_buffer;
	int		m_size;
};

// RingBuffer implementation.

template <typename T>
RingBuffer<T>::RingBuffer (int size)
	: m_numElements	(0)
	, m_front		(0)
	, m_back		(0)
	, m_size		(size)
{
	DE_ASSERT(size > 0);
	m_buffer = new T[m_size];
}

template <typename T>
RingBuffer<T>::~RingBuffer ()
{
	delete[] m_buffer;
}

template <typename T>
void RingBuffer<T>::clear (void)
{
	m_numElements	= 0;
	m_front			= 0;
	m_back			= 0;
}

template <typename T>
void RingBuffer<T>::resize (int newSize)
{
	DE_ASSERT(newSize >= m_numElements);
	T* buf = new T[newSize];

	try
	{
		// Copy old elements.
		for (int ndx = 0; ndx < m_numElements; ndx++)
			buf[ndx] = m_buffer[(m_back + ndx) % m_size];

		// Reset pointers.
		m_front		= m_numElements;
		m_back		= 0;
		m_size		= newSize;

		DE_SWAP(T*, buf, m_buffer);
		delete[] buf;
	}
	catch (...)
	{
		delete[] buf;
		throw;
	}
}

template <typename T>
inline void RingBuffer<T>::pushFront (const T& elem)
{
	DE_ASSERT(getNumFree() > 0);
	m_buffer[m_front] = elem;
	m_front = (m_front + 1) % m_size;
	m_numElements += 1;
}

template <typename T>
void RingBuffer<T>::pushFront (const T* elemBuf, int count)
{
	DE_ASSERT(de::inRange(count, 0, getNumFree()));
	for (int i = 0; i < count; i++)
		m_buffer[(m_front + i) % m_size] = elemBuf[i];
	m_front = (m_front + count) % m_size;
	m_numElements += count;
}

template <typename T>
inline T RingBuffer<T>::popBack ()
{
	DE_ASSERT(getNumElements() > 0);
	int ndx = m_back;
	m_back = (m_back + 1) % m_size;
	m_numElements -= 1;
	return m_buffer[ndx];
}

template <typename T>
inline T RingBuffer<T>::peekBack (int offset) const
{
	DE_ASSERT(de::inBounds(offset, 0, getNumElements()));
	return m_buffer[(m_back + offset) % m_size];
}

template <typename T>
void RingBuffer<T>::peekBack (T* elemBuf, int count) const
{
	DE_ASSERT(de::inRange(count, 0, getNumElements()));
	for (int i = 0; i < count; i++)
		elemBuf[i] = m_buffer[(m_back + i) % m_size];
}

template <typename T>
void RingBuffer<T>::popBack (int count)
{
	DE_ASSERT(de::inRange(count, 0, getNumElements()));
	m_back = (m_back + count) % m_size;
	m_numElements -= count;
}

} // de

#endif // _DERINGBUFFER_HPP
