// ATS.cpp (Automated Test Sequence) and User Interface.
// Object Model Demonstration using Bonsai. A bonsai is a non-empty set of trees
// in a bonsai pot. The term "bonsai" is both singular and plural.
// Version 1.12.
// Copyright 1999 by Rick Wagner, all rights reserved. Authorized use with
// attribution for educational purposes only.
// Created September 25, 1999.
// Last edited Nobember 5, 1999.

#include "Bonsai.h"
#include <conio.h>                                   // For getch().
#include <ctype.h>                                   // For toupper().

const char* gsVerNum = "Version 1.12";

// UI function prototypes:
void mainMenu(Collection* c);                        // Main menu.
void addTreesToStock(Collection* c);                 // Add trees to material stock in yard.
void addPotsToStock(Collection* c);                  // Add pots to shelf of empty pots.
void addBonsaiToCollection(Collection* c);           // Add bonsai to the bonsai collection.
void showBonsai(Collection* c);                      // Show bonsai data.
void autoBuildCollection(Collection* c);             // For test purposes.

void main()                                          // Start the user interface.
{
  Collection c;                                      // Using automatic memory.
  mainMenu(&c);                                      // Pass a pointer.
}

void mainMenu(Collection* c)
{
  char cChoice = 0;                                  // Choice selection variable.
  int iBeenBuilt = 0;                                // Only build test data once.

  while (cChoice != 'X')                             // Repeat until user wants out.
  {
    cout << "                     Bonsai Collection Program " << gsVerNum << endl << endl
         << "Main Menu"<< endl << endl << endl;
    cout << "  A. Add trees to yard stock." << endl;
    cout << "  B. Add pots to shelf stock." << endl;
    cout << "  C. Add bonsai to collection." << endl;
    cout << "  D. Show bonsai collection information." << endl;
    if (!iBeenBuilt) cout << "  E. Build hard-coded bonsai collection for test purposes." << endl;
    cout << endl << "  X. Exit program." << endl << endl;
    cout << endl << endl << endl << endl << endl << endl << endl;
    cout << "Please enter your selection: ";
    cin >> cChoice;
    cChoice = toupper(cChoice);
    switch (cChoice)
    {
      case 'A': addTreesToStock(c); break;
      case 'B': addPotsToStock(c); break;
      case 'C': addBonsaiToCollection(c); break;
      case 'D': showBonsai(c); break;
      case 'E': autoBuildCollection(c); iBeenBuilt = 1; break;
    }
  }
  cout << "Goodbye... ";
}

void addTreesToStock(Collection* c)
{
  int m = 0;                                            // Number of trees in stock.
  int n = 0;                                            // Number of trees to add.
  int i = 0;
  char cTemp[giMaxNameLength];                          // Temporary input variable.
  Tree* t;

  cout << endl << endl;
  cout << "How many trees do you want to add to stock: ";
  cin >> n;
  cout << endl;

  for (i = 0; i < n; i++)
  {
    m = c->getNumTrees();
    cout << endl << m << " trees in stock now." << endl;

    t = new Tree();
    c->addTree(t);

    cout << endl << "Enter the name of tree " << i + 1 << ": ";
    cin >> cTemp;

    t->setName(cTemp);

    cout << "Enter the species of tree " << i + 1 << ": ";
    cin >> cTemp;
    t->setSpecies(cTemp);
  }
  m = c->getNumTrees();
  cout << endl << m << " trees in stock now. Press any key to continue..." << endl;
  getch();
  cout << endl << endl << endl << endl << endl << endl << endl << endl;
}

void addPotsToStock(Collection* c)
{
  int m = 0;                                            // Number of pots in stock.
  int n = 0;                                            // Number of pots to add.
  int i = 0;
  float sfTemp;                                         // Temporary input variable.
  char cTemp[giMaxNameLength];                          // Temporary input variable.
  Pot* p;

  cout << endl << endl;
  cout << "How many pots do you want to add to stock: ";
  cin >> n;
  cout << endl;

  for (i = 0; i < n; i++)
  {
    m = c->getNumPots();
    cout << endl << m << " pots in stock now." << endl;

    p = new Pot();
    c->addPot(p);

    cout << endl << "Enter the size of pot " << i + 1 << " (inches): ";
    cin >> sfTemp;
    p->setSize(sfTemp);

    cout << "Enter the style of pot " << i + 1 << ": ";
    cin >> cTemp;
    p->setStyle(cTemp);

    cout << "Enter the color of pot " << i + 1 << ": ";
    cin >> cTemp;
    p->setColor(cTemp);

    cout << "Enter the country of origin of pot " << i + 1 << ": ";
    cin >> cTemp;
    p->setCountry(cTemp);
  }
  m = c->getNumPots();
  cout << endl << m << " Pots in stock now. Press any key to continue..." << endl;
  getch();
  cout << endl << endl << endl << endl << endl << endl << endl << endl;
}

