#ifndef BRICK_LOGIC_H
#define BRICK_LOGIC_H

#include "brick_base.h"

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

class BrickLogicNot: public BrickLogicBase {
	MBRICK(BrickLogicNot)
	BrickLogicNot(): BrickLogicBase(1, 1) {type = "Not"; setName(type);}
	virtual bool tick_body(double time) {outputs[0] = (inputs[0] > 0. ? 0. : 1.); return true;}
};
ADD_NEW_TO_COLLECTION(Logics, BrickLogicNot)


class BrickLogicAnd: public BrickLogicBase {
	MBRICK(BrickLogicAnd)
	BrickLogicAnd(int inputs_num = 2): BrickLogicBase(inputs_num, 1) {type = "And"; setName(type); inNames[0] = ""; io_Type = BrickBase::VariableInputs;}
	virtual bool tick_body(double time);
};
ADD_NEW_TO_COLLECTION(Logics, BrickLogicAnd)


class BrickLogicOr: public BrickLogicBase {
	MBRICK(BrickLogicOr)
	BrickLogicOr(int inputs_num = 2): BrickLogicBase(inputs_num, 1) {type = "Or"; setName(type); inNames[0] = ""; io_Type = BrickBase::VariableInputs;}
	virtual bool tick_body(double time);
};
ADD_NEW_TO_COLLECTION(Logics, BrickLogicOr)


class BrickLogicXor: public BrickLogicBase {
	MBRICK(BrickLogicXor)
	BrickLogicXor(int inputs_num = 2): BrickLogicBase(inputs_num, 1) {type = "Xor"; setName(type); inNames[0] = ""; io_Type = BrickBase::VariableInputs;}
	virtual bool tick_body(double time);
};
ADD_NEW_TO_COLLECTION(Logics, BrickLogicXor)


class BrickLogicNAnd: public BrickLogicBase {
	MBRICK(BrickLogicNAnd)
	BrickLogicNAnd(int inputs_num = 2): BrickLogicBase(inputs_num, 1) {type = "NAnd"; setName(type); inNames[0] = ""; io_Type = BrickBase::VariableInputs;}
	virtual bool tick_body(double time);
};
ADD_NEW_TO_COLLECTION(Logics, BrickLogicNAnd)


class BrickLogicNOr: public BrickLogicBase {
	MBRICK(BrickLogicNOr)
	BrickLogicNOr(int inputs_num = 2): BrickLogicBase(inputs_num, 1) {type = "NOr"; setName(type); inNames[0] = ""; io_Type = BrickBase::VariableInputs;}
	virtual bool tick_body(double time);
};
ADD_NEW_TO_COLLECTION(Logics, BrickLogicNOr)


class BrickLogicNXor: public BrickLogicBase {
	MBRICK(BrickLogicNXor)
	BrickLogicNXor(int inputs_num = 2): BrickLogicBase(inputs_num, 1) {type = "NXor"; setName(type); inNames[0] = ""; io_Type = BrickBase::VariableInputs;}
	virtual bool tick_body(double time);
};
ADD_NEW_TO_COLLECTION(Logics, BrickLogicNXor)


class BrickLogicMemory: public BrickLogicBase {
	MBRICK(BrickLogicMemory)
	BrickLogicMemory(): BrickLogicBase(2, 1) {type = "Memory"; setName(type); inNames[1] = "Write";}
	enum Inputs {Input, Write};
	virtual bool tick_body(double time) {if (inputs[Write] > 0) outputs[0] = inputs[Input]; return true;}
};
ADD_NEW_TO_COLLECTION(Logics, BrickLogicMemory)


class BrickLogicCompare: public BrickLogicBase {
	MBRICK(BrickLogicCompare)
	BrickLogicCompare(double tolerance = 0.): BrickLogicBase(3, 3) {setTolerance(tolerance); type = "Compare"; setName(type); inNames[0] = ""; inNames[2] = "Tolerance"; outNames[0] = "<"; outNames[1] = "="; outNames[2] = ">";}
	enum Inputs {Tolerance = 2};
	void setTolerance(double tolerance) {inputs[Tolerance] = tolerance;}
	virtual bool tick_body(double time);
};
ADD_NEW_TO_COLLECTION(Logics, BrickLogicCompare)

#endif // BRICK_LOGIC_H
