// ----------------------------------------------------------------------------
//
// Copyright (C) Columbia University, 1994. All Rights Reserved.
// Sameer A. Nene, Shree K. Nayar, Hiroshi Murase
//
// See file LICENSE for details of software license agreement.
//
// ----------------------------------------------------------------------------
//
// dataset.h
//
// Author:               Sameer Nene
// Date:                 05/24/94
// Version:              1.0
// Modification History:
//   06/26/94: Added feature to change dimensionality of the DataSet
//             dynamically
//   07/10/94: Added getText() and putText() to load/store dataset in text
//             form. This made it necessary to change the encapsulated VectAry
//             to be referenced by a pointer.
//
// Bugs:
//
// Classes:
//   DataSet
//   DataSetIter
//
// Notes:
//   This header includes declarations for the class DataSet and DataSetIter.
//   A DataSet serves as a wrapper for VectAry. Using DataSet, it is possible
//   to encode additional information, such as number of rows and columns in
//   the case of two dimensional data; or sequence number and set number in
//   case of data consisting of such.
//
//   DataSetIter iterates over elements in a DataSet. DataSetIter is much like
//   VectAryIter, except that it iterates over elements in a DataSet.
//   
// ----------------------------------------------------------------------------

#ifndef DATASET_INCLUDED
#define DATASET_INCLUDED

#ifndef PERSISTENT_INCLUDED
#include "persistent.h"
#endif

#ifndef VECTOR_INCLUDED
#include "vector.h"
#endif

#include <stdio.h>

class DataSetIter;

class DataSet : public Persistent {

  // Private members

  static void *d_protocol;
  static char *d_name_p;
  static Registrar d_registrar;
  
  static Persistent* createFunc();
  // returns a pointer to a newly created DataSet

  // DataSets cannot be copied or assigned

  DataSet(const DataSet&);
  DataSet& operator=(const DataSet&);
  
  // Friends

friend DataSetIter;

  // Protected Members

protected:

  int d_lsizes, *d_sizes_p;
  VectAry *d_va_p;
  
  int hasProtocol(void *protocol) const;
  // returns 1 if this object is of type(protocol) protocol OR is derived
  // from an object of type(protocol) protocol

  // Public members

public:

  // Construct & Destroy

  DataSet();
  DataSet(int n, int l);
  // Dataset of dimensionality n for data of _total_ size l
  DataSet(int l);
  // Dataset for data of _total_ size l

  ~DataSet();

  // Accessors

  static DataSet* safeCast(Persistent*);
  // Converts Persistent to a DataSet if the object pointed to by
  // Persistent is in fact a DataSet

  VectAry& operator()() const;
  // returns reference to VectAry

  int getSize() const;
  // returns number of dimensions in data
  
  int getSize(int i) const;
  // returns size of dimension i

  virtual Error put(FILE*) const;
  // writes DataSet to FILE

  Error putText(const char *fileName) const;
  // Stores text formatted dataset to file

  virtual const char* name() const;
  // returns name of class

  // Modifiers

  void setDimension(int n);
  // sets dimensionality to n
    
  void setSize(int n, int l);
  // sets size of dimension n as l

  virtual Error get(FILE*);
  // reads DataSet from FILE

  Error getText(const char *fileName); // Gets text formatted vector from file

};

class DataSetIter {

  // Private members

  VectAryIter d_it;

  // DataSetIters cannot be copied or assigned

  DataSetIter(const DataSetIter&);
  DataSetIter& operator=(const DataSetIter&);

  // Public Members

public:

  DataSetIter(const DataSet&);
  ~DataSetIter() {}

  // Accessors

  Vector& operator()() const;
  // returns reference to vector at current position

  operator const void*() const;
  // returns 0 if at end of iteration

  // Modifiers

  void operator++();
  // next state of iteration

  void reset();
  // resets state of iteration

};

#endif
