#pragma once
#include "Heap.h"
#include "Ptr.h"
#include "Event.h"
#include "RandomStreamManager.h"
#include "AbstractSimulator.h"
#include "GeneralSimulatorSubject.h"
#include "AbstractSimulationResultDTO.h"


class SimulatorSingleton:virtual public  AbstractSimulator, public GeneralSimulatorSubject
{
private:
	static SimulatorSingleton *_instance;
	static const int size=10;
	int arrivalsRate;
	bool simulationComplete;
	Event* currentEvent;
	AbstractSimulationResultDTO* simulationResult;
protected:
	Heap<Ptr<Event> >events;
	double clock;
public:
	void AbstractSimulator::start();
	void AbstractSimulator::reset();
	void AbstractSimulator::step();
	bool AbstractSimulator::isSimulationComplete();
	Event* AbstractSimulator::getCurrentEvent();
	Heap<Ptr<Event> > AbstractSimulator::getEventQueue();
	int AbstractSimulator::getEventQueueSize();
	Event* AbstractSimulator::getIthEvent(int i);
	static SimulatorSingleton* instance();
	RandomStreamManager *rStreamManager;
	AbstractSimulationResultDTO* AbstractSimulator::getSimulationResult();
	void AbstractSimulator::setSimulationResult(AbstractSimulationResultDTO* simulationResult);
	
	int simulationTime;

	SimulatorSingleton(int s):events(1,s)
	{
		_instance = this;
		rStreamManager = new RandomStreamManager();
	}

	void add_event(Event *evt)
	{
		evt->setInitialTime(clock);
		Ptr<Event> e(evt);
		events.heapInsert(e);
	}


	double get_clock()
	{
		return clock;
	}

	void setHeapSize(int value)
	{
		events.setSize(value);
	}

	void AbstractSimulator::setAverageArrivalsRate(int _arrivalsRate){
		arrivalsRate = _arrivalsRate;
	}
};