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

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


//
// $Log: DDTempl.h,v $
// Revision 1.10  1994/12/22  21:37:39  fjsoria
// static member template fix
//
// Revision 1.9  1994/07/25  17:26:39  thoth
// Name sanitization
//
// Revision 1.8  1994/03/30  13:55:17  thoth
// New zero-argument constructor that builds an unusable template as a
// space-holder.
//
// Revision 1.7  1994/03/15  14:22:53  thoth
// Add constructor that assumes the White Hole.
//
// Revision 1.6  1994/03/14  15:50:59  thoth
// Named template classes have been eliminated and operations are
// hung off of FBI.
//
// Revision 1.5  1994/02/22  18:47:01  thoth
// New private constructor from BaseDT<I>*
// New is_a virtual method, used to determine if an object is of a
// class derived from another class.
//
// Revision 1.4  1994/02/12  19:34:43  thoth
// Using IA::Type instead of the IA_DiscreteImageType typedef.
//
// Revision 1.3  1994/01/07  15:16:26  thoth
// Copy constructor and assignment were missing.  This was bad.
//
// Revision 1.2  1993/10/05  19:33:08  thoth
// Move to new Closure naming convention.
//
// Revision 1.1  1993/09/15  12:51:55  thoth
// Initial revision
//
// Revision 1.4  93/06/10  17:23:55  thoth
// Workaround for 3.0.1 bug.
// 
// Revision 1.3  93/05/27  11:19:34  thoth
// Copyright Notices
// 
// Revision 1.2  93/04/08  13:10:36  thoth
// Templates are now separate from images.
// 
// Revision 1.1  93/03/18  11:02:37  thoth
// Initial revision
// 

#ifndef DDTempl_h_
#define DDTempl_h_

#include "BaseDT.h"

#if 0
template <class I> class IA_ClosureDT;
#else
// Lame 3.0.1
#include "ClosureDT.h"
#endif

#include "Image.h"

template <class I>
class IA_DDTemplate {
#ifndef __NO_FRIEND_TEMPLATE_SUPPORT
    template <class Q, class U>
        friend class IA_FBI;
#else
    friend class IA_FBI<IA_Point<int>, IA_Point<int>, int, int, int>;
    friend class IA_FBI<IA_Point<int>, IA_Point<int>, float, float, float>;
    friend class IA_FBI<IA_Point<int>, IA_Point<int>, IA_Bit, IA_Bit, IA_Bit>;
    friend class IA_FBI<IA_Point<int>, IA_Point<int>, u_char, u_char, u_char>;
    friend class IA_FBI<IA_Point<int>, IA_Point<int>, IA_RGB, IA_RGB, IA_RGB>;
    friend class IA_FBI<IA_Point<int>, IA_Point<int>, complex, complex, complex>;
    friend class IA_FBI<IA_Point<double>, IA_Point<double>, float, float, float>;
#endif
  
  protected:
    IA_BaseDT<I>	*bdtp;

    void set_and_reference_template(IA_BaseDT<I> *);
    void disassociate_template();

    IA_DDTemplate(IA_BaseDT<I> *t) {
	set_and_reference_template(t);
    }

  public:
    IA_DDTemplate();

    IA_DDTemplate(const IA_DDTemplate &arg);

    // Construct a translation invariant template
    IA_DDTemplate(const IA_Set<IA_Point<int> > &, const I &);

    IA_DDTemplate(unsigned dim, const I &);

    // causes ambiguities
    // IA_DDTemplate(const I &);

    IA_DDTemplate(const IA_Set<IA_Point<int> > &, I (*)(const IA_Point<int> &));

    IA_DDTemplate(const IA_ClosureDT<I> &);

    ~IA_DDTemplate();

    IA_DDTemplate &operator=(const IA_DDTemplate&);

    I operator()(const IA_Point<int> &p) const { return (*bdtp)(p); }

    IA_Set<IA_Point<int> > domain() const { return bdtp->domain(); }
    IA::Type type() const { return bdtp->type(); }
    int is_a(IA::Type t) const { return bdtp->is_a(t); }

    //friend I gcon(const I&, const IA_DDTemplate<I>&);
};

#include "AuxDDTempl.h"

#endif
