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

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


// 
// $Log: MondoPS.h,v $
// Revision 1.12  1994/07/25  16:58:52  thoth
// \Name sanitization
//
// Revision 1.11  1993/11/17  18:02:03  thoth
// extensivep() is now extensive()
//
// Revision 1.10  1993/09/15  12:34:09  thoth
// Pointset behavior controls have moved to IA::
//
// Revision 1.9  93/08/08  13:21:31  thoth
// deInlining of a few methods.
// 
// Revision 1.8  93/07/15  11:46:30  thoth
// New iterator virtual method.
// 
// Revision 1.7  93/05/26  16:51:37  thoth
// Copyright Notices
// 
// Revision 1.6  93/04/29  12:52:58  thoth
// Mondo PointSets are now templatized.
// 
// Revision 1.5  93/04/19  23:27:46  thoth
// Convert BaseIPS to IA_BasePS<IA_IntPoint>
// 
// Revision 1.4  93/02/12  16:27:58  thoth
// more IA_ prefixes.
// 
// Revision 1.3  92/12/16  14:48:17  thoth
// conversion to IA_ mostly complete
// 
// Revision 1.2  92/12/07  12:05:11  thoth
// new IntPoint index(unsigned) operation for use with "other" iterators.
// 
// Revision 1.1  92/09/30  10:52:47  thoth
// Initial revision
// 
//

#ifndef MondoPS_h_
#define MondoPS_h_

#include <iostream.h>
#include "BasePS.h"

// this is the class that contains all of the points of its dimensionality
template <class P>
class IA_WhiteHole_: public IA_BasePS<P> {
private:
    static char	type_;
public:
    IA_WhiteHole_(unsigned dim) :IA_BasePS<P>(dim) { }
    // this class contains all points of a given dimensionality
    int equal(IA_BasePS<P>* ips) const { return ips->type()==this->type() &&
				      ips->dim() == this->dimen; }
    unsigned hash_self(unsigned) const { return 0; }
    static IA::Type s_type() { return &type_; }
    IA::Type type() const { return &type_; }
    int contains(const P&) const { return 1; }
    unsigned index(const P &) const { return 0; }
    P index(unsigned idx) const;
    int extensive() const { return dimen==0;}
    IA_BasePSIter<P> *iterator() const;
    unsigned card() const {
	if (this->dimen!=0)
	    ia_throw(Pointset_RequireExtensive_Exception(__FILE__,__LINE__));
	return 1;
    }
    int empty() const { return 0; }
    IA_BasePS<P> *offsetted(const P &) const
	{ return new IA_WhiteHole_(dimen); }
    IA_BasePS<P> *reflect_through_origin() const
	{ return new IA_WhiteHole_(dimen); }
    void output(ostream & o, unsigned indent=0) const {
      for (unsigned i=0; i<indent; i++) o << ' ';
      o << "White"<<dimen<<'\n';
    }
};

// this is the class that contains none of the points of its dimensionality
template <class P>
class IA_BlackHole_: public IA_BasePS<P> {
private:
    static char	type_;
public:
    IA_BlackHole_(unsigned dim) :IA_BasePS<P>(dim) { }
    ~IA_BlackHole_() {}
    // this class contains no points of a given dimensionality
    int equal(IA_BasePS<P>* ips) const { return ips->type()==this->type() &&
				      ips->dim()==this->dimen; }
    unsigned hash_self(unsigned mod) const { return (1+dimen)%mod; }
    static IA::Type s_type() { return &type_; }
    IA::Type type() const { return &type_; }
    int contains(const P&) const { return 0; }
    unsigned index(const P &) const {
	if (IA::throw_on_index_uncontained)
	    ia_throw(Pointset_BadIndex_Exception(__FILE__,__LINE__));
	return IA::index_of_uncontained;
    }
    P index(unsigned) const;
    int extensive() const { return 1;}
    IA_BasePSIter<P> *iterator() const;
    unsigned card() const { return 0;}
    int empty() const { return 1; }
    IA_BasePS<P> *offsetted(const P &) const
	{ return new IA_BlackHole_(dimen); }
    IA_BasePS<P> *reflect_through_origin() const
	{ return new IA_BlackHole_(dimen); }
    void output(ostream & o, unsigned indent=0) const {
      for (unsigned i=0; i<indent; i++) o << ' ';
      o << "Black"<<dimen<<'\n';
    }
};

#endif
