#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>
#include <sstream>
#include <iomanip>

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
	{
		DE_STATIC_ASSERT(0 < NumDigits && NumDigits <= 16);

		return stream	<< "0x"
						<< std::right
						<< std::setfill('0')
						<< std::setw(NumDigits)
						<< std::hex
						<< value;
	}

	std::string toString (void) const
	{
		std::stringstream stream;

		toStream(stream);
		return stream.str();
	}

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
