using namespace std;

#include "hashmap.h"
#include "treemap.h"

/**
 * Constructs an empty map.
 */

HashMap::HashMap()
{
  numBuckets = DEFAULT_BUCKETS;
  buckets = new TreeMap[numBuckets];

  numItems = 0;
}

/**
 * pre: none
 * post: destroys this map
 */

HashMap::~HashMap()
{
  delete[] buckets;
}

/**
 * pre: none
 * post: returns the number of items on the TreeMap.
 */

int HashMap::getSize() const
{
  return numItems;
}

/**
 * pre: the given item is in the map
 * post: the value associated with the given item is returned
 */

HashMap::ValueType HashMap::getValue(const ItemType& i) const
{
  // find the item in the appropriate bucket
  return buckets[hashValue(i)].getValue(i);
}

/**
 * pre: none
 * post: returns true iff the given item is in this map
 */

bool HashMap::contains(const ItemType& i) const
{
  // check for the item in the appropriate bucket
  return buckets[hashValue(i)].contains(i);
}

/**
 * pre: none
 * post: this map is empty
 */

void HashMap::makeEmpty()
{
  // empty each bucket
  for (int b = 0; b < numBuckets; b++)
    buckets[b].makeEmpty();

  numItems = 0;
}

/**
 * pre: the given item isn't already in the map and the map isn't full
 * post: item toAdd has been added to the TreeMap and associated with
 * the given value
 */

void HashMap::addItem(const ItemType& i, const ValueType& val)
{
  if (!contains(i))
    numItems++;

  // put the item/value pair in the appropriate bucket
  buckets[hashValue(i)].addItem(i, val);
}


/**
 * pre: none
 * post: returns the hash value of the given item
 */

int HashMap::hashValue(const ItemType& i) const
{
  // this works for strings; in practice each Item class would provide
  // its own hashValue method

  int tot = 0;

  for (int pos = 0; pos < i.length(); pos++)
    tot += i[pos];

  return (tot % numBuckets);
}

