//**************************************************************
//
// CS 240C   :Spring 2003 Ohio University Travis Dillon
// Project 2 :Emergency Room Triage
// file      :prog2.cc
// started   :04-21-03
//
//**************************************************************

#include "prog2.h"

int main()
{
   int num_hours(0);  //number of hours user wants to run simulation
   multiset <Patient> waiters;  //priority queue of patients
   ifstream fin_name;  //input file of names of patients
   ifstream fin_carrier;  //input file of insurance carriers
   ofstream fout;  //output file of log report
   string pat_name;  //name of patient
   string pat_carrier;  //name of insurance carrier
   vector <string> name_arr;  //array of patient names
   vector <string> carrier_arr;  //array of insurance carriers
   Room room1;  //room one of triage
   Room room2;  //room two of triage
   Room room3;  //room three of triage
   Average all_averages;  //average object of all patients
   Average aves[10];  //array of average objects according to level


   fout.open("logfile.txt");  //open log file
   fout << "LOE   Name                  Birthday    "
        << "Insurance             Arrived   Serviced";  //logfile header
   fin_name.open("names.txt");  //open name file
   fin_carrier.open("carriers.txt");  //open carriers file
   while(!fin_name.eof())  //put names into array, for random access
   {
      getline(fin_name, pat_name);
      name_arr.push_back(pat_name);
   }
   while(!fin_carrier.eof())  //put carriers into array, for random access
   {

      getline(fin_carrier, pat_carrier);
      carrier_arr.push_back(pat_carrier);
   }
   fin_name.close();
   fin_carrier.close();

   cout << "How many hours to run the simulation:  ";
   cin >> num_hours;  //user defined number of hours for simulation
   Time timer(num_hours, 0, 0);  //this is sentinal value, ends simulation
   Time start(0,0,0);  //start timer, runs till equal with sentinal
   
   while(start < timer)
   {  //each execution of loop represents one second of real time
      if(it_is(.0025))  //.25% chance of patient coming in.
      {
         Patient in(start, name_arr[rand()%(name_arr.size()-1)],  //randomly get
                    carrier_arr[rand()%(carrier_arr.size()-1)]);  //patient info
         waiters.insert(in);  //insert patient into the priority queue

         if(room1.is_empty() && !waiters.empty())  //if room is empty and someone
         {                                        //is waiting, they go to room 1
            room1.set_time_left();  //random time this room will be busy
            //next two statements get average waiting time for patient according
            //to level and overall
            all_averages.next_number(start - (*waiters.begin()).get_arrival());            
            aves[(*waiters.begin()).get_level() -1]
                .next_number(start -(*waiters.begin()).get_arrival());              
            fout << *waiters.begin() << "  " << start;  //output pat info to log
            waiters.erase(waiters.begin());  //take patient off priority queue
         }
         if(room2.is_empty() && !waiters.empty())  //if room is empty and someone
         {                                        //is waiting, they go to room 2
            room2.set_time_left();  //random time this room will be busy
            //next two statements are for average objects
            all_averages.next_number(start - (*waiters.begin()).get_arrival());            
            aves[(*waiters.begin()).get_level() -1]
                .next_number(start -(*waiters.begin()).get_arrival());            
            fout << *waiters.begin() << "  " << start;  //output pat info to log
            waiters.erase(waiters.begin());  //take patient off priority queue
         }
         if(room3.is_empty() && !waiters.empty())  //if room is empty and someone
         {                                        //is waiting, they go to room 3
            room3.set_time_left();  //random time this room will be busy
            //next two statements are for average objects
            all_averages.next_number(start - (*waiters.begin()).get_arrival());            
            aves[(*waiters.begin()).get_level() -1]
                .next_number(start -(*waiters.begin()).get_arrival());            
            fout << *waiters.begin() << "  " << start;  //output pat info to log
            waiters.erase(waiters.begin());  //take patient off priority queue
         }
      }
      --room1;  //take a second
      --room2;  //off of each
      --room3;  //rooms business
      start = start + 1;  //add a second to simulations total running time
   }

   Time temp;  //make a Time variable for output purposes
              //for some reason "cout << all_averages.the_average();" won't work
   temp = all_averages.the_average();
   
   cout << "The average waiting time for all emergency  levels:  " <<temp << endl;
   for(int i(0); i < 10; ++i)
   {  //output the averages in the array, for each emergency level
      Time temp_ave = aves[i].the_average();  
      cout <<"The average waiting time for level" << setw(3) << i + 1 << " emergency is:  "
           << temp_ave << endl;
   }
   //output the number of people who remain in the priority queue
   cout << "There are " << waiters.size() << " people still waiting." << endl;

   fout.close();
   return EXIT_SUCCESS;
}

bool it_is(double probability)
{  //gives a random probability
   return rand() < probability * RAND_MAX;
}