#ifndef _TCURANDOMVALUEITERATOR_HPP
#define _TCURANDOMVALUEITERATOR_HPP
/*-------------------------------------------------------------------------
 * drawElements Quality Program Tester Core
 * ----------------------------------------
 *
 * 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 Random value iterator.
 *//*--------------------------------------------------------------------*/

#include "tcuDefs.hpp"
#include "deRandom.hpp"

namespace tcu
{

template <typename T>
T getRandomValue (de::Random& rnd)
{
	// \note memcpy() is the only valid way to do cast from uint32 to float for instnance.
	deUint8 data[sizeof(T) + sizeof(T)%4];
	DE_STATIC_ASSERT(sizeof(data)%4 == 0);
	for (int vecNdx = 0; vecNdx < DE_LENGTH_OF_ARRAY(data)/4; vecNdx++)
	{
		deUint32 rval = rnd.getUint32();
		for (int compNdx = 0; compNdx < 4; compNdx++)
			data[vecNdx*4+compNdx] = ((const deUint8*)&rval)[compNdx];
	}
	return *(const T*)&data[0];
}

// Faster implementations for int types.
template <> inline deUint8	getRandomValue<deUint8>		(de::Random& rnd) { return (deUint8)rnd.getUint32();	}
template <> inline deUint16	getRandomValue<deUint16>	(de::Random& rnd) { return (deUint16)rnd.getUint32();	}
template <> inline deUint32	getRandomValue<deUint32>	(de::Random& rnd) { return rnd.getUint32();				}
template <> inline deUint64	getRandomValue<deUint64>	(de::Random& rnd) { return rnd.getUint64();				}
template <> inline deInt8	getRandomValue<deInt8>		(de::Random& rnd) { return (deInt8)rnd.getUint32();		}
template <> inline deInt16	getRandomValue<deInt16>		(de::Random& rnd) { return (deInt16)rnd.getUint32();	}
template <> inline deInt32	getRandomValue<deInt32>		(de::Random& rnd) { return (deInt32)rnd.getUint32();	}
template <> inline deInt64	getRandomValue<deInt64>		(de::Random& rnd) { return (deInt64)rnd.getUint64();	}

template <typename T>
class RandomValueIterator
{
public:
	using iterator_category = std::forward_iterator_tag;
	using value_type = T;
	using difference_type = std::ptrdiff_t;
	using pointer = T*;
	using reference = T&;

	static RandomValueIterator	begin					(deUint32 seed, int numValues)	{ return RandomValueIterator<T>(seed, numValues);	}
	static RandomValueIterator	end						(void)							{ return RandomValueIterator<T>(0, 0);				}

	RandomValueIterator&		operator++				(void);
	RandomValueIterator			operator++				(int);

	const T&					operator*				(void) const { return m_curVal; }

	bool						operator==				(const RandomValueIterator<T>& other) const;
	bool						operator!=				(const RandomValueIterator<T>& other) const;

private:
								RandomValueIterator		(deUint32 seed, int numLeft);

	de::Random					m_rnd;
	int							m_numLeft;
	T							m_curVal;
};

template <typename T>
RandomValueIterator<T>::RandomValueIterator (deUint32 seed, int numLeft)
	: m_rnd		(seed)
	, m_numLeft	(numLeft)
	, m_curVal	(numLeft > 0 ? getRandomValue<T>(m_rnd) : T())
{
}

template <typename T>
RandomValueIterator<T>& RandomValueIterator<T>::operator++ (void)
{
	DE_ASSERT(m_numLeft > 0);

	m_numLeft	-= 1;
	m_curVal	 = getRandomValue<T>(m_rnd);

	return *this;
}

template <typename T>
RandomValueIterator<T> RandomValueIterator<T>::operator++ (int)
{
	RandomValueIterator copy(*this);
	++(*this);
	return copy;
}

template <typename T>
bool RandomValueIterator<T>::operator== (const RandomValueIterator<T>& other) const
{
	return (m_numLeft == 0 && other.m_numLeft == 0) || (m_numLeft == other.m_numLeft && m_rnd == other.m_rnd);
}

template <typename T>
bool RandomValueIterator<T>::operator!= (const RandomValueIterator<T>& other) const
{
	return !(m_numLeft == 0 && other.m_numLeft == 0) && (m_numLeft != other.m_numLeft || m_rnd != other.m_rnd);
}

} // tcu

#endif // _TCURANDOMVALUEITERATOR_HPP
