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

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


//
// $Log:	reduce_fn_nz,v $
// Revision 1.2  93/05/27  11:49:03  thoth
// Copyright Notices
// 
// Revision 1.1  93/03/10  13:49:13  thoth
// Initial revision
// 

static ATYPE vec_reduce_OPNAME(const IA_VectorDI<LTYPE> *arg)
{
    const LTYPE *ls = arg->vec;

    ATYPE	rval=*(ls++);

    const unsigned sz = arg->domain().card();
    for (unsigned i=1; i<sz; i++) {
	rval = SUBOP( rval, (*(ls++)));
    }

    return rval;
}

#ifndef const_reduce_ATYPE_LTYPE_OPNAME
#define const_reduce_ATYPE_LTYPE_OPNAME
static ATYPE const_reduce_OPNAME(unsigned sz, LTYPE arg)
{
    ATYPE	rval=arg;
    for (unsigned i=1; i<sz; i++) {
	rval = SUBOP(rval, arg);
    }
    return rval;
}
#endif

static ATYPE iter_reduce_OPNAME(const IA_DiscreteImage<LTYPE> &arg)
{
    IA_DIVIter<LTYPE>	iter(arg);

    LTYPE	temp;
    iter(temp);

    ATYPE	rval=temp;

    while(iter(temp)) {
	rval = SUBOP(rval, temp);
    }

    return rval;
}

ATYPE OP ( const IA_DiscreteImage<LTYPE> &arg)
{
    if (arg.domain().card()==0)
	abort(); // XXX unfinished code

    if (arg.type() == IA_VectorDI<LTYPE>::s_type()) {
	return vec_reduce_OPNAME((IA_VectorDI<LTYPE> *)arg.bdip);
    } else if (arg.type() == IA_ConstDI<LTYPE>::s_type()) {
	return const_reduce_OPNAME(arg.domain().card(),
				   ((IA_ConstDI<LTYPE> *)arg.bdip)->value);
    } else {
	return iter_reduce_OPNAME(arg);
    }
}
