/*************************************************
 * Lazy_deletion_tree_tester
 * A class for testing lazy trees
 *
 * Author:  Douglas Wilhelm Harder
 * Copyright (c) 2006-13 by Douglas Wilhelm Harder.  All rights reserved.
 *
 * DO NOT EDIT THIS FILE
 *************************************************/

#ifndef LAZY_DELETION_TREE_TESTER_H
#define LAZY_DELETION_TREE_TESTER_H

#ifndef nullptr
#define nullptr 0
#endif

#include "ece250.h"
#include "Exception.h"
#include "Tester.h"
#include "Lazy_deletion_tree.h"

#include <iostream>

template <typename Type>
class Lazy_deletion_tree_tester:public Tester< Lazy_deletion_tree<Type> > {
	using Tester< Lazy_deletion_tree<Type> >::object;
	using Tester< Lazy_deletion_tree<Type> >::command;

	public:
		Lazy_deletion_tree_tester( Lazy_deletion_tree<Type> *obj = 0 ):Tester< Lazy_deletion_tree<Type> >( obj ) {
			// empty
		}

		void process();
};

/****************************************************
 * void process()
 *
 * Process the current command.  For lazy trees, these include:
 *
 *           Member
 *   Flag   Function         Tests if ...
 *
 *  Accessors
 *   empty b                  empty                    the value of empty
 *   height n                 height                   the height of the tree equals n
 *   size n                   size                     the size of the tree equals n
 *   traverse                 breadth_first_traversal  perform a breadth-first traversal
 *                                                     the tree, printing it
 *   front n                  front                    the least element is the one given
 *   front!                   front                    there is no least element
 *   back n                   back                     the greatest element is the one given
 *   back!                    back                     there is no greatest element
 *   member n b               member                   check if n is in the tree
 *
 *  Mutators
 *   insert n b               insert                   insert a new node into the lazy tree
 *   erase n b                erase                    erase a node from the lazy tree
 *   clear                    clear                    clear the lazy tree
 *   clean                    clean                    clean the lazy tree
 *
 *  Others
 *   summary                         prints the amount of memory allocated
 *                                   minus the memory deallocated
 *   details                         prints a detailed description of which
 *                                   memory was allocated with details
 *   !!                              use the previous command, e.g.  5 push_front 3
 *                                                                   6 !! 7         // same as push_front 7
 *   !n                              use the command used in line n  7 front 7
 *                                                                   8 !7 9         // same as push_front 9
 ****************************************************/

template <typename Type>
void Lazy_deletion_tree_tester<Type>::process() {
	if ( command == "new" ) {
		object = new Lazy_deletion_tree<Type>();
		std::cout << "Okay" << std::endl;
	} else if ( command == "empty" ) {
		// check if empty equals the next Boolean value read

		bool expected_empty;

		std::cin >> expected_empty;

		bool actual_empty = object->empty();

		if ( actual_empty == expected_empty ) {
			std::cout << "Okay" << std::endl;
		} else {
			std::cout << ": Failure in empty(): expecting the value '" << expected_empty << "' but got '" << actual_empty << "'" << std::endl;
		}
	} else if ( command == "height" ) {
		// check if the height equals the next integer read

		int expected_height;

		std::cin >> expected_height;

		int actual_height = object->height();

		if ( actual_height == expected_height ) {
			std::cout << "Okay" << std::endl;
		} else {
			std::cout << ": Failure in height(): expecting the value '" << expected_height << "' but got '" << actual_height << "'" << std::endl;
		}
	} else if ( command == "size" ) {
		// check if the size equals the next integer read

		int expected_size;

		std::cin >> expected_size;

		int actual_size = object->size();

		if ( actual_size == expected_size ) {
			std::cout << "Okay" << std::endl;
		} else {
			std::cout << ": Failure in size(): expecting the value '" << expected_size << "' but got '" << actual_size << "'" << std::endl;
		}
	} else if ( command == "traverse" ) {
		object->breadth_first_traversal();
                std::cout << std::endl;
	}  else if ( command == "front" ) {
		// find the smallest element

		Type expected_front;

		std::cin >> expected_front;

		Type actual_front = object->front();

		if ( actual_front == expected_front ) {
			std::cout << "Okay" << std::endl;
		} else {
			std::cout << ": Failure in front(): expecting the value '" << expected_front << "' but got '" << actual_front << "'" << std::endl;
		}
	} else if ( command == "front!" ) {
		// front of an empty lazy tree - catch an exception

		Type actual_front;

		try {
			actual_front = object->front();
			std::cout << "Failure in front(): expecting to catch an exception but got '" << actual_front << "'" << std::endl;
		} catch( underflow ) {
			std::cout << "Okay" << std::endl;
		} catch (...) {
			std::cout << "Failure in front(): expecting an underflow exception but caught a different exception" << std::endl;
		}
	}  else if ( command == "back" ) {
		// find the largest element

		Type expected_back;

		std::cin >> expected_back;

		Type actual_back = object->back();

		if ( actual_back == expected_back ) {
			std::cout << "Okay" << std::endl;
		} else {
			std::cout << ": Failure in back(): expecting the value '" << expected_back << "' but got '" << actual_back << "'" << std::endl;
		}
	} else if ( command == "back!" ) {
		// back of an empty lazy tree - catch an exception

		Type actual_back;

		try {
			actual_back = object->back();
			std::cout << "Failure in back(): expecting to catch an exception but got '" << actual_back << "'" << std::endl;
		} catch( underflow ) {
			std::cout << "Okay" << std::endl;
		} catch (...) {
			std::cout << "Failure in back(): expecting an underflow exception but caught a different exception" << std::endl;
		}
	}  else if ( command == "member" ) {
		// check for membership

		bool expected_member;
		Type n;

		std::cin >> n;
		std::cin >> expected_member;

		bool actual_member = object->member( n );

		if ( actual_member == expected_member ) {
			std::cout << "Okay" << std::endl;
		} else {
			std::cout << ": Failure in member(" << n << "): expecting the value '" << expected_member << "' but got '" << actual_member << "'" << std::endl;
		}
	}  else if ( command == "insert" ) {
		// insert the next integer read onto the lazy tree

		bool expected_insert;
		Type n;

		std::cin >> n;
		std::cin >> expected_insert;

		bool actual_insert = object->insert( n );

		if ( actual_insert == expected_insert ) {
			std::cout << "Okay" << std::endl;
		} else {
			std::cout << ": Failure in insert(" << n << "): expecting the value '" << expected_insert << "' but got '" << actual_insert << "'" << std::endl;
		}
	} else if ( command == "erase" ) {
		// erase the first integer from the lazy tree

		bool expected_erase;
                Type n;

		std::cin >> n;
		std::cin >> expected_erase;

		bool actual_erase = object->erase( n );

		if ( actual_erase == expected_erase ) {
			std::cout << "Okay" << std::endl;
		} else {
			std::cout << ": Failure in erase(" << n << "): expecting the value '" << expected_erase << "' but got '" << actual_erase << "'" << std::endl;
		}
	} else if ( command == "clear" ) {
		object->clear();
		std::cout << "Okay" << std::endl;
	} else if ( command == "clean" ) {
		object->clean();
		std::cout << "Okay" << std::endl;
	} else {
		std::cout << command << ": Command not found." << std::endl;
	}
}
#endif