#include "dset.h"

dset::dset()
{
  datatree = NULL;
  numnodes = 0;
}

dset::~dset()
{
  clear();
}

int dset::clear()
{
  rm(datatree);
  datatree = NULL;
  return 0;
}

int dset::rm(dnode *n)
{
  if(n == NULL)
    return 0;
  rm(n->left);
  rm(n->right);
  delete n;
  return 0;
}

int dset::insert(unsigned int id, double amount)
{
  //depth = 0;
  return insert(&datatree, id, amount);
}

int dset::insert(dnode **n, unsigned int id, double amount)
{
  //depth++;
  if(*n == NULL)
    {
      //numnodes++;
      //std::cout << numnodes << " " << depth << "\n";
      *n = new dnode;
      //      std::cout << "new\n";
      (*n)->data.data = amount;
      (*n)->data.id = id;
      (*n)->left = (*n)->right = NULL;
      return 0;
    }
  else if((*n)->data.id == id)
    {
      //std::cout << numnodes << " " << depth << "\n";
      //      std::cout << "old\n";
      (*n)->data.data += amount;
      return 0;
    }
  else if(id < (*n)->data.id)
    return insert(&( (*n)->left), id, amount);
  else
    return insert(&( (*n)->right), id, amount);
}

int dset::print()
{
  //degree = numnodes = 0;
  //leaves = 0;
  print(datatree);
  //std::cout << numnodes << " " << degree << " " << leaves << "\n";
  return 0;
}

std::vector< std::pair<float, unsigned int> > dset::desclist()
{
  std::vector< std::pair<float, unsigned int> > l;
  print(datatree, l);
  return l;
}

int dset::print(dnode *n)
{
  if(n == NULL)
    return 0;
#ifdef __DEBUG__
  numnodes++;
  if(n->left == NULL &&  n->right == NULL)
    leaves++;

  if(n->left != NULL)
    degree++;
  if(n->right != NULL)
    degree++;
#endif
  print(n->left);
  std::cout << n->data.data << "\t" << n->data.id << "\n";
  print(n->right);
  return 0;
}

int dset::print(dnode *n, std::vector< std::pair<float, unsigned int> > &dlist)
{
  if(n == NULL)
    return 0;
#ifdef __DEBUG__
  numnodes++;
  if(n->left == NULL &&  n->right == NULL)
    leaves++;

  if(n->left != NULL)
    degree++;
  if(n->right != NULL)
    degree++;
#endif
  print(n->left, dlist);
  dlist.push_back( std::pair<float, unsigned int>(n->data.data, n->data.id) );
  print(n->right, dlist);
  return 0;
}
