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

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

static char copyright[] = "Copyright 1993, Center for Computer Vision and Visualization,\nUniversity of Florida.  All rights reserved.\n";

static char rcsid[] = "$Id: IPSIter.c,v 1.11 93/05/28 15:05:27 thoth Exp $";

// 
// $Log:	IPSIter.c,v $
// Revision 1.11  93/05/28  15:05:27  thoth
// removed dependency on with-ia-pointset*
// 
// Revision 1.10  93/05/27  18:05:39  thoth
// eliminated dependency on internal testing file.
// 
// Revision 1.9  93/05/26  16:57:44  thoth
// Copyright Notices
// 
// Revision 1.8  93/04/29  12:50:00  thoth
// Mondo PointSets are now templatized.
// 
// Revision 1.7  93/04/16  15:50:16  thoth
// use IA_IntPoint instead of IntPoint.
// 
// Revision 1.6  93/02/12  16:25:15  thoth
// more IA_ prefixes.
// more comments.
// 
// Revision 1.5  92/12/16  14:48:06  thoth
// conversion to IA_ mostly complete
// 
// Revision 1.4  92/09/30  10:28:44  thoth
// White and Black holes are now semi-public classes, unfortunately.
// type() system now based on address of static data member.
// 
// Revision 1.3  92/09/03  13:34:10  thoth
// I unnamed unused formal parameters
// 
// Revision 1.2  92/08/26  13:43:10  thoth
// meaningful exception types.
// 
// Revision 1.1  92/08/23  13:30:08  thoth
// Initial revision
// 
// 

#include "IPSIter.h"
#include "BoxyIPSIter.h"
#include "YoderIPSIter.h"
#include "MondoPS.h"

#ifdef IA_PRII
#pragma implementation
#endif

#define WhiteIter IA_WhiteIter
#define BlackIter IA_BlackIter

class WhiteIter: public IA_BaseIPSIter {
private:
    int	done;
public:
    WhiteIter(const IA_IntPointSet&ps): IA_BaseIPSIter(ps) { done=0; }
    IA_BaseIPSIter *clone_self() { return new WhiteIter(domain); }
    int next(IA_IntPoint& ip) {
	if (done)
	    return 0;
	else {
	    ip = IA_IntPoint();
	    done = 1;
	    return 1;
	}
    }
    void reset() { done=0; }
};

class BlackIter: public IA_BaseIPSIter {
public:
    BlackIter(const IA_IntPointSet&ps): IA_BaseIPSIter(ps) {}
    IA_BaseIPSIter *clone_self() { return new BlackIter(domain); }
    int next(IA_IntPoint&) {
	return 0;
    }
    void reset() {}
};

IA_BaseIPSIter * IA_IPSIter::make_iter(const IA_IntPointSet & ips)
{
    IA_PointSetType	itype=ips.type();
    if (itype==IA_BoxyIPS::s_type())
	return new IA_BoxyIPSIter(ips,(IA_BoxyIPS*)ips.ps);
    else if (itype==IA_YoderIPS::s_type())
	return new IA_YoderIPSIter(ips,(IA_YoderIPS*)ips.ps);
    else if (itype==IA_WhiteHole_<IA_IntPoint>::s_type())
	return new WhiteIter(ips);
    else if (itype==IA_BlackHole_<IA_IntPoint>::s_type())
	return new BlackIter(ips);
    else {
	// AUGH!!
	ia_throw(IA::PSET_REQUIRE_EXTENSIVE, __FILE__, __LINE__);
	return 0;
    }
}

IA_IPSIter & IA_IPSIter::operator=(const IA_IntPointSet &x)
{
    delete this->iter;

    this->iter = make_iter(x);

    return *this;
}

IA_IPSIter & IA_IPSIter::operator=(const IA_IPSIter &x)
{
    if (x.iter==this->iter)
	return *this;

    delete this->iter;

    this->iter = x.iter->clone_self();

    return *this;
}
