// ----------------------------------------------------------------------------
//
// 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.
//
// ----------------------------------------------------------------------------
//
// vector.h
//
// Author:               Sameer Nene
// Date:                 07/02/94
// Version:              1.1
// Modification History:
//   07/02/94: Added getText() and putText() to load/store vector in text form
//
// Bugs:
//
// ToDo:
//   Add a global macro defining the type(float or double or anything else) of
//   the floating point data used to store elements in a Vector. Unfortunately
//   this adds complexity in reading/writing of vectors from/to disk if
//   compatibility with older files is required, so the plan is shelved for the
//   moment! Using Templates does not solve the problem either.
//
// Classes:
//   Vector
//   VectAry
//   VectAryIter
//
// Notes:
//   This header includes declarations for class Vector, VectAry and
//   VectAryIter. Vector and VectAry are Persistents.
//
//   Vector is used extensively in SLAM for storage and processing of Image and
//   other vectors. Overloaded operators have been provided to facilitate
//   intuitive coding.
//
//   VectAry is used to implement an array of Vectors. It is recommended to use
//   Matrix instead of VectAry whenever possible for reasons of storage
//   efficiency. Wastage of space is especially a problem when the ratio of
//   rows:columns is very high (1000 or more).
//
//   VectAryIter is an iterator used to iterate over indvidual Vectors in a
//   VectAry. It is especially useful when one needs to access every Vector in
//   a VectAry serially in a loop.
//   
// ----------------------------------------------------------------------------

#ifndef VECTOR_INCLUDED
#define VECTOR_INCLUDED

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

#ifndef REGISTRY_INCLUDED
#include "registry.h"
#endif

#include <stdio.h>

class ostream;
class VectAryIter;
class Matrix;
class ImageUtil;
class J300Util;

class Vector : public Persistent {

  // Private Members

  static void *d_protocol;
  static char *d_name_p;
  static Registrar d_registrar;

  int d_size;
  double *d_data_p;

  static Persistent* createFunc();
  // returns a pointer to a newly created Vector

  // Friends

friend J300Util;
friend ImageUtil;
friend Matrix;
friend Vector operator*(double, const Vector&);
friend ostream& operator<<(ostream&, const Vector&);

  // Protected Members

protected:

  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

  Vector();
  Vector(int size); // Vector of size size
  Vector(const Vector&);
  ~Vector();

  // Manipulators

  Vector& operator=(const Vector&);
  void element(int i, double v); // Sets value of element i to v
  Vector& operator+=(const Vector&);
  Vector& operator-=(const Vector&);
  Vector& operator*=(double);
  Vector& operator/=(double);

  void length(int i);
  // sets length of vector to i. WARNING: This destroys all previous elements
  
  Error get(FILE*); // gets Vector from file
  Error getText(const char *fileName); // Gets text formatted vector from file

  // Accessors

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

  double element(int) const;
  int length() const;
  double operator()() const; // returns modulus of vector
  double distance(const Vector&) const;
  // returns square of the cartesian distance between two vectors

  Error put(FILE*) const; // puts Vector in file
  Error putText(const char *fileName) const;
  // Stores text formatted vector to file
  
  const char* name() const;
  // returns the name of the class

  // Operations

  Vector operator+(const Vector&) const;
  Vector operator-(const Vector&) const;
  Vector operator*(double) const;
  double operator*(const Vector&) const;
  Vector operator/(double) const;

};

Vector operator*(double, const Vector&);
ostream& operator<<(ostream&, const Vector&);

class VectAry : public Persistent {
  
  // Private Members

  static void *d_protocol;
  static char *d_name_p;
  static Registrar d_registrar;
  
  int d_size;
  Vector **d_data_p;

  static Persistent* createFunc();
  // returns a pointer to a newly created VectAry

  // VectArys cannot be copied or assigned

  VectAry(const VectAry&);
  VectAry& operator=(const VectAry&);

  // Friends

friend VectAryIter;

  // Protected Members

protected:

  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:

  VectAry();
  VectAry(int size);
  ~VectAry();
  
  // Manipulator
  
  Vector& operator[](int i) const;
  // returns readable/writable reference to i th Vector

  Error get(FILE*); // gets VectAry from file
  Error getText(const char *fileName); // Loads text formatted vector from file
  
  // Accessors

  static VectAry* safeCast(Persistent*);
  // Converts Persistent to a VectAry if the object pointed to by
  // Persistent is in fact a VectAry
  
  int getSize() const;

  Error put(FILE*) const; // puts VectAry in file
  Error putText(const char *fileName) const;
  // Stores text formatted vector to file

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

};

class VectAryIter {

  // Private members

  const VectAry &d_va;
  Vector **d_pos_p;

  // VectAryIters cannot be copied or assigned

  VectAryIter(const VectAryIter&);
  VectAryIter& operator=(const VectAryIter&);

  // Public Members

public:

  VectAryIter(const VectAry&);
  ~VectAryIter() {}

  // 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 set(int i);
  // sets state of iteration to i th element

};

#endif		     
