/* Stash2.cpp */

#include "stash2.h"
#include <iostream>
#include <cassert>

using namespace std;


// Quantity of elements to add when increasing storage:
const int increment = 100;


Stash::Stash(int size) {
  this->size = size;
  quantity = 0;
  next = 0;
  storage = 0;
}



int Stash::add(const void *element) {
   // Enough space left?
  if(next >= quantity) {
    inflate(increment);
  }

  // Copy element into storage, starting at next empty space:
  int startBytes = next * size;
  unsigned char *e = (unsigned char *)element;

  for (int i = 0; i < size; i++) {
    storage[startBytes + i] = e[i];
  }
  next++;
  return (next - 1);
}



void *Stash::fetch(int index) {
  // Check index boundaries:
  assert(0 <= index);
  if(index >= next) {
    return 0;          // To indicate the end
  }
  // Produce pointer to desired element:
  return &(storage[index * size]);
}



int Stash::count() {
  // Number of elements in CStash:
  return next;
}



void Stash::inflate(int increase) {
  assert(increase > 0);
  int newQuantity = quantity + increase;
  int newBytes = newQuantity * size;
  int oldBytes = quantity * size;

  unsigned char *b = new unsigned char[newBytes];
  for (int i = 0; i < oldBytes; i++) {
    // Copy old to new:
    b[i] = storage[i];
  }

  // Old storage
  delete[] storage;

 // Point to new memory:
  storage = b;
  quantity = newQuantity;
}



Stash::~Stash() {
  if (storage != 0) {
    cout << "freeing storage" << endl;
    delete[] storage;
  }
}
