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

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


//
// $Log: closure.c,v $
// Revision 1.7  1994/01/31  15:51:47  thoth
// removed cruft.
// chi_contains is only good for Discrete images.
// value-value closures are now available.
// we can instantiate things (like chi_contains) that only make sense on
// discrete images.
// Neighborhoods now exist.
// the double-double FDI composition was not being instantiated.
//
// Revision 1.6  1994/01/07  15:10:00  thoth
// Image class is now CoreImage and named image types are
// Image<P,T>.
//
// Revision 1.5  1993/12/29  17:17:12  thoth
// New FunctionI type.
// new chi_contains function.
//
// Revision 1.4  1993/11/17  18:30:27  thoth
// We now instantiate templates too.
// translated is now translate.
// extensivep is now extensive.
// ComplexDI is instantiated.
// DoubleDI is commented out.
//
// Revision 1.3  1993/10/05  19:34:25  thoth
// Move to new Closure naming convention.
// Eliminated unnecessary Continuous Images.
//
// Revision 1.2  1993/09/27  15:54:08  thoth
// xlated is now translated.
//
// Revision 1.1  1993/09/15  12:58:07  thoth
// Initial revision
//


#include <complex.h>
#include "CoreImage.h"
#include "ImageIter.h"

#include "BitDI.h"
#include "UcharDI.h"
#include "IntDI.h"
#include "FloatDI.h"
#include "ComplexDI.h"
#include "DDTempl.h"

#include "Neighborhood.h"


#define INSTANTIATE(P,T) \
{ \
    P	*points=0; \
    T	*vals=0; \
    IA_ClosureI<P,T>	*zero=0; \
    IA_ValueSet<T>	vs; \
    IA_Set<P>		ps; \
    IA_Array<T>		ar; \
    IA_CoreImage<P,T>	i1; \
    IA_CoreImage<P,T>	i2(i1), i3(ps, vals[0]), i4(ps, (T*)0, 0, 0), \
	i5(ps, vals, 0), i6(*zero), \
	i7(ps, (T(*)(const P&))0), i8(ps, (T(*)(P))0); \
    int	j; \
 \
    i1 = i2; \
    i1 = vals[0]; \
    vals[0] = i2(points[0]); \
    i2[points[0]] = vals[0]; \
 \
    i1.restrict(IA_IntPointSet()); \
    i1 = i1.restrict(IA_FloatPointSet()); \
    i1 = i1.restrict(vs); \
    i1 = i1.extend(i2); \
    i1 = i1.translate(points[0]); \
    ps = i1.domain(); \
    vs = i1.range(); \
    ar = i1.value_array(); \
    j = i1.card(); \
    j = i1.extensive(); \
    vals[0] = i1.reduce((T(*)(const T&, const T&))0, 0); \
    vals[0] = i1.reduce((T(*)(T, T))0, 0); \
 \
    i1.restrict_assign(i2); \
 \
    cout << i1; \
 \
    IA_IVIter<P,T>	viter1; \
    IA_IVIter<P,T>	viter2(viter1), viter3(i1); \
    viter1 = viter2; \
    viter1 = i1; \
    i1 = viter1.domain(); \
    while (viter1(vals[0])) \
	; \
    viter1.reset(); \
 \
    IA_IPIter<P,T>	piter1; \
    IA_IPIter<P,T>	piter2(piter1), piter3(i1); \
    piter1 = piter2; \
    piter1 = i1; \
    i1 = piter1.domain(); \
    while (piter1(points[0],vals[0])) \
	; \
    piter1.reset(); \
 \
    i1 = compose(i1, *(IA_Closure<P,P>*)0); \
    i1 = compose(i1, (P (*)(const P&))0); \
    i1 = compose((T (*)(T))0, i1); \
    i1 = compose(*(IA_Closure<T,T>*)0, i1); \
    i1 = compose(*(IA_Closure<T,T>*)0, i1, (T*)0); \
 \
}

#define INST_TEMPL(I) \
{ \
    IA_IntPointSet	ps; \
    IA_IntPoint	p; \
    I	img; \
    IA_DDTemplate<I> templ1(ps, img); \
    IA_DDTemplate<I> templ2(ps, (I(*)(const IA_IntPoint&))0); \
    IA_DDTemplate<I> templ3(*(IA_ClosureDT<I>*)0); \
 \
    img = templ1(p); \
    ps = templ1.domain(); \
    templ1.type(); \
}

typedef IA_Image<IA_IntPoint,IA_Bit>	BDI;
typedef	IA_Image<IA_IntPoint,u_char>	UDI;
typedef	IA_Image<IA_IntPoint,int>	IDI;
typedef	IA_Image<IA_IntPoint,float>	FDI;
typedef	IA_Image<IA_IntPoint,complex>	CDI;

#define INSTANTIATE_D(T) \
{ \
    IA_Image<IA_IntPoint, T>	i1; \
    IA_ValueSet<T>		vs; \
    chi_contains(i1, vs); \
    transpose(i1); \
}


void crap ()
{
    INSTANTIATE(IA_IntPoint, IA_Bit);
    INSTANTIATE(IA_IntPoint, unsigned char);
    INSTANTIATE(IA_IntPoint, int);
    INSTANTIATE(IA_IntPoint, float);
    //INSTANTIATE(IA_IntPoint, double);
    INSTANTIATE(IA_IntPoint, complex);
    INSTANTIATE(IA_FloatPoint, float);
    //INSTANTIATE(IA_FloatPoint, double);
    //INSTANTIATE(IA_FloatPoint, complex);

    INSTANTIATE_D(IA_Bit);
    INSTANTIATE_D(unsigned char);
    INSTANTIATE_D(int);
    INSTANTIATE_D(float);
  //INSTANTIATE_D(double);
    INSTANTIATE_D(complex);


    INST_TEMPL(BDI);
    INST_TEMPL(UDI);
    INST_TEMPL(IDI);
    INST_TEMPL(FDI);
    INST_TEMPL(CDI);

    {
	IA_Neighborhood<IA_IntPoint,IA_IntPoint>
	    n1(2,IA_IntPointSet()),
	n2(n1);
	n1 = n2;
	n1(IA_IntPoint());
	n1.domain();
	n2.type();
    }

    compose((double(*)(double))0, IA_CoreImage<IA_IntPoint,float>());
    compose((double(*)(double))0, IA_Image<IA_IntPoint,float>());
}



int main()
{
  cout << "Hello, world.\n";
  crap();
}
