/* 
File:	 ps2-sampler.doc
Author:	R. P. Futrelle
Date:	 8/4/98
Notice:	Copyright 1998 by R. P. Futrelle and the College of Computer Science,
		Northeastern University
Class:  COM1204, Object-Oriented Design, Summer 1998.
Proj:	 PS2.� Metrowerks Code Warrior Mac. Done in IDE version 2.0.1.
Purpose: Some code from the system up to this point.
						

Modification history:
8/4/98:	RPF. Started.

*/

// INCLUDES.H

/* 
File:	 includes.h
Author:	R. P. Futrelle
Date:	 8/4/98
Notice:	Copyright 1998 by R. P. Futrelle and the College of Computer Science,
		Northeastern University
Class:  COM1204, Object-Oriented Design, Summer 1998.
Proj:	 PS2.� Metrowerks Code Warrior Mac. Done in IDE version 2.0.1.
Purpose: Included in every .cp file in project.  Collects together all includes.
						

Modification history:
8/1/98:	RPF. Started.
8/4/98: RPF. Added stdlib.h for rand() and srand().

*/

#include <fstream>
#include <iomanip>
#include <vector>
#include <string>
#include <stdlib.h>

#include "declares.h"
#include "super.h"
#include "phone.h"
#include "switch.h"
#include "link.h"
#include "packet.h"
#include "misc.h"
#include "system.h"
#include "log.h"
#include "globals.h"

// PHONE.H

/* 
File:	 phone.h
Author:	R. P. Futrelle
Date:	 8/1/98
Notice:	Copyright 1998 by R. P. Futrelle and the College of Computer Science,
		Northeastern University
Class:  COM1204, Object-Oriented Design, Summer 1998.
Proj:	 PS2.� Metrowerks Code Warrior Mac. Done in IDE version 2.0.1.
Purpose: Phone class definition.
						

Modification history:
8/1/98:	RPF. Started.

*/

// Phone number forms:  exchange is 1-9, remainder of phone number is 1-99
//  (leading zeros print poorly).

class Phone : public Node{
	public:
	static int next_id;
	
	int id;	// ID number
	int p_number;  // (100*exchange + p_number)
	
	Phone(int p_number);	// constructor
	void run();
	void do_states();
	

	// Actions
	void pickup();	// puts pickup packet in link
	void hangup();	// puts hangup packet in link
	void dial(int p_number);	// puts dial packet in link
	void speak(string);	// puts speech in packet and packet in link
	
	};	

// SYSTEM.CP

/* 
File:	 system.cp
Author:	R. P. Futrelle
Date:	 8/1/98
Notice:	Copyright 1998 by R. P. Futrelle and the College of Computer Science,
		Northeastern University
Class:  COM1204, Object-Oriented Design, Summer 1998.
Proj:	 PS2.� Metrowerks Code Warrior Mac. Done in IDE version 2.0.1.
Purpose: Method definitions for classes System, Timer, and Switch_Phone_State.
						

Modification history:
8/1/98:	RPF. Started.
8/3/98: Timer finished, tested.
				System constructor done.

*/

#include "includes.h"

// THE SYSTEM
// CONSTRUCTION

System::
System(int how_many_phones) 
	: time(0), num_phones(how_many_phones), num_switches(1), the_log(new Log){	
	// first, create the vector objects needed
	// note that superclass is used for switches and phones
	switches = new vector<Switch*, allocator<Switch*> >;
	phones = new vector<Phone*, allocator<Phone*> >;
	links = new vector<Link*, allocator<Link*> >;
	
	// create phones, switch, links and wire them up
	(*switches)[1] = new Switch;
	a_switch = (*switches)[1];
	
	// use phone and link id's as indexes into vectors
	for(int i = 0; i < how_many_phones; i++)
		{a_phone  = new Phone(2*i + 1);	// exchange is 1 and a phone number
		(*phones)[a_phone->id] =a_phone;
		a_link = new Link;
		(*links)[a_link->id] = a_link;
		
		// now wire them up
		a_link->source_a = (Node*)(a_switch);
		a_link->source_b = (Node*)(a_phone);
		a_phone->my_link = a_link;
		(*(a_switch->links))[i] = a_link;
		
		}	// end of loop over phones
	}

// RUNNING THE SYSTEM

void System::
run(int how_many_steps, string *log_file_name, bool c_logging, int rseed) {
	max_steps = how_many_steps;
	for(time = 0; time < max_steps; time++)
		{
		for(int i = 0; i < num_phones; i++)
			{
			(*phones)[i]->run();
			}
			(*switches)[0]->run();
		}
	if(flog || clog) {}	// print summary stats to cout in either event
	}

// TIMER IMPLEMENTATION

Timer::
Timer() : on(false), set_for(0) { }

void Timer::
start(int duration) {
	set_for = sys->time + duration;
	}

int Timer::
start(int min_duration, int max_duration){
	set_for = sys->time + rand_range(min_duration, max_duration);
	return(set_for);
	}
	
void Timer::
shut_off() {
	on = false;
	set_for = 0;
	}
	
bool Timer::
rang() {
	return(set_for < sys->time);
	}

int Timer::
remaining (){
	return(set_for - sys->time);
	}