#include "BinTree.h"

#include <string.h>
#include <iostream>

#if !defined(_RWSTD_NO_NAMESPACE)
using namespace std;
#endif

#if defined(__DECCXX)
static EZTools<BinTreeNode> i1("BinTreeNode");
static EZTools<BinTree> i2("BinTree");
#else
static EZTools<BinTreeNode> i1;
static EZTools<BinTree> i2;
#endif

BinTreeNode::BinTreeNode(const char *pName, int age) : m_Age(age)
{
  int i = 0;

  // truncate if too long
  while(pName[i] != '\0' && i < MaxNameLength)
  {
    m_Name[i] = pName[i];
    ++i;
  }

  m_Name[i] = '\0';
}

// recursive calls to EZDelete
BinTreeNode::~BinTreeNode()
{
  if(m_pLeftChild != 0)
    EZDelete(m_pLeftChild);

  if(m_pRightChild != 0)
    EZDelete(m_pRightChild);
}

// non-recursive insertion
void BinTree::AddToTree(const char *pName, int age)
{
  BinTreeNode **ppBinTreeNode = &m_pTopNode;
  int c;

  while(*ppBinTreeNode != 0)
  {
    c = strcmp(pName, (*ppBinTreeNode)->m_Name);
    if(c < 0)
      ppBinTreeNode = &((*ppBinTreeNode)->m_pLeftChild);
    else if(c > 0)
      ppBinTreeNode = &((*ppBinTreeNode)->m_pRightChild);
    else
      return;  // ignore, don't add duplicate to tree
  }

  // create and insert new BinTreeNode at the proper place
  (*ppBinTreeNode) = EZNew(BinTreeNode)(pName, age);
}

// recursive function to print a binary tree
void BinTree::PrintTree(const EZPtr<BinTreeNode> & ptr) const
{
  if(ptr->m_pLeftChild != 0)
    PrintTree(ptr->m_pLeftChild);

  cout << ptr->m_Name << ", " << ptr->m_Age << endl;

  if(ptr->m_pRightChild != 0)
    PrintTree(ptr->m_pRightChild);
}

void BinTree::PrintTree() const
{
  PrintTree(m_pTopNode);
}

int RandomAge()
{
  return rand() % 100;
}

const char * RandomName()
{
  static char Name[MaxNameLength+1];

  int size = rand() % (MaxNameLength+1);  // strlen
  if(size == 0)
    ++size;

  for(int i = 0; i < size; i++)
    Name[i] = 'a' + rand() % 26;

  Name[i] = '\0';

  return Name;
}