void addBonsaiToCollection(Collection* c)
{
  int m1 = 0;                               // Number of trees in collection (total).
  int m2 = 0;                               // Number of pots in collection (total).
  int m3 = 0;                               // Number of bonsai in collection.
  int n = 0;                                // Number of bonsai to add.
  int iNumTrees;                            // Number of trees in ith bonai.
  int i = 0;
  int j = 0;
  int k = 0;
  int iTemp;                                // Temporary input variable.
  char cTemp[giMaxNameLength];              // Temporary input variable.
  Tree* t;
  Pot* p;
  Bonsai* b;

  cout << endl << endl;
  cout << "How many bonsai do you want to add to the collection? ";
  cin >> n;
  cout << endl;

  m1 = c->getNumTrees();
  m2 = c->getNumPots();

  for (i = 0; i < n; i++)
  {
    m3 = c->getNumBonsai();

    cout << endl << m3 << " bonsai in the collection now." << endl << endl;
    cout << "Enter the label for bonsai " << i + 1 << ": ";
    cin >> cTemp;

    b = new Bonsai(cTemp);
    c->addBonsai(b);

    for (j = 0; j < m2; j ++)
    {
      p = c->getPot(j);
      if (p->getPartOf() == NULL)                               // Only unused pots are avaialble.
      {
        cout << j << ".  " << p->getSize() << "  " << p->getColor() << "  "
             << p->getStyle() << "  from  " << p->getCountry() << endl;
      }
    }
    cout << endl << "Which pot for bonsai " << i + 1 << "? ";
    cin >> iTemp;
    b->setPot(c->getPot(iTemp));

    cout << endl<< "How many trees for bonsai " << i + 1 << "? ";
    cin >> iNumTrees;

    for (j = 0; j < iNumTrees; j++)
    {
      for (k = 0; k < m1; k++)
      {
        t = c->getTree(k);
        if (t->getPartOf() == NULL)                             // Only unused trees are avaialble.
        {
          cout << k << ".  " << t->getName() << "  " << t->getSpecies() << endl;
        }
      }
      cout << endl << "Which tree for bonsai " << i + 1 << " tree " << j + 1 << "? ";
      cin >> iTemp;
      b->addTree(c->getTree(iTemp));
    }
  }
  m3 = c->getNumBonsai();
  cout << endl << m3 << " Bonsai in the collection now. Press any key to continue..." << endl;
  getch();
  cout << endl << endl << endl << endl << endl << endl << endl << endl;
}

void showBonsai(Collection* c)
{
  int i = 0;
  int j = 0;
  int n = 0;
  int iNumTrees = 0;
  Bonsai* b;
  Pot* p;
  int iLineCounter = 0;                                         // Count lines to control scrolling.

  n = c->getNumBonsai();
  cout << "Collection information for " << n << " bonsai: " << endl;
  iLineCounter++;

  for (i = 0; i < n; i++)
  {
    b = c->getBonsai(i);
    iNumTrees = b->getNumTrees();
    if (iLineCounter >= 18)
    {
      iLineCounter = 4;
      cout << endl << "Press any key for more..." << endl;
      getch();
    }
    cout << endl << "Bonsai " << i + 1 << " has " << iNumTrees << " trees in it:" << endl << endl;
    iLineCounter++; iLineCounter++; iLineCounter++;
    for (j = 0; j < iNumTrees; j++)
    {
      if (iLineCounter >= 20)
      {
        iLineCounter = 4;
        cout << endl << "Press any key for more..." << endl;
        getch();
      }
      cout << "  " << j + 1 << " ";
      cout << b->getTree(j)->getName() << " ";
      cout << b->getTree(j)->getSpecies() << endl;
      iLineCounter++;
    }
    p = b->getPot();
    cout << endl << "Bonsai " << i + 1 << " is in "
         << p->getSize() << " inch " << p->getColor() << " "
         << p->getStyle() << " pot from " << p->getCountry() << "." << endl;
    iLineCounter++; iLineCounter++;
    if (iLineCounter >= 23)
    {
      iLineCounter = 2;
      cout << endl << "Press any key for more..." << endl;
      getch();
    }
  }
  cout << endl << "Press any key to continue..." << endl;
  getch();
  cout << endl << endl << endl << endl << endl << endl << endl << endl;
}

void autoBuildCollection(Collection* c)
{
  Tree *t1, *t2, *t3, *t4, *t5, *t6, *t7;
  Pot *p1, *p2, *p3, *p4, *p5;
  Bonsai *b1, *b2, *b3;

  t1 = new Tree("Gnarley old Oak", "Black Oak");
  t2 = new Tree("Straight old Oak", "Black Oak");
  t3 = new Tree("Venerable old Oak", "Black Oak");
  t4 = new Tree("Green", "Black Pine");
  t5 = new Tree("Brown", "Monterey Pine");
  t6 = new Tree("Young", "Cherry");
  t7 = new Tree("Flowering", "Quince");

  c->addTree(t1);
  c->addTree(t2);
  c->addTree(t3);
  c->addTree(t4);
  c->addTree(t5);
  c->addTree(t6);
  c->addTree(t7);

  p1 = new Pot(12, "Oval", "Brown", "Japan");
  p2 = new Pot(13, "Round", "Gray", "Japan");
  p3 = new Pot(17, "Rectangular", "Brown", "China");
  p4 = new Pot(8, "Square", "Gray", "Japan");
  p5 = new Pot(10, "Cascade", "Brown", "Korea");

  c->addPot(p1);
  c->addPot(p2);
  c->addPot(p3);
  c->addPot(p4);
  c->addPot(p5);

  b1 = new Bonsai("Single");
  b2 = new Bonsai("Double");
  b3 = new Bonsai("Triple");

  b1->setPot(p1);
  b1->addTree(t1);

  b2->setPot(p3);
  b2->addTree(t2);
  b2->addTree(t3);

  b3->setPot(p5);
  b3->addTree(t4);
  b3->addTree(t5);
  b3->addTree(t7);

  c->addBonsai(b1);
  c->addBonsai(b2);
  c->addBonsai(b3);

  cout << endl << c->getNumTrees() << " trees, "
       << c->getNumPots() << " pots, and "
       << c->getNumBonsai()
       << " bonsai in the collection now.\nPress any key to continue..."
       << endl;
  getch();
  cout << endl << endl << endl << endl << endl << endl << endl << endl;

}