#ifndef BRICK_STATISTIC_H
#define BRICK_STATISTIC_H

#include "brick_math.h"


class BrickStatisticBase: public BrickBase {
public: BrickStatisticBase(int inputs_num = 1, int outputs_num = 1, int parameters_num = 0): BrickBase(inputs_num, outputs_num, parameters_num) {lib = "Statistic";}
};


class BrickStatisticMinMaxI: public BrickStatisticBase {
	MBRICK(BrickStatisticMinMaxI)
	BrickStatisticMinMaxI(): BrickStatisticBase(2, 2) {type = "MinMax_Immediate"; setName(type); outNames[Min] = "Min"; outNames[Max] = "Max"; inNames[0] = "0"; io_Type = VariableInputs;}
	enum Inputs {Min, Max};
	virtual void reset_specified() {min = max = 0.;}
	virtual bool tick_body(double time);
private:
	double min, max;
};
ADD_NEW_TO_COLLECTION(Statistic, BrickStatisticMinMaxI)


class BrickStatisticMinMaxF: public BrickStatisticBase {
	MBRICK(BrickStatisticMinMaxF)
	BrickStatisticMinMaxF(): BrickStatisticBase(1, 2) {type = "MinMax_Function"; setName(type); outNames[Min] = "Min"; outNames[Max] = "Max";}
	enum Inputs {Min, Max};
	virtual void reset_specified() {min = max = 0.;}
	virtual bool tick_body(double time) {if (min > inputs[0]) min = inputs[0]; if (max < inputs[0]) max = inputs[0]; outputs[Min] = min; outputs[Max] = max; return true;}
private:
	double min, max;
};
ADD_NEW_TO_COLLECTION(Statistic, BrickStatisticMinMaxF)


class BrickStatisticExpectation: public BrickStatisticBase {
	MBRICK(BrickStatisticExpectation)
	BrickStatisticExpectation(): BrickStatisticBase(1, 1) {type = "Expectation"; setName(type);}
	virtual void reset_specified() {i.reset(); pt = t = 0.;}
	virtual bool tick_body(double time);
private:
	BrickMathIntegral i; double pt, t;
};
ADD_NEW_TO_COLLECTION(Statistic, BrickStatisticExpectation)


class BrickStatisticVariance: public BrickStatisticBase {
	MBRICK(BrickStatisticVariance)
	BrickStatisticVariance(): BrickStatisticBase(1, 1) {type = "Variance"; setName(type);}
	virtual void reset_specified() {i0.reset();  i1.reset(); pt = t = 0.;}
	virtual bool tick_body(double time);
private:
	BrickMathIntegral i0, i1; double pt, t;
};
ADD_NEW_TO_COLLECTION(Statistic, BrickStatisticVariance)

#endif // BRICK_STATISTIC_H
