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

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


//
// $Log: DDTempl.c,v $
// Revision 1.8  1994/09/16  14:57:11  thoth
// more DOS-inspired renaming.
//
// Revision 1.7  1994/08/22  15:20:29  thoth
// DOS-inspired name rework.
//
// Revision 1.6  1994/07/25  17:26:39  thoth
// Name sanitization
//
// Revision 1.5  1994/03/30  13:55:17  thoth
// New zero-argument constructor that builds an unusable template as a
// space-holder.
//
// Revision 1.4  1994/03/15  14:22:53  thoth
// Add constructor that assumes the White Hole.
//
// 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:40  thoth
// Initial revision
//
// Revision 1.3  93/05/27  11:28:18  thoth
// Copyright Notices
// 
// Revision 1.2  93/04/08  13:10:04  thoth
// Templates are now separate from images.
// 
// Revision 1.1  93/03/18  11:02:14  thoth
// Initial revision
// 

#include "IntPoint.h"
#include "DDTempl.h"
#include "IntPS.h"
#include "ErrorDT.h"
#include "InvDT.h"
#include "FuncDT.h"
#include "ClosureDT.h"



template <class I>
void IA_DDTemplate<I>::set_and_reference_template(IA_BaseDT<I> *t)
{
    t->incr_ref();
    this->bdtp = t;
}

template <class I>
void IA_DDTemplate<I>::disassociate_template()
{
    if (this->bdtp->decr_ref() <= 0)
	delete this->bdtp;
    this->bdtp = 0;
}

//
//

template <class I>
IA_DDTemplate<I>::IA_DDTemplate()
{
    set_and_reference_template(new IA_ErrorDT<I>());
}

template <class I>
IA_DDTemplate<I>::IA_DDTemplate(const IA_DDTemplate<I> &arg)
{
    set_and_reference_template(arg.bdtp);
}

template <class I>
IA_DDTemplate<I>::IA_DDTemplate(const IA_Set<IA_Point<int> > &ps, const I &i)
{
    set_and_reference_template(new IA_InvariantDT<I>(ps, i));
}

template <class I>
IA_DDTemplate<I>::IA_DDTemplate(unsigned dim, const I &i)
{
    set_and_reference_template(new IA_InvariantDT<I>(IA_WhiteHole(dim), i));
}

#if 0
// causes ambiguities
template <class I>
IA_DDTemplate<I>::IA_DDTemplate(const I &i)
{
    set_and_reference_template(new IA_InvariantDT<I>
			       (IA_WhiteHole(i.domain().dim()), i));
}
#endif

template <class I>
IA_DDTemplate<I>::IA_DDTemplate(const IA_Set<IA_Point<int> > &ps,
				I (*f)(const IA_Point<int>&))
{
    set_and_reference_template(new IA_FunctionDT<I>(ps, f));
}

template <class I>
IA_DDTemplate<I>::IA_DDTemplate(const IA_ClosureDT<I> &o)
{
    set_and_reference_template(o.clone_self());
}

template <class I>
IA_DDTemplate<I>::~IA_DDTemplate()
{
    disassociate_template();
}

template <class I>
IA_DDTemplate<I> & IA_DDTemplate<I>::operator=(const IA_DDTemplate<I>&arg)
{
    IA_BaseDT<I>	*temp = arg.bdtp;

    temp->incr_ref();

    if (this->bdtp->decr_ref() <= 0)
	delete this->bdtp;

    this->bdtp = temp;

    return *this;
}
