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

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

// 
// $Log: BoxyIPS.h,v $
// Revision 1.20  1994/07/25  16:58:52  thoth
// \Name sanitization
//
// Revision 1.19  1993/11/17  18:02:03  thoth
// extensivep() is now extensive()
//
// Revision 1.18  1993/07/15  11:35:24  thoth
// Add support for iterator virtual method.
//
// Revision 1.17  93/05/26  16:41:04  thoth
// Copyright Notices.
// 
// Revision 1.16  93/04/19  23:27:37  thoth
// Convert BaseIPS to IA_BasePS<IA_IntPoint>
// 
// Revision 1.15  93/04/17  14:52:54  thoth
// Use IA_IntPoint instead of IntPoint
// 
// Revision 1.14  93/02/12  16:26:18  thoth
// more IA_ prefixes.
// 
// Revision 1.13  92/12/16  14:47:58  thoth
// conversion to IA_ mostly complete
// 
// Revision 1.12  92/12/07  12:05:03  thoth
// new IntPoint index(unsigned) operation for use with "other" iterators.
// 
// Revision 1.11  92/09/30  10:27:34  thoth
// type() system now based on address of static data member.
// contains now accepts const Point<>&.
// infimum & supremum virtuals now inf & sup.
// 
// Revision 1.10  92/09/20  17:37:37  thoth
// fixed spelling error
// 
// Revision 1.9  92/09/20  14:05:46  thoth
// new infimum and supremum methods for point sets.
// 
// Revision 1.8  92/09/03  13:31:10  thoth
// hash_self now deals with unsigneds
// 
// Revision 1.7  92/08/25  15:28:40  thoth
// new offsetted virtual functions
// 
// Revision 1.6  92/08/23  13:29:57  thoth
// CFrontified version
// 
// 

#ifndef BoxyIPS_h_
#define BoxyIPS_h_

#ifdef IA_PRII
#pragma interface
#endif

#include "BasePS.h"
#include "IntPoint.h"

class IA_BoxyIPSIter;

class IA_BoxyIPS: public IA_BasePS<IA_Point<int> > {
private:
    static char	type_;
protected:
    // invariants:
    // dimen>0
    // start is pointwise <= end
    // start and end are included in the pointset (the boundaries are a part).
    IA_Point<int> start, end;
public:

    ~IA_BoxyIPS() { }
    IA_BoxyIPS(const IA_Point<int>&, const IA_Point<int>&);
    IA_BoxyIPS(const IA_BoxyIPS&);
    IA_BoxyIPS& operator=(const IA_BoxyIPS&);

    int equal(IA_BasePS<IA_Point<int> >*) const;
    unsigned hash_self(unsigned) const;
    int operator==(const IA_BoxyIPS&) const;

    // I hate the tail end of page 179, but the constness differentiates.
    //static IA::Type type() { return &type_; }
    static IA::Type s_type() { return &type_; }
    IA::Type type() const { return &type_; }

    int contains(const IA_Point<int>&) const;
    unsigned index(const IA_Point<int>&) const;
    IA_Point<int> index(unsigned) const;

    IA_Point<int> min() const { return start; }
    IA_Point<int> max() const { return end; }
    IA_Point<int> inf() const { return start; }
    IA_Point<int> sup() const { return end; }
    IA_Point<int> choice() const { return index(IA::rand_mod(card())); }

    unsigned card() const;
    int empty() const { return 0; }

    IA_BasePS<IA_Point<int> > *offsetted(const IA_Point<int> &ip) const
	{ return new IA_BoxyIPS(start+ip, end+ip); }

    IA_BasePS<IA_Point<int> > * reflect_through_origin() const {
	return new IA_BoxyIPS(-end, -start);
    }

    int extensive() const { return 1; }

    virtual IA_BasePSIter<IA_Point<int> > *iterator() const;

    void output(ostream &, unsigned=0) const;
    // extra functions

    // This method returns the n-1 dimensional shadow of the
    // boxy point set.  (Basically, we chop off the first coordinate).
    // This method is used to convert a boxy point set to the yoder
    // representation.
    // Calling this method on a BoxyIPS of dimension 0 is an error.
    // Calling this method on a BoxyIPS of dimension 1 is not
    // particularly useful.
    IA_BoxyIPS shadow() const {
	return IA_BoxyIPS(cdr(start), cdr(end));
    }
    unsigned	width(unsigned i) const { return end[i]-start[i]+1; }

    friend class IA_BoxyIPSIter;
};

#endif
