#ifndef __MODEL_H
#define __MODEL_H

// Odwzorowanie analizowanego systemu
// Fragment pracy dyplomowej
//
// Dariusz Cieślak, http://cieslakd.prv.pl

#include "Const.h"
#include "Trigger.h"
#include "Predicate.h"
#include "Transition.h"
#include "PtrList.h"
#include "AbstractModel.h"
#include "VariableList.h"
#include "Set.h"

class Variable;
class AbstractState;
class InputSet;
class ostream;
class Expression;
class Input;
class Scaner;

class Model : public AbstractModel
{
	friend class RealTriggerGenerator;

	PtrList<Const> consts;
	PtrList<Predicate> predicates;
	Expression* /*only null*/ errorCondition;
	PtrList<Trigger> triggerList;

	const BitVector computeAbstractState() const;
	void createData();

	// do celów debugowania
	void showAbstractState(
		ostream& os, AbstractState* /*shared*/ as) const;
	void dumpVars();

	// disallow copy and assign by clients
	Model(const Model&);
	Model& operator=(const Model&);

	// elementy rekursywnego parsera wyrażeń
	Expression* /*only*/ parse_mul(Scaner& scan) const;
	Expression* /*only*/ parse_sum(Scaner& scan) const;
	Expression* /*only*/ parse_rel(Scaner& scan) const;
	Expression* /*only*/ parse_log(Scaner& scan) const;

	// metoda ułatwiająca zapisywanie testów
	// wykonuje wyrażenie i sprawdza wynik
	// sygnalizuje jeśli wynik inny niż oczekowany
	bool checkExpressionResult(
		const char* sExpression, int iExpected) const;

public:
	SetOf<Input> inputList;
	VariableList variableList;

	Model();
	~Model();

	// budowanie modelu ze składników
	void add(Const* /*only*/ c);
	void add(Predicate* /*only*/ p);
	void add(Trigger* /*only*/ t);

	Expression* /*only*/ parseExpression(Scaner& scan) const;
	Expression* /*only*/ parseValue(Scaner& scan) const;
	void setErrorCondition(Expression* /*only*/ expr);

	// format CXL służy do wymiany danych z narzędziami środowiska
	// COSMA
	void saveCxl(ostream& os);

	static void selfTest();
};

#endif /* __MODEL_H */

