#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "bst_words.h"

// find where word is in the tree and return its parent
// if not in the tree then return what would be parent if
// we inserted
tree_t *bst_lookup_parent(tree_t *root, char *word) {
  if (root == NULL) return NULL;

  // look for word in the tree.  keep track of current
  // and its parent as we go.
  tree_t *current=root, *parent = NULL;
  while (current  != NULL) {
    int compare = strcmp(word, current->word);
    if (compare == 0) return parent; // found the word in the tree
    
    parent = current;
    
    if (compare < 0)
      current = current->left;
    else
      current = current->right;
  }

  return parent;
}

// make a new node - allocate memory, set right/left = NULL,
//   put in word and number
tree_t *bst_make_node(char *s, int n) {
  // create a new node 
  tree_t *t = (tree_t *) malloc(sizeof(tree_t));
  if (t == NULL) {
    fprintf(stderr, "malloc fail\n");
    exit(0);
  }
  t->word = strdup(s);
  t->num = n;
  t->left = t->right = NULL;
  
  return t;
}


// free memory from the node
void bst_free_node(tree_t *t) {
  if (t == NULL) return;
  if (t->word != NULL) free(t->word);
  free(t);
}


tree_t *bst_insert(tree_t *root, char *s, int n) {
  if (s == NULL) return root; // sanity check
      
  tree_t *t = bst_make_node(s, n);

  // NULL root is empty tree, so t is now the root, return it
  if (root == NULL) return t;

  // find where should be inserted (lookup)
  tree_t *parent = bst_lookup_parent(root, s);
  if (parent == NULL) {
    // root != NULL but parent==NULL means s is in the root
    bst_free_node(t);
    return root;
  }

  // there is a parent, let's see...
  int compare = strcmp(s, parent->word);
  if (compare < 0 && parent->left == NULL) // put on the left
    parent->left = t;
  else if (compare > 0 && parent->right == NULL) // put on the right
    parent->right = t;
  else // s is already in the tree
    bst_free_node(t);

  return root;
}


tree_t *bst_lookup(tree_t *root, char *word) {
  tree_t *current=root;
  while (current  != NULL) {
    if (strcmp(word, current->word) == 0) break;
    
    if (strcmp(word, current->word) < 0)
      current = current->left;
    else
      current = current->right;
  }
  return current;
}  

tree_t *bst_delete(tree_t *root, tree_t *p) {
  // needs to be completed
  return root;
}

// helper function for bst_print, prints the tree
//  with the # spaces indicating depth
void bst_print__(tree_t *root, int depth) {
  if (root == NULL) return;

  bst_print__(root->left, depth+1);
  printf("%*s%s : %d\n", depth, "", root->word, root->num);
  bst_print__(root->right, depth+1);
}

void bst_print(tree_t *root) {
  bst_print__(root, 0);
}