#include "../../include/dv-sdk/module.hpp"

#include <vector>

struct matrixS {
	uint32_t timestamp; // keep only the lower part for performance
	bool polarity;

	matrixS() : timestamp{0}, polarity{false} {
	}
};

using densityMatrixType = bool;
using densityMatrixT    = std::vector<densityMatrixType>;
using matrixBufferT     = std::vector<matrixS>;
using dividedT          = std::vector<uint32_t>;

class Ynoise : public dv::ModuleBase {
public:
	static const char *initDescription();

	static void initInputs(dv::InputDefinitionList &in);

	static void initOutputs(dv::OutputDefinitionList &out);

	static void initConfigOptions(dv::RuntimeConfig &config);

	Ynoise();

	void run() override;

	void configUpdate() override;

private:
	densityMatrixT densityMatrix;
	densityMatrixT resetMatrix;
	matrixBufferT matrixMem;
	uint32_t deltaT;
	uint8_t lParam;
	uint32_t squareLParam;
	uint8_t threshold;
	uint32_t sizeX;
	uint32_t sizeY;
	dividedT dividedLparam;
	dividedT modLparam;

	void updateMatrix(const dv::Event &event);

	uint8_t calculateDensity(const dv::Event &event);

	// generation of array of i/lParam and i%lParam for performance optimisation
	void regenerateDMLparam();
};

registerModuleClass(Ynoise)
