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

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


// 
// $Log: FloatPointSet.h,v $
// Revision 1.7  1994/01/31  16:36:28  thoth
// Resurrected the int(*)(Point) constructor.
// Added static member functions to construct white and black holes.
//
// Revision 1.6  1993/11/17  18:02:03  thoth
// extensivep() is now extensive()
//
// Revision 1.5  1993/10/20  15:48:39  thoth
// New naming scheme.  Closures are named Closure.
//
// Revision 1.4  1993/09/15  12:31:34  thoth
// Certain functions are necessary for Continuous images,
// we will implement them later.
//
// Revision 1.3  93/08/08  13:14:35  thoth
// Parametrization of the pointsets on the point type using
// template specialization.
// 
// Revision 1.2  93/05/26  16:51:16  thoth
// Copyright Notices
// 
// Revision 1.1  93/05/10  08:33:25  thoth
// Initial revision
// 

#ifndef FloatPointSet_h_
#define FloatPointSet_h_

#define SUPPRESS_INCLUDE
#include "Set.h"
#undef SUPPRESS_INCLUDE

#include "FloatPoint.h"
#include "BasePS.h"
#include "SetStructure.h"

template <class P> class IA_ClosurePS;
template <class P> class IA_PSIter;


class IA_Set<IA_FloatPoint> {
  private:
    
    IA_BasePS<IA_FloatPoint>	*ps;

    void associate(IA_BasePS<IA_FloatPoint> *);
    void disassociate();

    IA_Set(IA_BasePS<IA_FloatPoint> *fps) { associate(fps); }
    IA_Set(IA_PointSetType t, unsigned dim);
  public:
    IA_Set();
    IA_Set(const IA_FloatPoint&p);
    IA_Set(unsigned dimen, int(*f)(const IA_FloatPoint&));
    IA_Set(unsigned dimen, int(*f)(IA_FloatPoint));
    IA_Set(const IA_ClosurePS<IA_FloatPoint>&);
    IA_Set(unsigned dimen, const IA_FloatPoint *afp, unsigned len);
    IA_Set(const IA_Set<IA_FloatPoint> &fps);
//    IA_Set(const IA_IntPointSet &ips);

    ~IA_Set();

    IA_Set<IA_FloatPoint> & operator=(const IA_Set<IA_FloatPoint>&);

    int operator==(const IA_Set<IA_FloatPoint>&fps) const ;
    int operator!=(const IA_Set<IA_FloatPoint>&fps) const ;

    // This block NYI
    friend IA_Set<IA_FloatPoint> operator|
    (const IA_Set<IA_FloatPoint> &,const IA_Set<IA_FloatPoint> &);
    friend IA_Set<IA_FloatPoint> operator&
    (const IA_Set<IA_FloatPoint> &,const IA_Set<IA_FloatPoint> &);
    friend IA_Set<IA_FloatPoint> operator^
    (const IA_Set<IA_FloatPoint> &,const IA_Set<IA_FloatPoint> &);
    friend IA_Set<IA_FloatPoint> operator/
    (const IA_Set<IA_FloatPoint> &,const IA_Set<IA_FloatPoint> &);
    //
    friend IA_Set<IA_FloatPoint> operator+
    (const IA_Set<IA_FloatPoint> &,const IA_FloatPoint &);
    //
    friend IA_Set<IA_FloatPoint> intersect_with_structure
    (const IA_Set<IA_FloatPoint> &lhs, const IA_Set<IA_FloatPoint> &rhs,
     IA_SetStructure *s_struct);
    friend IA_Set<IA_FloatPoint> union_with_structure
    (const IA_Set<IA_FloatPoint> &lhs, const IA_Set<IA_FloatPoint> &rhs, IA_SetStructure *s_struct);
    //

#if 0
    int operator==(const IA_Set<IA_FloatPoint>&fps) const;
    int operator!=(const IA_Set<IA_FloatPoint>&fps) const
    { return !(*this==fps); }
#endif
    unsigned dim() const { return ps->dim(); }

    int contains(const IA_FloatPoint &ip) const { return ps->contains(ip); }
    unsigned index(const IA_FloatPoint &fp) const { return ps->index(fp); }
    IA_FloatPoint index(unsigned idx) const { return ps->index(idx); }

    unsigned card() const { return ps->card(); }
    int empty() const { return ps->empty(); }
    int extensive() const { return ps->extensive(); }

    // he has to know how to get at the underlying IA_BasePS<IA_FloatPoint>*
    friend class IA_PSIter<IA_FloatPoint>;

    friend IA_Set<IA_FloatPoint> IA_CBlackHole(unsigned dim);
    friend IA_Set<IA_FloatPoint> IA_CWhiteHole(unsigned dim);

    static IA_Set<IA_FloatPoint> WhiteHole(unsigned dim) {
	return IA_CWhiteHole(dim);
    }
    static IA_Set<IA_FloatPoint> BlackHole(unsigned dim) {
	return IA_CBlackHole(dim);
    }
};

typedef IA_Set<IA_FloatPoint> IA_FloatPointSet;

#include "IntPointSet.h"	// for the intersection

IA_Set<IA_IntPoint> operator&(const IA_Set<IA_IntPoint>&,
			      const IA_FloatPointSet&);
inline IA_Set<IA_IntPoint> operator&(const IA_FloatPointSet&lhs,
			      const IA_Set<IA_IntPoint>&rhs) {
    return rhs&lhs;
}

void SortFloatPointArray(IA_FloatPoint *afp, unsigned len);

#endif
