#include "mylinks.h"
#include <iostream.h>
#include <math.h>

class Scheduler;


// Some underlying functions

void oosError(char* Err);
void error(char*);
void error(char*,char*);

void oosDump_Ev_List();

void report();

void trace(char*);
void trace(char* Mess1, char* Mess2);
void trace(char* Mess1, char* Mess2, float Val);
void trace(char* Mess1, char* Mess2, int Val, char* Mess3);

// These parts define the statistical collection devices

class Statistic: public mylink
{
protected:
   Statistic(char*);
   char* my_Title;
   long observations;
   Scheduler * clock;
public:
   virtual void report() = 0;
   virtual void update(float r) = 0;
   virtual void reset() = 0;
};

class Report: public mylink
{
private:

   const char* my_Title;
   Collection stats;

public:
   Report(const char *);
   void add_to(Statistic*);
   void report();
};

// Here's a simple integer statistic

class Count: public Statistic
{
private:
   int total;

public:
   Count(char*);
   void update(float);
   void report();
   void reset();
};

// Here's a simple floating point statistic

class Average: public Statistic
{
private:
   float sum;

public:
   Average(char*);
   void update(float);
   void report();
   void reset();
};

// These parts define the PassiveEntity stuff

class PassiveEntity
{
 private:
   char * title;

 protected:
 // We use standard input for the external dataset
  Collection blocked;
  Statistic * mystat;
  PassiveEntity(char *);
};

class ActiveEntity;

class Resource: public PassiveEntity
{
private:
   int avail;

public:
   void acquire(ActiveEntity* a);
   void release();
   Resource(char*);

};


// The ActiveEntity stuff

class TimeOrderedList : public Collection
{
public:
  void addInOrder(ActiveEntity*);
};

class ActiveEntity: public mylink
{
protected:
   float evTime;
   char* Title;
   int nextEvent;
   Scheduler * s;
   char * title;

   ActiveEntity(Scheduler *,char*,float);

public:
   float getTime();
   void trace(char* m);
   virtual void do_it() = 0;
   void reschedule();
};

//The Scheduler

class Scheduler
{
private:
   Collection * reports;
   TimeOrderedList evList;
   float s_now;

public:
   float now();
   Scheduler(Collection*);
   void wait(ActiveEntity* a);
   void run(float);
};
