#pragma once

#include <memory>

template<typename T>
class Node
{
public:
	Node(T data)
		: mData(data)
	{}

	void addChild(std::unique_ptr<Node> child)
	{
		if(!mLeftChild)
		{
			mLeftChild = std::move(child);
		}
		else
		{
			mRightChild = std::move(child);
		}
	}

	bool isLeaf() const
	{
		return !mLeftChild && !mRightChild;
	}

	T getData() const
	{
		return mData;
	}

private:
	T mData;
	unsigned char mTag{0};
	std::unique_ptr<Node> mLeftChild;
	std::unique_ptr<Node> mRightChild;
};

template<typename T>
using NodePtr = std::unique_ptr<Node<T> >;

template<typename T>
class Tree
{
public:
	Tree()
	{

	}

	void addRootNode(NodePtr<T> root)
	{
		mRootNode = std::move(root);
	}

	Node<T>* getRootNode() const
	{
		return mRootNode.get();
	}

private:
	NodePtr<T> mRootNode;
};
