#ifndef NAVCONTROLLER_H
#define NAVCONTROLLER_H

#include "../sensors/AccelerometerSensor.h"
#include "../sensors/GyroscopeSensor.h"
#include "../sensors/BarometerSensor.h"
#include "../sensors/WiFiSensor.h"
#include "../sensors/SensorFactory.h"
#include "../sensors/StepSensor.h"
#include "../sensors/TurnSensor.h"

//#include "../ui/debug/SensorDataWidget.h"
//#include "../ui/map/3D/MapView3D.h"
//#include "../ui/debug/InfoWidget.h"

#include <Indoor/Assertions.h>
#include <thread>

#include "Observation.h"
#include "../Settings.h"

//#include "Filter.h"
//#include "Controller.h"
//#include "NavControllerListener.h"

//#include <KLib/misc/gnuplot/Gnuplot.h>
//#include <KLib/misc/gnuplot/GnuplotSplot.h>
//#include <KLib/misc/gnuplot/GnuplotSplotElementPoints.h>
//#include <KLib/misc/gnuplot/GnuplotSplotElementLines.h>

////#ifndef ANDROID
////#include <valgrind/callgrind.h>
////#endif

//#include "Settings.h"
//#include "RegionalResampling.h"
//#include "NodeResampling.h"

#include "NavControllerListener.h"
#include "CurEst.h"

class Controller;

class NavController :
		public SensorListener<AccelerometerData>,
		public SensorListener<GyroscopeData>,
		public SensorListener<BarometerData>,
		public SensorListener<WiFiMeasurements>,
		public SensorListener<GPSData>,
		public SensorListener<StepData>,
        public SensorListener<TurnData>,
        public SensorListener<ActivityData>
		{


protected:

	Controller* mainController;
	Floorplan::IndoorMap* im;

	bool running = false;
	std::thread tFilter;
	std::thread tDisplay;

	/** the estimated path */
	std::vector<Point3> estPath;

	/** all listeners */
	std::vector<NavControllerListener*> listeners;

	/** display stuff */
	const int display_ms = Settings::MapView3D::msPerFrame.ms();
	Point3 curPosFast;
	Point3 curPosSlow;
	CurEst curEst;

	Timestamp lastTransition;

public:

	NavController(Controller* mainController, Floorplan::IndoorMap* im);

	virtual ~NavController() {
		if (running) {stop();}
	}

	/** attach a new event listener */
	void addListener(NavControllerListener* l) {
		listeners.push_back(l);
	}

public:

	virtual void stop() {;}

	virtual void start() = 0;

	int cameraMode = 0;
	void toggleCamera() {
		cameraMode = (cameraMode + 1) % 3;
	}

	/** update the map-view (called from within a background-loop) */
	void updateMapView();

};

#endif // NAVCONTROLLER_H
