#ifndef _HashIndex_h
#define _HashIndex_h

#include "Vector3.h"

/*
CLASS
  HashIndex
  
  Defines a simple multi-dimensional index for the gemotric hash table 
  defined in class GeomHash.

KEYWORDS
  Geometric Hash

AUTHORS
  Meir Fuchs (mailto: meirfux@math.tau.ac.il)

CHANGES LOG
<UL>
<LI>
</UL

GOALS
  HashIndex defines a general purpose index for the geometric hash table. The
  index holds an array of floats whose maximal size is predetermined (i.e. the
  size is not dynamic as in vector). The goal is to define a well performing
  hash index which would be widely used there by enhancing the simplicity of
  the geometric hash table classes and reducing some code bloat.

  Elements are added to the back of the HashIndex using the add method or the
  << operator and are accessed using the [] operator. The HashIndex must be
  initialized with a default maximal size.

USAGE
  The following is an example of using the HashIndex class as an index to a
  GeomHash.
  EXAMPLE
    typedef GeomHash<HashIndex, int> GHash;
    GHash table;
    HashIndex index(5);           // maximal size 5.
    index.add(Vector3(1, 2, 3));  // use the add method for first 3 elements
    index << 4 << 5;              // use the << operator to add the last two.
    table.insert(index, 1);       // insert using the index
    GHash::Result result;
    table.query(index, result);   // query using the index. 
  END
*/

class HashIndex
{
public:
  //// Creates a default 0-size hash-index. HashIndex instances created using
  // this constructor have no use. The constructor is defined so that 
  // it will be available for subclassing and STL containers.
  HashIndex();

  //// Instantiates a HashIndex object of a given size. This size remains
  // constant throughout the life of the object. Space allocated for the
  // floating point parameters is deallocated in the HashIndex destructor.
  HashIndex(unsigned short indexSize);
  
  //// Destructor. Deallocates space of floats.
  ~HashIndex();

  //// HashIndex keeps a fixed size array of floats. float values may be added
  // sequentially using the add method. add methods called after the float
  // array is full are simply ignored. 
  void add(float value);

  //// HashIndex keeps a fixed size array of floats. 3 float values may be 
  // added sequentially using the add method. add methods called after the 
  // float array is full are simply ignored. 
  void add(const Vector3& v);

  //// Same as add method. The << operator allows adding several values in
  // one line of syntactically presentable code.
  HashIndex& operator<<(float value);

  //// Same as add method. The << operator allows adding several values in
  // one line of syntactically presentable code.
  HashIndex& operator<<(const Vector3& v);

  //// Empty the HashIndex object. The space is not deallocated but the 
  // add counter is reset. Immediately after a reset operation the values
  // inserted into a HashIndex object are still available.
  void reset();

  //// Returns a reference to the index'th place in the float array. This
  // may be used to change values within the array. If index is bigger than
  // the size of the array then index modulo array size is used.
  float& operator[](unsigned short index) const;
  
  //// Prints out all the hash index elements (spaces beteween elements).
  friend ostream& operator<<(ostream& out, HashIndex& hi);

private:
  unsigned short size;
  unsigned short used;
  float* values;
};

#endif

