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

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


//
// $Log: bin-TF,v $
// Revision 1.3  1994/09/16  14:57:11  thoth
// more DOS-inspired renaming.
//
// Revision 1.2  1994/07/25  17:26:39  thoth
// Name sanitization
//
// Revision 1.1  1994/03/29  21:08:26  jnw
// Initial revision
//

#include "DDTempl.h"
#include "InvDT.h"
#include "ImageIter.h"

void OPNAME_extending
(const IA_SetStructure &ss, ATYPE ** dst,
#ifdef FUNKY_ERROR
 void *src1_,
 void *src2_
#else
 IA_IVIter<IA_Point<int>,LTYPE> *src1,
 IA_IVIter<IA_Point<int>,RTYPE> *src2
#endif
)
{
#ifdef FUNKY_ERROR
    IA_IVIter<IA_Point<int>,LTYPE> *src1 =
	(IA_IVIter<IA_Point<int>,LTYPE> *)src1_;
    IA_IVIter<IA_Point<int>,RTYPE> *src2 =
	(IA_IVIter<IA_Point<int>,RTYPE> *)src2_;
#endif

    LTYPE	t1;
    RTYPE	t2;

    for(int i = 0; i < ss.nintervals(); i++) {
	IA_ss_interval ssi = ss.retrieve_interval(i);
	if (ssi.substructure == IA_SetStructure::BOTH) {
	    for (int j=0; j<ssi.count; j++) {
		if (!(*src1)(t1))
		    IA::internal_error(__FILE__,__LINE__);
		if (!(*src2)(t2))
		    IA::internal_error(__FILE__,__LINE__);
		*((*dst)++) = SUBOP( t1 , t2);
	    }
	} else if (ssi.substructure == IA_SetStructure::FIRST_ONLY) {
	    for (int j=0; j<ssi.count; j++) {
		if (!(*src1)(t1))
		    IA::internal_error(__FILE__,__LINE__);
		*((*dst)++) = SUBOP( t1 , (ZERO));
	    }
	} else if (ssi.substructure == IA_SetStructure::SECOND_ONLY) {
	    for (int j=0; j<ssi.count; j++) {
		if (!(*src2)(t2))
		    IA::internal_error(__FILE__,__LINE__);
		*((*dst)++) = SUBOP( (ZERO) , t2);
	    }
	} else {
	    for (int j=0; j<ssi.count; j++) {
		OPNAME_extending(ssi.substructure, dst, src1, src2);
	    }
	}
    }
}


IA_DDTemplate<IA_Image<IA_Point<int>,ATYPE> >
OP(const IA_DDTemplate<IA_Image<IA_Point<int>,LTYPE> > &lhs,
   const IA_DDTemplate<IA_Image<IA_Point<int>,RTYPE> > &rhs)
{
    if (lhs.type() == IA_InvariantDT<IA_Image<IA_Point<int>,LTYPE> >::s_type() &&
	rhs.type() == IA_InvariantDT<IA_Image<IA_Point<int>,RTYPE> >::s_type()) {
	IA_SetStructure	ss;
	IA_Image<IA_Point<int>, LTYPE>	li=
	    ((IA_InvariantDT<IA_Image<IA_Point<int>, LTYPE> > *)
	     IA_FBI<IA_Point<int>, IA_Point<int>, LTYPE, LTYPE, LTYPE>::extract_baseptr(lhs))->value;
	IA_Image<IA_Point<int>, RTYPE>	ri=
	    ((IA_InvariantDT<IA_Image<IA_Point<int>, RTYPE> > *)
	     IA_FBI<IA_Point<int>, IA_Point<int>, RTYPE, RTYPE, RTYPE>::extract_baseptr(rhs))->value;
	IA_Set<IA_Point<int> >	ps = union_with_structure(li.domain(),
						  ri.domain(), &ss);
	const int sz = ps.card();
	ATYPE *const dest	= new ATYPE[sz];
	{
	    IA_IVIter<IA_Point<int>, LTYPE>	liter(li);
	    IA_IVIter<IA_Point<int>, RTYPE>	riter(ri);
	    ATYPE	*dp = dest;
	    OPNAME_extending(ss, &dp, &liter, &riter);
	}
	return IA_DDTemplate<IA_Image<IA_Point<int>,ATYPE> >
	    (lhs.domain(), IA_Image<IA_Point<int>, ATYPE>(ps, dest, sz, 1));
    } else {
	IA::not_yet_implemented(__FILE__, __LINE__);
    }
}
