//#  eulerN -- program for statistical estimation of Euler characteristic of a 3-dimensional body
//#  given as a sufficiently dense "volumetric" point sampling
//#
//#  Copyright (c) 2005-2007 Bradford Jones, Konstantin Rybnikov, Karen Daniels, Daniel Klain
//#  Release 2: 1 June 2007 
//#
//#  This program is free software; you can redistribute it and/or modify it
//#  under the terms of the GNU General Public License as published by the
//#  Free Software Foundation; either version 2, or (at your option) any
//#  later version: http://www.gnu.org/licenses/gpl.txt.
//#
//#  This program is distributed in the hope that it will be useful,
//#  but WITHOUT ANY WARRANTY; without even the implied warranty of
//#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//#  GNU General Public License for more details.
//#-----------------------------------------------------------------------------


#ifndef EULERSWEEP
#define EULERSWEEP
	#include <vector>
	#include <algorithm>
	#include <stack>
	#include "Interval.h"
	#include "d2point.h"
	#include "math_vector.h"
	using namespace std;

	class EulerSweep
	{
		private:
			static bool hard; // hard == true means that the hard approach should be used, calling matching() at every iteration
			static double smallT;
			static double bigT;

			// these private functions are used in the implementation
			static double inline min(double a, double b)
			{
				if (a <= b)
					return a;
				else
					return b;
			}
			static bool overlapInterval(Interval &a, Interval &b, double smallT, double bigT);
			static int matching(stack<Interval> SL, stack<Interval> SR, double smallT, double bigT);
			static stack<Interval> constructIntervals (vector<double> &pointcloud, double stripwidth);
		public:
			EulerSweep(bool hardapproach, double littleT, double largeT)
			{
				hard = hardapproach;
				smallT = littleT;
				bigT = largeT;
			}
			double getTau()
			{
				return smallT;
			}
			double getT()
			{
				return bigT;
			}
			static int euler2d (vector<d2point> &pointcloud, vector<double> &deltas, int numdirections, vector<math_vector> &directions);

	};

#endif
