//

//   The main program demonstrating building a polymorphic list of
//   figures.   The figures are read interactively and entered into an
//   vector of Figure pointers.  An iterator is then used to step
//   through these figures to print them.
//
//   Note the difference between building the list and printing it.
//   When building the list we must be conscious of which type of
//   element we are handling.  After the list is built, this is done
//   automatically. 
 
#include <iostream>
#include <vector>		// vector container class from the standard library
#include <algorithm>         // generic algorithms from the standard library

#include "figure.h"

bool AreaCompare( Figure * lft, Figure * rgt )
{
	return lft->Area() < rgt->Area();
}


void
main( )
{
  std::vector< Figure * > figures;

  //  Here are input errors that are not caught by the program and
  //  will cause the program to abort.  A more sophisticated program
  //  would catch these.
  std::cin.exceptions(std::ios_base::badbit
                        | std::ios_base::failbit
                        | std::ios_base::eofbit);

  std::cout << "\nProgram demonstrating polymorphic list of shapes\n";
  bool done = false;

  do {
    std::cout << "\nEnter the next shape (r for rectangle, c for circle,\n"
			<< "s for sphere, q for square, y for cylinder, n to end) ==> ";
	char in_char;
	std::cin >> in_char;
	Figure * p;

    switch ( in_char ) {
    case 'R': case 'r':
		float height,width;
		std::cout << "Enter the rectangle's height and width ==> ";
		std::cin >> height >> width;
		p = new Rectangle( height, width );
		figures.push_back( p );
		break;
    case 'C': case 'c':
		float radius;
		std::cout << "Enter the circle's radius ==> ";
		std::cin >> radius;
        p = new Circle( radius );
		figures.push_back( p );
		break;
    case 'S': case 's':
		std::cout << "Enter the sphere's radius ==> ";
		std::cin >> radius;
		p = new Sphere( radius );
		figures.push_back( p );
		break;
    case 'Q': case 'q':
		float side;
		std::cout << "Enter the square's side ==> ";
		std::cin >> side;
		p = new Square( side);
		figures.push_back( p );
		break;
    case 'Y': case 'y':
		std::cout << "Enter the cylinder's radius and height ==> ";
		std::cin >> radius >> height;
        p = new Cylinder( radius, height );
		figures.push_back( p );
		break;
	case 'N': case 'n':
		done = true;	
		break;
    default:  // throw away rest of input line and output error message
		char input_line[256];
		if ( ! std::cin.getline( input_line, 256 ) ) done=true;
		std::cout << "Illegal input.  Rest of line ignored.\n";
    }
  } while ( ! done );

  std::sort( figures.begin(), figures.end(), AreaCompare );

  std::cout << "\n\nHere is the list of figures:\n";

  std::vector< Figure * >::iterator fig_itr;
  for ( fig_itr = figures.begin();
        fig_itr != figures.end(); fig_itr ++ ) {
	std::cout << "\n";
    (*fig_itr)->Output_Info( );
    std::cout << "Area: " << (*fig_itr)->Area()
			  << "  Volume: "  << (*fig_itr)->Volume() << std::endl;
  }
  std::cout << std::endl;
}
      
      

