#ifndef ARRAY_H
#define ARRAY_H
static char array_h_id[] = "$Header: /usr/tiburon/xPlatform/utils/RCS/array.h,v 1.5 1998/06/09 21:13:21 oreilly Exp pean $";

/*
$Log: array.h,v $
Revision 1.5  1998/06/09 21:13:21  oreilly
VxWorks needs memLib.h instead of malloc.h

Revision 1.4  1997/03/20 12:27:01  oreilly
*** empty log message ***

 * Revision 1.3  96/10/28  09:00:36  09:00:36  oreilly (Thomas C. O'Reilly)
 * *** empty log message ***
 * 
*/


#include <stdio.h>
#ifdef UNIX
# include <malloc.h>
# include <sys/param.h>
#else
# include <memLib.h>
# include <mbari/param.h>
#endif

#include "mbariConst.h"

template<class T>
class DynArray {

  public:
  // Constructor
  DynArray(int incr = 10) {

    if (incr <= 0)    
    {
      mem_error = TRUE;
      return;
    }
    n_elems = 0;
    n_allocd = 0;
    alloc_incr = incr;
  }

  // Destructor
  ~DynArray() {
    if (n_allocd)
      free(array);
  }

  // Set specified element to specified value
  int set(int i, T* val)
  {
    if (i < 0)
    {
      mem_error = TRUE;
      return -1;
    }

    if (i >= n_allocd)
    {
      // Compute blocks needed to index specified element
      int nblocks = (i + 1) / alloc_incr;
      if ((i+1) % alloc_incr)
        nblocks++;

      if (!n_allocd)
      {
        n_allocd = nblocks * alloc_incr;
        if ((array = (T *)malloc(n_allocd*sizeof(T))) == NULL)
        {
          mem_error = TRUE;
          return -1;
        }
      }
      else
      {
        n_allocd += (nblocks * alloc_incr);
        if ((array = (T *)realloc(array, n_allocd*sizeof(T))) == NULL)
        {
          mem_error = TRUE;
          return -1;
        }
      }
    }
    array[i] = *val;
    mem_error = FALSE;
    n_elems = MAX((i+1), n_elems);
    return 0;
  }

  // Get value of specified element
  int get(int i, T* val)
  {
    if (i < 0 || i >= n_elems)
    {
      mem_error = TRUE;
      return -1;
    }
    *val = array[i];
    mem_error = FALSE;
    return 0;
  }

  int size() 
  {
    return n_elems;
  }
  
  int get_n_elems() { return n_elems; }
  int get_n_allocd() { return n_allocd; }
  T *get_array() { return array; }

  // Add element to end of list
  int add(T* val)
  { 
    return set(size(), val);
  }
  
  void clear()
  {
    n_elems = 0;
  }
  
  // Check for memory allocation error
  MBool mem_error;
 
  private:
  T *array;
  int n_elems;
  int n_allocd;

  // Size of malloc'ed and realloc'ed blocks (in # elems)
  int alloc_incr;

};


#endif
