#ifndef BACKTRACKER_H
#define BACKTRACKER_H

#include <QString>
#include <QThread>
#include <QRunnable>
#include <QThreadPool>
#include <QDebug>
#include <QSemaphore>

#include <batch/genericsolution.h>

namespace Backtrack
{
	template <typename TrackableT> class Generic //: public QRunnable
	{
	public:
		typedef QList<TrackableT> ListT;

		Generic() : Generation(0) {}
		virtual ~Generic() {/*qDebug() << "destruct " << QString::number(( qulonglong)this, 16);*/}

		virtual bool solved(void) const = 0;
		virtual ListT variants(void) const = 0;
		virtual QString toString(void) const = 0;

		int Generation;
	};


	template <class TrackableT> class Backtracker
		: public SQt::Concurrent::Solution::Generic<TrackableT, TrackableT>
	{
	public:
		typedef SQt::Concurrent::Solution::Generic<TrackableT, TrackableT> BaseT;

		Backtracker(QObject* parent, bool dbg = false)
			: BaseT(parent,QThread::idealThreadCount())
			, DebugSolved(dbg) { }

		virtual void compute (const typename BaseT::InputT& input) override {
			if (input.solved()) {
				this->addResults(input);
				if (DebugSolved)
					qDebug().noquote() << input.toString();
			}
			else
				this->solve(input.variants());
		}
	private:
		bool DebugSolved = false;
	};

}
#endif // BACKTRACKER_H
