#ifndef BRICK_MANAGER_H
#define BRICK_MANAGER_H

#include "pitimer.h"
#include "brick_base.h"

class BrickManager
{
	friend class BrickEmitFrequency;
public:
	BrickManager(double frequency = 20., double time_step = 0.);
	~BrickManager() {delete timer;}
	
	void start();
	void stop();
	void reset();
	void resetOutputs();
	void resetScheme();
	bool loadScheme(const PIString & file);
	inline void pause() {paused = true;}
	inline void resume() {paused = false;}
	inline void needLockRun(bool yes) {timer->needLockRun(yes);}
	inline void lock() {timer->lock();}
	inline void unlock() {timer->unlock();}
	inline bool isPaused() const {return paused;}
	inline bool isRunning() const {return timer->isRunning();}
	inline bool isReset() const {return wasReset;}
	inline double frequency() const {return freq;}
	inline double * frequency_ptr() {return &freq;}
	void setFrequency(double frequency, double time_step = 0.);
	void addBrick(BrickBase * brick, bool uniqueName = true);
	inline void addBrick(BrickBase & brick) {addBrick(&brick);}
	inline void clearBricks() {bricks.clear();}
	void removeBrick(BrickBase * brick);
	void replaceBrick(BrickBase * old_b, BrickBase * new_b);
	inline int bricksCount() const {return bricks.size();}
	inline double time() const {return ctime;}
	inline double * time_ptr() {return &ctime;}
	inline void setTime(double time) {ctime = time;}
	void tick(bool realTime = true);
	void proceedConnections(bool compositeToo = false);
	void saveInputsToDefault();
	inline void startBricks() {for (uint i = 0; i < bricks.size(); ++i) bricks[i]->started();}
	inline void stopBricks() {for (uint i = 0; i < bricks.size(); ++i) bricks[i]->finished();}
	bool checkUniqueName(const PIString & name, BrickBase * brick);
	PIString getUniqueName(const PIString & name);
	BrickBase * findBrick(const PIString & name);
	inline BrickBase::Mode mode() const {return mode_;}
	void setMode(BrickBase::Mode m);
	void buildSchemeTree();
	
	PIVector<PIVector<BrickBase * > > tree;
	
private:
	static void run(void * d, int ) {((BrickManager * )d)->tick();}
	void disconnectBrick(BrickBase * brick);
	void loadBrick(PIConfig & sr, const PIString & prefix, BrickBase * b);
	
	PITimer * timer;
	PIVector<BrickBase * > bricks;
	BrickBase::Mode mode_;
	double freq, ctime, tstep;
	bool paused, wasReset;
	
};

#endif // BRICK_MANAGER_H
