//
//  NAME
//    asgn3.cpp
//
//  DESCRIPTION
//    This file contains the functions in the Main module.
//    This module contains the top-level functions of the program.
//


//
//  Include files.
//

#include <iostream.h>
#include "bool.h"        //  You may comment this line out.
#include "expr.h"
#include "parse.h"


//
//  Function prototypes.
//

static void displayMenu();
static int  chooseExpr();
static void doEnter(expr * exprs[]);
static void doDisplay(expr * exprs[]);
static void doEvaluate(expr * exprs[]);
static void doClear(expr * exprs[]);
static void doJoin(expr * exprs[]);


//
//  NAME
//    main
//
//  DESCRIPTION
//    This function is the top-level function of the program.
//
//  PARAMETERS
//    (none)
//
//  RETURNS
//    0
//

int main() {
   char   choice;
   bool   done = false;
   expr * exprs[2];

   exprs[0] = new constant(0.0);
   exprs[1] = new constant(0.0);

   while (!done) {
      displayMenu();
      cin >> choice;

      switch (choice) {
         case '1': doEnter(exprs);    break;
         case '2': doDisplay(exprs);  break;
         case '3': doEvaluate(exprs); break;
         case '4': doClear(exprs);    break;
         case '5': doJoin(exprs);     break;
         case '6': done = true;       break;
         }

      }

   delete exprs[0];
   delete exprs[1]; 

   return 0;
}


//
//  NAME
//    displayMenu
//
//  DESCRIPTION
//    This function displays the menu to the standard output.
//
//  PARAMETERS
//    (none)
//
//  RETURNS
//    (none)
//

static void displayMenu() {
   cout << endl
        << "1.  Enter expression"      << endl
        << "2.  Display expression"    << endl
        << "3.  Evaluate expression"   << endl
        << "4.  Clear expression"      << endl
        << "5.  Join expressions"      << endl
        << "6.  Quit"                  << endl
        << endl
        << "> ";
}


//
//  NAME
//    chooseExpr
//
//  DESCRIPTION
//    This function prompts the user to choose an expression, then
//    returns value entered.
//
//  PARAMETERS
//    (none)
//
//  RETURNS
//    value entered
//

static int chooseExpr() {
   int choice;

   cout << endl;
   cout << "Which expression (1 or 2): ";
   cin  >> choice;
   return choice-1;
}


//
//  NAME
//    doEnter
//
//  DESCRIPTION
//    This function reads in an expression from the user.
//
//  PARAMETERS
//    exprs  (in/out) - array of expressions.
//
//  RETURNS
//    (none)
//

static void doEnter(expr * exprs[]) {
   char str[100];
   int  index;

   cout << endl << "Enter an expression: ";
   cin.getline(str, 100);
   cin.getline(str, 100);

   index = chooseExpr();
   delete exprs[index];
   exprs[index] = parse(str);
}


//
//  NAME
//    doDisplay
//
//  DESCRIPTION
//    This function displays an expression
//
//  PARAMETERS
//    exprs  (in/out) - array of expressions.
//
//  RETURNS
//    (none)
//

static void doDisplay(expr * exprs[]) {
   (exprs[chooseExpr()]->display(cout << endl)) << endl;
}


//
//  NAME
//    doEvaluate
//
//  DESCRIPTION
//    This function evaluates an expression
//
//  PARAMETERS
//    exprs  (in/out) - array of expressions.
//
//  RETURNS
//    (none)
//

static void doEvaluate(expr * exprs[]) {
   int index;

   index = chooseExpr();
   cout << endl;
   cout << exprs[index]->evaluate() << endl;
}


//
//  NAME
//    doClear
//
//  DESCRIPTION
//    This function resets an expression to zero.
//
//  PARAMETERS
//    exprs  (in/out) - array of expressions.
//
//  RETURNS
//    (none)
//

static void doClear(expr * exprs[]) {
   int  index;

   index = chooseExpr();
   delete exprs[index];
   exprs[index] = new constant(0.0);

   return;
}


//
//  NAME
//    doJoin
//
//  DESCRIPTION
//    This function joins two expressions
//
//  PARAMETERS
//    exprs  (in/out) - array of expressions.
//
//  RETURNS
//    (none)
//

static void doJoin(expr * exprs[]) {
   char                 choice;
   composite::operation oper;

   cout << endl << "Which operation?" << endl
        << "  1. Addition" << endl
        << "  2. Subtraction" << endl
        << "  3. Multiplication" << endl
        << "  4. Division" << endl
        << endl
        << "> ";

   cin >> choice;

   switch (choice) {
      case '1': oper = composite::Addition;       break;
      case '2': oper = composite::Subtraction;    break;
      case '3': oper = composite::Multiplication; break;
      case '4': oper = composite::Division;       break;
      default:  oper = composite::Addition;       break;
      }

   exprs[0] = new composite(oper, exprs[0], exprs[1]->clone());

   return;
}


//
//  End of file.
//