// restaurant.cpp
// James Atlas and Phill Conrad, for CISC181, Fall 2004

// An object representing a basic implementation of a Restaurant
// with properties and functions

#include "getThings.h" // for getFirstCharacter(), getFirstInteger()
#include "restaurant.h"
#include "table.h"

#include <iostream>
using std::cout;
using std::cin;
using std::cerr;
using std::endl;
using std::getline;

#include <cassert> // for assert() function
#include <cstdlib> // for atoi

// normal Constructor
Restaurant::Restaurant(int pNumberOfTables, int pMaxGuestsPerTable)
{
  numberOfTables = pNumberOfTables;
  maxGuestsPerTable = pMaxGuestsPerTable;
  // allocate space for the tables from the heap
  table = new Table[numberOfTables];

  // This line above calls the constructor for each new table
  // object created, initializing each one.   This is one of the ways that 
  // the "new" operator in C++ is different from the "malloc" function in C,
  // which just gives you some "raw space" from the heap.
}

// copy Constructor
Restaurant::Restaurant(const Restaurant &restaurantToCopy)
{
  numberOfTables = restaurantToCopy.numberOfTables;
  maxGuestsPerTable = restaurantToCopy.maxGuestsPerTable;
  
  table = new Table[numberOfTables];
  for (int i = 0; i < numberOfTables; i++)
    {
      table[i] = restaurantToCopy.table[i];
    }
}

// overloaded assignment operator
Restaurant Restaurant::operator=(const Restaurant &rightHandSide)
{
  delete [] table ; // return OLD table array to the heap
  
  numberOfTables = rightHandSide.numberOfTables;
  maxGuestsPerTable = rightHandSide.maxGuestsPerTable;
  
  // now allocate a new table array
  
  table = new Table[numberOfTables];
  for (int i = 0; i < numberOfTables; i++)
    {
      table[i] = rightHandSide.table[i];
    }

  return (*this); // return a copy of yourself
}


Restaurant::~Restaurant()
{
  // return the space for the table array to the heap
  delete [] table;
}

int Restaurant::getNumberOfTables()
{
  return numberOfTables;
}

int Restaurant::getMaxGuestsPerTable()
{
  return maxGuestsPerTable;
}


void Restaurant::reserveTable()
{
  int i;
  // find first open table
  for (i=0; i<numberOfTables && table[i].getNumberOfGuests()>0; i++)
    ; // for loop has empty body;	  
  
  // postcondition: if i < numberOfTables, table[i] is empty
  // postcondition: if i == numberOfTables, all tables are full
  
  if (i==numberOfTables)
    cout << "Sorry, all tables are full";
  else  
    {
      assert(i<numberOfTables); // assert precondition 
      int guests;
      cout << "Table " << i << " has space" << endl;
      cout << "How many guests? (0 to cancel) :" ;
      guests = getFirstInteger();
      while (guests > maxGuestsPerTable || guests < 0)
	{
	  cout << "Enter a number between 0 and " << maxGuestsPerTable << endl;
	  cout << "How many guests? (0 to cancel) :" ;
	  guests = getFirstInteger();
	}
      // reserve table
      table[i].setNumberOfGuests(guests);
      // postcondition: table[i] is between 0 and 4.
      assert(table[i].getNumberOfGuests() >= 0 &&
	     table[i].getNumberOfGuests() <= 4);
    }
}

void Restaurant::clearTable()
{
  cout << "Which table do you wish to clear? ";
  int i = getFirstInteger();
  if (i<0 || i>=numberOfTables)
    {
      cout << "Table number should be in range 0 to "
	   << numberOfTables -1 << endl;
    }	   
  else if (table[i].getNumberOfGuests() == 0)
    {
      cout << "That table is already clear \n" << endl;
    }
  else
    {
      cout << table[i].getNumberOfGuests() 
	   << " guests cleared from table " << i << endl;
      table[i].setNumberOfGuests(0);
    }
}

void Restaurant::printTableStatus()
{
  for (int i=0; i<numberOfTables; i++)
    {
      if (table[i].getNumberOfGuests() > 0)
	cout << "Table [" << i << "] has " 
	     << table[i].getNumberOfGuests() << " guests\n";
      else
	cout << "Table [" << i << "] is clear \n";
    }
  
}

