#ifndef _ARRAY_H
#define _ARRAY_H

#include <string.h>

// for efficiency we allow only 3 dimensional arrays, should be more
// than enough and not hard to change, I could use variable argument
// lists but that is not fast enough
template<class T>
class Array
{
public:
  Array() {
    sizes[0] = sizes[1] = sizes[2] = 0;
    ptr = NULL;
  }
  Array(long dim1, long dim2 = 1, long dim3 = 1) {
    sizes[0] = dim1; sizes[1] = dim1*dim2; sizes[2] = sizes[1]*dim3;
    ptr = new T[sizes[2]];
  }
  ~Array() { delete [] ptr; }

  T &operator ()(long dim1) { return *(ptr+dim1); }

  T &operator ()(long dim1, long dim2) {
    return *(ptr+dim1+dim2*sizes[0]);
  }

  T &operator ()(long dim1, long dim2, long dim3) {
    return *(ptr+dim1+dim2*sizes[0]+dim3*sizes[1]);
  }

  // resize will destroy the arrays current contents so use it
  // carefully
  void Resize(long dim1, long dim2 = 1, long dim3 = 1) {
    delete [] ptr;
    sizes[0] = dim1; sizes[1] = dim1*dim2; sizes[2] = sizes[1]*dim3;
    ptr = new T[sizes[2]];
  }

  // relinquishes ownership of the array
  T *GetArray() {
    T *ptr1 = ptr;
    sizes[0] = sizes[1] = sizes[2] = 0;
    ptr = NULL;
    return ptr1;
  }

  void CopyFrom(T *src)
  { memcpy(ptr, src, (unsigned)Size()); }

  T *GetFirst() { return ptr; }

  long Size() { return sizes[2]*sizeof(T); }

private:
  T *ptr;
  long sizes[3];
};

#endif
