// Emacs: -*- C++ -*-

//
//	Copyright 1993, Center for Computer Vision and Visualization,
//	University of Florida.  All rights reserved.
//


// $Log:	VectorDI.h,v $
// Revision 1.12  93/05/27  11:22:45  thoth
// Copyright Notices
// 
// Revision 1.11  93/05/26  17:04:03  thoth
// new value_array() method.
// 
// Revision 1.10  93/04/17  18:45:13  thoth
// Iterator support is no longer based on a switch statement.  We now
// use a virtual method.  The user can now provide faster iterators.
// 
// Revision 1.9  93/04/08  13:21:44  thoth
// new pointset restriction method.
// new translation method.
// 
// Revision 1.8  93/03/10  13:37:13  thoth
// range method no longer returns valueset due to
// difficulties with template implementation.
// 
// Revision 1.7  93/02/20  15:15:11  thoth
// The size member is now constant.  VectorDIs are therefore no longer
// as mutable.
// The pointset should go first in an image constructor.
// Generic equality testing is not the domain of the BaseDI derived classes.
// Operations to index the vector directly are no longer supported.
// 
// Revision 1.6  93/02/17  11:05:04  thoth
// VectorDI is now a struct since it will have lots of friends.
// 
// Revision 1.5  93/02/08  13:05:27  thoth
// static dummy member belongs in the .c file.
// 
// Revision 1.4  93/01/19  14:56:41  jnw
// Modified to support IA_ naming convention
// 
// Revision 1.3  92/11/14  09:34:47  jnw
// Substituted () and [] for val and ref
// 
// Revision 1.2  92/11/13  13:50:40  jnw
//  Updated to include all sorts of new goodies
// 
// Revision 1.1  92/10/05  11:43:55  jnw
// Initial revision
// 

#ifndef VectorDI_h_
#define VectorDI_h_

#include "BaseDI.h"

template <class T> class IA_VectorDIVIter;
template <class T> class IA_VectorDIPIter;

template <class T>
class IA_VectorDI: public IA_BaseDI<T>{
//private:
  public: // public because we have too many friends.  Every operator on
    // images will want to play with our privates.
    T *vec;
    const int size;
    
    static char dummy;
  public:
    //IA_VectorDI(const IA_IntPointSet&);
    
    IA_VectorDI(IA_IntPointSet, T *, unsigned, int giveaway);
    
    IA_VectorDI(const IA_IntPointSet&, const T&);
    
    ~IA_VectorDI() { delete [] this->vec; }
    
    int extensivep() const { return 1; }
    
    T operator ()(const IA_IntPoint& p) const {
	// not guaranteed safe
	return this->vec[this->ps.index(p)];
    }
    
    // The &T operator[] is inherently unsafe, in that it returns
    // a reference to heap storage associated with an object.
    // The image of interest may go out of scope while the reference
    // is still alive.
    //
    // An additional assumption is that the user of this image object
    // (normally DiscreteImage<T>) has insured that either the
    // refcount is 1 (as DiscreteImage<T> does) or that there will
    // be no problem with returning a reference to a shared VectorDI
    // pixel value.
    
    T& operator [](const IA_IntPoint& p) {
	// not guaranteed safe
	return this->vec[this->ps.index(p)];
    }
    
#if 0
    // T& operator [](int) is unsafe in the same way as &T operator[].
    
    T& operator [](int i) { return this->vec[i]; }
    
    T operator ()(int i) const { return this->vec[i]; }
#endif

    static IA_DiscreteImageType s_type() { return &dummy; }

    IA_DiscreteImageType type() const { return &dummy; }

    IA_ValueSet<T> range() const;

    IA_Array<T> value_array() const;

    IA_BaseDI<T>* clone_self_extensively() const;

  private:
    static void vec_2_vec_structcopy(const T** source_vec, T** dest_vec,
				     const IA_SetStructure &ss);
  public:
    IA_BaseDI<T>* restricted_to(const IA_IntPointSet &) const;

    IA_BaseDI<T>* xlated_by(const IA_IntPoint &) const;

    IA_BaseDIVIter<T> *value_iterator() const;
    IA_BaseDIPIter<T> *pixel_iterator() const;

    ostream& print_this(ostream&) const;

    friend class IA_VectorDIVIter<T>;
    friend class IA_VectorDIPIter<T>;
};

#endif
