/* tables.c   T. Harvey, modified from P. Conrad   for CISC105, Fall 2004                         
* Sample program using an array                                  
* Number of guests at tables in a restaurant                             
* Tables are numbered 0 through NUM_TABLES - 1                           
*                                                                        
* Things to notice in this program                                       
*   (1) Use of #define to set array size (NUM_TABLES) and                
*       limit on table size                                              
*   (2) Structure of menu driven program                                 
*   (3) Use of "printWelcome();" and "printMenu();"                      
*       to remove long series of printf(...) from the main program       
*   (4) Use of "fgets(stdin,buffer,bufSize);" (file get string)                          
*   (5) Use of guests = readFirstInteger(); instead of scanf     
*   (6) Techniques to use with arrays: initializing (manually),          
*       finding first occurence of a value (in this case, 0),            
*       setting a particular value, printing out entire array.           
*   (7) Use of the assert statement (stops the program with an error
*       msg if condition is not met)
*   (8) Use of while loop to test for bogus input, ask again
*/

#define NUM_TABLES 6 /*  number of tables */
#define GUEST_MAX 4  /*  maximum guests per table */

#include <stdio.h>
#include <assert.h> /*  for assert() function */
#include <stdlib.h> /*  for atoi() function */

void printWelcome(void);
void printMenu(void);

/* Reads first character from a line of input */
char getFirstCharacter(void);

/* Reads first integer from a line of input */
int readFirstInteger(void);

/* Sets the number of guests for a table to zero */
void clearTable(int tables[]);

/* Finds first table with zero guests and fill it with your party. */
void fillFirstOpenTable(int tables[]);

int main(void)
{
  int table[NUM_TABLES];
  int i; /*  declare it here so it can be used throughout */
  char option; /* menu option chosen by user */

  printWelcome(); /* a great name like this doesn't need a comment */

  /*  clear all tables */
  for (i=0; i<NUM_TABLES; i++) 
      table[i]= 0; /* What is another way you could do this?*/

  /*  postcondition: all tables from 0 to NUM_TABLES - 1 have 0 guests */
  
  printMenu();

  option = getFirstCharacter(); /*  instead of scanf("%c",&option); */
  while (option != 'Q' && option != 'q') {
      switch (option) {

      case 'R': case 'r':
          /* This option puts the specified number of people at a
             specific table; we pass it the ARRAY table */
          fillFirstOpenTable(table);    
          break;
      case 'C': case 'c':
          clearTable(table);
          break;
      case 'P': case 'p':
          for (i=0; i<NUM_TABLES; i++) {
              if (table[i] > 0)
                  printf("Table [%d] has %d  guests\n", i,  table[i]);
              else
                  printf("Table [%d] is clear \n", i);
          }
          break;
      default:
          printf("Sorry, option %c not understood.\n", option);
          break;
      }//end switch
      
      printMenu();
      option = getFirstCharacter();
  }//end while
  
  printf("Thanks. Come again soon!\n");
  return 0;
}


void printWelcome(void)
{
  printf("Welcome to the restaurant table manager program. \n");
  printf("\n");
  printf("Because the restaurant owner loves C programming,\n"); 
  printf("tables are numbered from 0 through %d\n", NUM_TABLES -1);
  printf("\n");
  printf("Initially all tables are empty, "
         "and can hold up to four guests.\n");
  printf("\n");
  return;
}

void printMenu(void)
{
  printf("\n");
  printf("Enter R to reserve a table\n");
  printf("      C to clear a table\n");
  printf("      P to print status of all tables\n");
  printf("      Q to quit\n");
  printf("Enter option: ");
  return;
}

char getFirstCharacter(void)
{
  /*  reads in an entire line of text up to the newline, */
  /*  returns the first character read, and throws away the rest */
  const int bufSize=1024;
  char buffer[bufSize];
  fgets(buffer,bufSize,stdin);
  return buffer[0];
}

int readFirstInteger(void)
{
  /*  reads in an entire line of text up to the newline, */
  /*  convert the first integer you find in the string */
  /*    from ascii to integer (atoi) */
  /*  if conversion can't be performed, atoi returns 0 */

  const int bufSize=1024;
  char buffer[bufSize];
  fgets(buffer,bufSize,stdin);
  return atoi(buffer);
}

void fillFirstOpenTable(int tables[]){

    int tableNumber;
    /*  find first open table */
          
    tableNumber = 0;
    while(tableNumber < NUM_TABLES && tables[tableNumber] > 0)
        tableNumber++;
    
    /*  postcondition: if tableNumber < NUM_TABLES, tables[i] is empty */
    /*  postcondition: if tableNumber == NUM_TABLES, all tables are full */

    if (tableNumber == NUM_TABLES)
        printf("Sorry, all tables are full.\n");
    else {
        int numGuests;
            
        assert(tableNumber<NUM_TABLES); /*  assert precondition  */
        printf("Table %d has space\n", tableNumber);
        printf("How many guests? (0 to cancel) :") ;
            
        /* NOTE: Here is a classic way to read in data and then
           ask for a correction, over and over, until the user
           puts in a valid number. Very useful.*/
        numGuests = readFirstInteger();
        while (numGuests > GUEST_MAX || numGuests < 0) {

            printf("Enter a number between 0 and %d\n" , GUEST_MAX);
            printf("How many guests? (0 to cancel) :");
            numGuests = readFirstInteger();
        }
        /* fill table (finally!) */
        tables[tableNumber] = numGuests;
            
        /*  postcondition: tables[tableNumber] is between 0 and GUEST_MAX. */
        assert(tables[tableNumber] >= 0 && tables[tableNumber] <= GUEST_MAX);
    }
}//end of void fillFirstOpenTable(int tables[])

void clearTable(int tables[]){
        
    int tableNumber;

    printf("Which table do you wish to clear? ");
    tableNumber = readFirstInteger();
    if (tableNumber<0 || tableNumber>=NUM_TABLES) {
        printf("Table number should be in range 0 to %d\n",
               NUM_TABLES -1 );
    }      
    else if (tables[tableNumber] == 0) {
        printf("That table is already clear \n"); 
    }
    else {
        printf("%d guests cleared from table %d.\n", tables[tableNumber], tableNumber);
        tables[tableNumber] = 0;
    }
}

