#ifndef VGS_PROCTOOLS_FORMATTER_H
#define VGS_PROCTOOLS_FORMATTER_H

#include <string>
#include <sstream>
#include <iostream>
#include <iomanip>

namespace proctools 
{

	class format
	{
	public:
		template<typename T>
		struct prec_t
		{
			prec_t(const T& val, int width): m_val(val), m_width(width) {}
			const T& m_val;
			int m_width;
		};

		template<typename T>
		static prec_t<T> prec(const T& val, int width);

		format(const std::string& format): m_text(format), m_index(0) {}

		operator const std::string&() { return m_text; }

		template<typename T>
		format& operator%(const T& object);

	private:
		std::string m_text;
		int m_index;
	};

	template<typename T>
	std::ostream& operator<<(std::ostream& s, const format::prec_t<T>& obj)
	{
		return s << std::setw(obj.m_width) << obj.m_val;
	}

	template<typename T>
	format::prec_t<T> format::prec(const T& val, int width)
	{
		return prec_t<T>(val, width);
	}

	template<typename T>
	format& format::operator%(const T& object)
	{
		std::stringstream stream, item;
		stream << object;
		item << "{" << m_index << "}";

		std::string::size_type pos;
		if ((pos = m_text.find(item.str())) != std::string::npos)
			m_text.replace(pos, item.str().length(), stream.str());

		++m_index;
		return *this;
	}

};

#endif // VGS_PROCTOOLS_FORMATTER_H
