// sort algorithm example
#ifndef SORT_H_H
#define SORT_H_H
#include "Vector.h"
#include <algorithm>
#include <cassert>
#include <iostream>

namespace PsimagLite
{
template <typename ContainerType>
class Sort
{
public:

	typedef typename ContainerType::value_type FieldType;
	typedef std::pair<FieldType, SizeType> PairType;
	class Compare
	{

	public:

		Compare(const typename Vector<PairType>::Type& x)
		    : x_(x)
		{
		}

		bool operator()(const PairType& x1, const PairType& x2)
		{
			return (x1.first < x2.first);
		}

	private:

		const typename Vector<PairType>::Type& x_;
	};

	template <typename A>
	void sort(ContainerType& x, typename std::vector<SizeType, A>& iperm, SizeType smallSize = 0)
	{
		SizeType n = x.size();
		if (n == 0)
			return;
		// FIXME: DON'T USE smallSize, just say n=iperm.size()
		if (smallSize != 0)
			n = smallSize;
		assert(n == iperm.size());
		const ContainerType& xread = x;
		PairType onep(xread[0], 0);
		typename Vector<PairType>::Type p(n, onep);
		for (SizeType i = 0; i < n; i++) {
			p[i].first = xread[i];
			p[i].second = i;
		}
		std::sort(p.begin(), p.end(), Compare(p));
		for (SizeType i = 0; i < n; i++) {
			x[i] = p[i].first;
			iperm[i] = p[i].second;
		}
	}

}; // class Sort
} // namespace PsimagLite

#endif // SORT_H_H
