#ifndef _TCUFORMATUTIL_HPP
#define _TCUFORMATUTIL_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 String format utilities.
 *//*--------------------------------------------------------------------*/

#include "tcuDefs.hpp"
#include "deString.h"

#include <ostream>
#include <string>

namespace tcu
{
namespace Format
{

// Hexadecimal value formatter.
template <size_t NumDigits>
class Hex
{
public:
	Hex (deUint64 value_) : value(value_) {}

	std::ostream& toStream (std::ostream& stream) const
	{
		return stream << this->toString();
	}

	std::string toString (void) const
	{
		DE_STATIC_ASSERT(0 < NumDigits && NumDigits <= 16);

		const char longFmt[]	= {'0', 'x', '%', '0', '0' + NumDigits/10, '0' + NumDigits%10, 'l', 'l', 'x', 0};
		const char shortFmt[]	= {'0', 'x', '%', '0', '0' + NumDigits, 'l', 'l', 'x', 0};

		char buf[sizeof(deUint64)*2 + 3];
		deSprintf(buf, sizeof(buf), NumDigits > 9 ? longFmt : shortFmt, value);

		return std::string(buf);
	}

private:
	deUint64 value;
};

template <size_t NumDigits>
std::ostream& operator<< (std::ostream& stream, tcu::Format::Hex<NumDigits> hex)
{
	return hex.toStream(stream);
}

// Bitfield formatter.

class BitDesc
{
public:
	deUint64	bit;
	const char*	name;

	BitDesc (deUint64 bit_, const char* name_) : bit(bit_), name(name_) {}
};

#define TCU_BIT_DESC(BIT) tcu::Format::BitDesc(BIT, #BIT)

template <size_t BitfieldSize>
class Bitfield
{
public:
	Bitfield (deUint64 value, const BitDesc* begin, const BitDesc* end)
		: m_value	(value)
		, m_begin	(begin)
		, m_end		(end)
	{
	}

	std::ostream& toStream (std::ostream& stream)
	{
		deUint64 bitsLeft = m_value;
		for (const BitDesc* curDesc = m_begin; curDesc != m_end; curDesc++)
		{
			if (curDesc->bit & bitsLeft)
			{
				if (bitsLeft != m_value)
					stream << "|";
				stream << curDesc->name;
				bitsLeft ^= curDesc->bit;
			}
		}

		if (bitsLeft != 0)
		{
			if (bitsLeft != m_value)
				stream << "|";
			stream << Hex<BitfieldSize/4>(bitsLeft);
		}

		return stream;
	}

private:
	deUint64			m_value;
	const BitDesc*		m_begin;
	const BitDesc*		m_end;
};

template <size_t BitfieldSize>
inline std::ostream& operator<< (std::ostream& stream, Bitfield<BitfieldSize> decoder)
{
	return decoder.toStream(stream);
}

// Enum formatter.
// \todo [2012-10-30 pyry] Use template for GetName.
template <typename T, size_t NumBytes = sizeof(T)>
class Enum
{
public:
	typedef const char* (*GetNameFunc) (T value);

	Enum (GetNameFunc getName, T value)
		: m_getName	(getName)
		, m_value (value)
	{
	}

	std::ostream& toStream (std::ostream& stream) const
	{
		const char* name = m_getName(m_value);
		if (name)
			return stream << name;
		else
			return stream << Hex<NumBytes*2>((deUint64)m_value);
	}

	std::string toString (void) const
	{
		const char* name = m_getName(m_value);
		if (name)
			return std::string(name);
		else
			return Hex<NumBytes*2>((deUint64)m_value).toString();
	}

private:
	const GetNameFunc	m_getName;
	const T				m_value;
};

template <typename T, size_t NumBytes>
inline std::ostream& operator<< (std::ostream& stream, const Enum<T, NumBytes>& fmt) { return fmt.toStream(stream); }

// Array formatters.

template <typename Iterator>
class Array
{
public:
	Iterator	begin;
	Iterator	end;

	Array (const Iterator& begin_, const Iterator& end_) : begin(begin_), end(end_) {}
};

template <typename T>
class ArrayPointer
{
public:
	const T*	arr;
	int			size;

	ArrayPointer (const T* arr_, int size_) : arr(arr_), size(size_) {}
};

template <typename Iterator>
std::ostream& operator<< (std::ostream& str, const Array<Iterator>& fmt)
{
	str << "{ ";
	for (Iterator cur = fmt.begin; cur != fmt.end; ++cur)
	{
		if (cur != fmt.begin)
			str << ", ";
		str << *cur;
	}
	str << " }";
	return str;
}

template <typename T>
std::ostream& operator<< (std::ostream& str, const ArrayPointer<T>& fmt)
{
	if (fmt.arr != DE_NULL)
		return str << Array<const T*>(fmt.arr, fmt.arr+fmt.size);
	else
		return str << "(null)";
}

// Hex format iterator (useful for combining with ArrayFormatter).
// \todo [2012-10-30 pyry] Implement more generic format iterator.

template <typename T, typename Iterator = const T*>
class HexIterator
{
public:
										HexIterator			(Iterator iter) : m_iter(iter) {}

	HexIterator<T, Iterator>&			operator++			(void)	{ ++m_iter; return *this;		}
	HexIterator<T, Iterator>			operator++			(int)	{ return HexIterator(m_iter++);	}

	bool								operator==			(const HexIterator<T, Iterator>& other) const { return m_iter == other.m_iter; }
	bool								operator!=			(const HexIterator<T, Iterator>& other) const { return m_iter != other.m_iter; }

#if !defined(__INTELLISENSE__)
	// Intellisense in VS2013 crashes when parsing this.
	Hex<sizeof(T)*2>					operator*			(void) const { return Hex<sizeof(T)*2>(*m_iter);	}
#endif

private:
	Iterator							m_iter;
};

} // Format

template <int Bits>		inline deUint64 makeMask64			(void)				{ return (1ull<<Bits)-1;								}
template <>				inline deUint64 makeMask64<64>		(void)				{ return ~0ull;											}
template <typename T>	inline deUint64	toUint64			(T value)			{ return (deUint64)value & makeMask64<sizeof(T)*8>();	}

/** Format value as hexadecimal number. */
template <size_t NumDigits, typename T>
inline Format::Hex<NumDigits> toHex (T value)
{
	return Format::Hex<NumDigits>(toUint64(value));
}

/** Format value as hexadecimal number. */
template <typename T>
inline Format::Hex<sizeof(T)*2> toHex (T value)
{
	return Format::Hex<sizeof(T)*2>(toUint64(value));
}

/** Decode and format bitfield. */
template <typename T, size_t Size>
inline Format::Bitfield<sizeof(T)*8> formatBitfield (T value, const Format::BitDesc (&desc)[Size])
{
	return Format::Bitfield<sizeof(T)*8>((deUint64)value, &desc[0], &desc[Size]);
}

/** Format array contents. */
template <typename Iterator>
inline Format::Array<Iterator> formatArray (const Iterator& begin, const Iterator& end)
{
	return Format::Array<Iterator>(begin, end);
}

/** Format array contents. */
template <typename T>
inline Format::ArrayPointer<T> formatArray (const T* arr, int size)
{
	return Format::ArrayPointer<T>(arr, size);
}

/** Format array contents. */
template <typename T, int Size>
inline Format::ArrayPointer<T> formatArray (const T (&arr)[Size])
{
	return Format::ArrayPointer<T>(arr, Size);
}

} // tcu

#endif // _TCUFORMATUTIL_HPP
