001/**
002 * 
003 */
004package icy.roi;
005
006import icy.type.Position2DIterator;
007
008import java.awt.Point;
009import java.awt.geom.Point2D;
010import java.util.NoSuchElementException;
011
012/**
013 * BooleanMask2D iterator.<br>
014 * This class permit to use simple iterator to navigate each point of specified BooleanMask2D in XY
015 * <i>([Y[X]])</i> dimension order.<br>
016 * <b>If the BooleanMask is modified during iteration the iterator becomes invalid and exception can
017 * happen.</b>
018 * 
019 * @author Stephane
020 */
021public class BooleanMask2DIterator implements Position2DIterator
022{
023    protected final BooleanMask2D mask;
024    protected final int w, h;
025    protected int x, y;
026    protected int off;
027    protected boolean done;
028
029    /**
030     * Create a new BooleanMask2D iterator to iterate each point through the specified
031     * <code>BooleanMask2D</code>
032     * 
033     * @param mask
034     *        BooleanMask2D to iterate
035     */
036    public BooleanMask2DIterator(BooleanMask2D mask)
037    {
038        super();
039
040        this.mask = mask;
041        // cached
042        w = mask.bounds.width;
043        h = mask.bounds.height;
044
045        // start iterator
046        reset();
047    }
048
049    public int getMinX()
050    {
051        return mask.bounds.x;
052    }
053
054    public int getMaxX()
055    {
056        return (mask.bounds.x + w) - 1;
057    }
058
059    public int getMinY()
060    {
061        return mask.bounds.y;
062    }
063
064    public int getMaxY()
065    {
066        return (mask.bounds.y + h) - 1;
067    }
068
069    @Override
070    public void reset()
071    {
072        done = mask.bounds.isEmpty();
073
074        if (!done)
075        {
076            // reset position
077            y = 0;
078            x = -1;
079            off = -1;
080            // allow to correctly set initial position in boolean mask
081            next();
082        }
083    }
084
085    @Override
086    public void next()
087    {
088        if (done)
089            throw new NoSuchElementException();
090
091        do
092            nextPosition();
093        // advance while mask do not contains current point
094        while (!done && !mask.mask[off]);
095    }
096
097    /**
098     * Advance one position
099     */
100    protected void nextPosition()
101    {
102        off++;
103        if (++x >= w)
104        {
105            x = 0;
106            if (++y >= h)
107                done = true;
108        }
109    }
110
111    @Override
112    public boolean done()
113    {
114        return done;
115    }
116
117    @Override
118    public Point2D get()
119    {
120        if (done)
121            throw new NoSuchElementException();
122
123        return new Point(getX(), getY());
124    }
125
126    @Override
127    public int getX()
128    {
129        if (done)
130            throw new NoSuchElementException();
131
132        return x + mask.bounds.x;
133    }
134
135    @Override
136    public int getY()
137    {
138        if (done)
139            throw new NoSuchElementException();
140
141        return y + mask.bounds.y;
142    }
143}