/**
 * This class represents the GDI2 B-Tree
 */

public class GDI2BTree 
{
	private GDI2BTreeNode root;	// the root of the B-Tree
	private int order;			// the order (=k) of the B-Tree
	
	// TODO: Specify other private data, variables	
	// TODO: Implement other necessary methods, e.g. a method to traverse the B-Tree
	
	/**
	 * This method inserts into the B-Tree the given key/entry (String)
	 * @param entry the value to add into the tree
	 * @return true - if successful, false otherwise
	 */
	public boolean addData(String entry) {
		// TODO: implement the method
		return false;
	}
	/**
	 * This method deletes from the B-Tree the given key/entry (String)
	 * @param entry the value to delete from the tree
	 * @return true - if successful, false otherwise
	 */
	public boolean delData(String entry) {
		// TODO: implement the method
		return false;
	}
	/**
	 * Checks if the given entry/key can be found in the B-Tree
	 * @param entry The entry/key which is to be found
	 * @return the B-Tree node containing the given key/entry (String), otherwise null
	 */
	public GDI2BTreeNode findData(String entry) {
		// TODO: implement this method
		return null;
	}
	/**
	 * Checks if the B-Tree is empty
	 * @return true - if B-Tree empty, otherwise false
	 */
	public boolean isBTreeEmpty()
	{
		// TODO: implement this method	
		return false;
	}
	/**
	 * This method prints the B-Tree
	 */
	public void printBTree()
	{
		// TODO: implement this method
		/*
		 * An example of the output is given below:
		 * 
		 * GDI2 B-Tree: order = 2, keys = 11, height = 2
		 * ------------------------------------------------
		 * [3,7,#,#]
		 * 
		 * [1,2,#,#] [4,5,6,#] [8,9,10,11]
		 * 
		 */
	}
	/**
	 * This method helps to check the correctness 
	 * of the B-Tree after adding/deleting data.
	 *
	 * You can and should extend/modify this method 
	 * to check the correctness of your B-Tree implementation.
	 * You are allowed to change the signature 
	 * of this methods according to your needs.
	 * 
	 * We will use a similar method 
	 * correctnessCheckPrivate(...) to test your implementation.
	 */
	public void correctnessCheckPublic()
	{
		// OPTIONAL TODO: extend/modify this method
		
		// the following checks are only some examples 
		
		// check if the root has data
		if (getRoot().hasKeys())
		{
			// check if the number of children is correct (root not being a leaf)
			if (!getRoot().isLeaf() && (getRoot().getData().size() + 1 < getRoot().getChildren().size()))
			{
				throw new GDI2BTreeFileFormatException(
						GDI2BTreeFileFormatException.GDI2TypeOfException.BTREE, 
						"Too many children.");
			}
			// check if the number of keys is conform to the given order
			if (getRoot().getData().size() > 2 * getOrder())
				throw new GDI2BTreeFileFormatException(
						GDI2BTreeFileFormatException.GDI2TypeOfException.BTREE, 
						"Too many keys - the given order is violated.");
		}
		// check if the root has children
		if (getRoot().hasChildren())
		{
			// check if root is a leaf
			if (getRoot().isLeaf())
				throw new GDI2BTreeFileFormatException(
						GDI2BTreeFileFormatException.GDI2TypeOfException.BTREE, 
						"It should not be possible for a leaf to have children.");
			// check if the correct number of children is provided
			if (getRoot().getData().size() >= getRoot().getChildren().size())
				throw new GDI2BTreeFileFormatException(
						GDI2BTreeFileFormatException.GDI2TypeOfException.BTREE, 
						"Too few children.");
		}
	}
	/**
	 * @param root the root to set
	 */
	public void setRoot(GDI2BTreeNode root) {
		this.root = root;
	}
	/**
	 * @return the root
	 */
	public GDI2BTreeNode getRoot() {
		return root;
	}
	/**
	 * @param order the order to set
	 */
	public void setOrder(int order) {
		this.order = order;
	}
	/**
	 * @return the order
	 */
	public int getOrder() {
		return order;
	}
}
