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

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


//
// $Log: VectorI.h,v $
// Revision 1.4  1994/07/25  17:26:39  thoth
// Name sanitization
//
// Revision 1.3  1994/03/14  15:48:33  thoth
// ValueSet has been replaced by container class Set.
//
// Revision 1.2  1993/11/17  18:29:17  thoth
// extensivep is now extensive.
//
// Revision 1.1  1993/09/15  12:57:46  thoth
// Initial revision
//

#ifndef VectorI_h_
#define VectorI_h_

#include "BaseI.h"

template < class P,class T> class IA_VectorIVIter;
template < class P,class T> class IA_VectorIPIter;

template < class P,class T>
class IA_VectorI: public IA_BaseImage<P,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_VectorI(const IA_Set<P>&);
    
    IA_VectorI(IA_Set<P>, T *, unsigned, int giveaway);
    
    IA_VectorI(const IA_Set<P>&, const T&);
    
    ~IA_VectorI() { delete [] this->vec; }
    
    int extensive() const { return 1; }
    
    T operator ()(const P& p) const {
	// not guaranteed safe
	return this->vec[this->ps.index(p)];
    }

    // XXX out of date:
    // 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 Image<T>) has insured that either the
    // refcount is 1 (as Image<T> does) or that there will
    // be no problem with returning a reference to a shared VectorI
    // pixel value.
    
    T& operator [](const P& 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::Type s_type() { return &dummy; }

    IA::Type type() const { return &dummy; }

    IA_Set<T> range() const;

    IA_Array<T> value_array() const;

    IA_BaseImage<P,T>* clone_self_extensively() const;

  private:
    static void vec_2_vec_structcopy(const T** source_vec, T** dest_vec,
				     const IA_SetStructure &ss);
  public:
#if 0
    IA_BaseImage<IA_Point<int>,T>* restricted_to
    (const IA_Set<IA_Point<int> > &) const;
    IA_BaseImage<P,T>* restricted_to(const IA_Set<IA_Point<double> > &) const;
#endif
    IA_BaseImage<P,T>* xlated_by(const P &) const;

    IA_BaseIVIter<P,T> *value_iterator() const;
    IA_BaseIPIter<P,T> *pixel_iterator() const;

    ostream& print_this(ostream&) const;

    friend class IA_VectorIVIter<P,T>;
    friend class IA_VectorIPIter<P,T>;
};

#endif
