#ifndef SENSOR_H
#define SENSOR_H

#include <vector>
#include <QObject>
#include <Indoor/data/Timestamp.h>

template <typename T> class Sensor;

/** listen for sensor events */
template <typename T> class SensorListener {

public:

	/** incoming sensor data */
	virtual void onSensorData(Sensor<T>* sensor, const Timestamp ts, const T& data) = 0;

};


/** base-class for all sensors */
template <typename T> class Sensor {

private:

	std::vector<SensorListener<T>*> listeners;

public:

	/** start this sensor */
	virtual void start() = 0;

	/** stop this sensor */
	virtual void stop() = 0;

	/** whether the sensor is currently start()ed */
	virtual bool isRunning() const = 0;

	/** add the given listener to the sensor */
	void addListener(SensorListener<T>* l) {
		listeners.push_back(l);
	}

	/** remove the given listener from the sensor */
	void removeListener(SensorListener<T>* l) {
		listeners.erase(std::remove(listeners.begin(), listeners.end(), l), listeners.end());
	}

protected:

	/** inform all attached listeners */
	void informListeners(const T& sensorData) {
		const Timestamp now = Timestamp::fromRunningTime();
		for (SensorListener<T>* l : listeners) {
			l->onSensorData(this, now, sensorData);
		}
	}

	/** inform all attached listeners. call this if you know the timestamp */
	void informListeners(const Timestamp ts, const T& sensorData) {
		for (SensorListener<T>* l : listeners) {
			l->onSensorData(this, ts, sensorData);
		}
	}


};

#endif // SENSOR_H
