JAL-2759 Generalised HiddenColsIterator naming
[jalview.git] / src / jalview / datamodel / VisibleColsIterator.java
1 package jalview.datamodel;
2
3 import java.util.ArrayList;
4 import java.util.Iterator;
5 import java.util.List;
6 import java.util.NoSuchElementException;
7
8 /**
9  * Iterator over the visible *columns* (not regions) as determined by the set of
10  * hidden columns. Uses a local copy of hidden columns.
11  * 
12  * @author kmourao
13  *
14  */
15 public class VisibleColsIterator implements Iterator<Integer>
16 {
17   private int last;
18
19   private int current;
20
21   private int next;
22
23   private List<int[]> localHidden = new ArrayList<>();
24
25   private int nexthiddenregion;
26
27   VisibleColsIterator(int firstcol, int lastcol, List<int[]> hiddenColumns)
28   {
29     last = lastcol;
30     current = firstcol;
31     next = firstcol;
32     nexthiddenregion = 0;
33
34     if (hiddenColumns != null)
35     {
36       int i = 0;
37       for (i = 0; i < hiddenColumns.size()
38               && (current <= hiddenColumns.get(i)[0]); ++i)
39       {
40         if (current >= hiddenColumns.get(i)[0]
41                 && current <= hiddenColumns.get(i)[1])
42         {
43           // current is hidden, move to right
44           current = hiddenColumns.get(i)[1] + 1;
45           next = current;
46           nexthiddenregion = i + 1;
47         }
48       }
49
50       for (i = hiddenColumns.size() - 1; i >= 0
51               && (last >= hiddenColumns.get(i)[1]); --i)
52       {
53         if (last >= hiddenColumns.get(i)[0]
54                 && last <= hiddenColumns.get(i)[1])
55         {
56           // last is hidden, move to left
57           last = hiddenColumns.get(i)[0] - 1;
58         }
59       }
60
61       // make a local copy of the bit we need
62       i = nexthiddenregion;
63       while (i < hiddenColumns.size() && hiddenColumns.get(i)[0] <= last)
64       {
65         int[] region = new int[] { hiddenColumns.get(i)[0],
66             hiddenColumns.get(i)[1] };
67         localHidden.add(region);
68         i++;
69       }
70     }
71   }
72
73   @Override
74   public boolean hasNext()
75   {
76     return next <= last;
77   }
78
79   @Override
80   public Integer next()
81   {
82     if (next > last)
83     {
84       throw new NoSuchElementException();
85     }
86     current = next;
87     if ((localHidden != null) && (nexthiddenregion < localHidden.size()))
88     {
89       // still some more hidden regions
90       if (next + 1 < localHidden.get(nexthiddenregion)[0])
91       {
92         // next+1 is still before the next hidden region
93         next++;
94       }
95       else if ((next + 1 >= localHidden.get(nexthiddenregion)[0])
96               && (next + 1 <= localHidden.get(nexthiddenregion)[1]))
97       {
98         // next + 1 is in the next hidden region
99         next = localHidden.get(nexthiddenregion)[1] + 1;
100         nexthiddenregion++;
101       }
102     }
103     else
104     {
105       // finished with hidden regions, just increment normally
106       next++;
107     }
108     return current;
109   }
110
111   @Override
112   public void remove()
113   {
114     throw new UnsupportedOperationException();
115   }
116 }