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

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


//
// $Log: BaseNbh.h,v $
// Revision 1.1  1994/01/31  16:43:38  thoth
// Initial revision
//


#ifndef BaseNbh_h_
#define BaseNbh_h_

#include <iostream.h>
#include "ia.h"
#include "IntPoint.h"
#include "IntPointSet.h"
#include "ValueSet.h"


template <class P, class Q> class IA_Neighborhood;

template <class P, class Q>
class IA_BaseNbh {
protected:
    IA_Set<Q> ps;

    // refcount counts the number of references to this BaseNbh object
    //   from DNbhemplate container class objects.
    // It is maintained by container classes.
    int refcount;


public:
    // Constructor for BaseNbh takes care of initting the refcount.
    // Derived classes need not frob it.
    // It is the responsibility of the container to maintain the refcount!

    IA_BaseNbh(const IA_Set<Q> &p):ps(p) {
	refcount = 0;
    }

    virtual ~IA_BaseNbh() {};

    int get_ref() { return refcount; }
    int incr_ref() { return ++refcount; }
    int decr_ref() { return --refcount; }

    // For the next function, we expect our container to trap
    // out-of-bounds points
    virtual IA_Set<P> operator ()(const Q &) const =0;

    // Each class derived from BaseNbh must support the member function
    // type which returns an IA::Type value (a pointer to an int).
    // To distinguish between the different classes derived from BaseNbh,
    // we make certain that type will be distinct for each of these classes
    // as follows:
    //	Each class derived from BaseNbh defines a static function member dummy:
    //		static char dummy;
    //  The class definition for derived class "classname" must also be
    //	followed by a declaration of form
    //		template <class T> char classname<T>::dummy = 0;
    //	The member function type() in each class derived from BaseNbh returns
    //	the address of dummy.
    // Thus each class returns a unique value for a call of type().

    virtual IA::Type type() const =0;

    IA_Set<Q> domain() const { return this->ps; }

    virtual ostream& print_this(ostream&) const = 0;
    
    friend class IA_Neighborhood<P,Q>;
};

#endif
