#ifndef B_TREE_H
#define B_TREE_H

/*****************************************
 * UW User ID:  pagunnew
 * Submitted for ECE 250
 * Department of Electrical and Computer Engineering
 * University of Waterloo
 * Calender Term of Submission:  Winter 2011
 *
 * By submitting this file, I affirm that
 * I am the author of all modifications to
 * the provided code.
 *****************************************/

#include "ece250.h"
#include "B_tree_node.h"

template <typename Object>
class B_tree;

template <typename Object>
class B_tree {
	private:
		B_tree_node<Object> *tree_root;

	public:
		B_tree();
		~B_tree();

		B_tree_node<Object> *root() const;
		int        size() const;
		bool       empty() const;
		int        count( Object const & ) const;
		void       draw() const;

		void       insert( Object const & );
};

template <typename Object>
B_tree<Object>::B_tree():tree_root( new B_tree_node<Object>() ) {
	// Constructor
	//tree_root = new B_tree_node<Object>;
}

template <typename Object>
B_tree<Object>::~B_tree() {
    // Destructor
    delete tree_root;
}

template <typename Object>
B_tree_node<Object> *B_tree<Object>::root() const {
    // Returns the root pointer
	return tree_root;
}

template <typename Object>
bool B_tree<Object>::empty() const {
    // Returns true if the tree is empty, false otherwise
	return tree_root->empty();
}

template <typename Object>
int B_tree<Object>::size() const {
    // Returns the number of items in the tree
	return tree_root->size();
}

template <typename Object>
int B_tree<Object>::count( Object const &obj ) const {
    //Returns 1 if the argument is stored by one of the nodes in the tree and 0 otherwise
	return tree_root->count(obj);
}

template <typename Object>
void B_tree<Object>::draw() const {
	tree_root->draw();
}

template <typename Object>
void B_tree<Object>::insert( Object const &obj ) {
    // Inserts an object into the root node
    B_tree_node<Object> *ptr = tree_root->insert(obj);

    // Case where node was full and had to be split
    if(ptr != 0)
    {
        // There is a new internal root node
        tree_root = new B_tree_node<Object>(tree_root, ptr);
    }
}

#endif

