JAL-2759 Added in JAL-2851 fix
[jalview.git] / src / jalview / datamodel / BoundedStartRegionIterator.java
1 package jalview.datamodel;
2
3 import java.util.ArrayList;
4 import java.util.Iterator;
5 import java.util.List;
6
7 /**
8  * An iterator which iterates over visible start positions of hidden column
9  * regions in a range.
10  */
11 public class BoundedStartRegionIterator implements Iterator<Integer>
12 {
13   // start position to iterate from
14   private int start;
15
16   // end position to iterate to
17   private int end;
18
19   // current index in hiddenColumns
20   private int currentPosition = 0;
21
22   // local copy or reference to hiddenColumns
23   private List<Integer> positions = null;
24
25   /**
26    * Construct an iterator over hiddenColums bounded at [lowerBound,upperBound]
27    * 
28    * @param lowerBound
29    *          lower bound to iterate from
30    * @param upperBound
31    *          upper bound to iterate to
32    * @param useCopyCols
33    *          whether to make a local copy of hiddenColumns for iteration (set
34    *          to true if calling from outwith the HiddenColumns class)
35    */
36   BoundedStartRegionIterator(int lowerBound, int upperBound,
37           List<int[]> hiddenColumns)
38   {
39     start = lowerBound;
40     end = upperBound;
41
42     if (hiddenColumns != null)
43     {
44       positions = new ArrayList<>(hiddenColumns.size());
45
46       // navigate to start, keeping count of hidden columns
47       int i = 0;
48       int hiddenSoFar = 0;
49       while ((i < hiddenColumns.size())
50               && (hiddenColumns.get(i)[0] < start + hiddenSoFar))
51       {
52         int[] region = hiddenColumns.get(i);
53         hiddenSoFar += region[1] - region[0] + 1;
54         i++;
55       }
56
57       // iterate from start to end, adding start positions of each
58       // hidden region. Positions are visible columns count, not absolute
59       while (i < hiddenColumns.size()
60               && (hiddenColumns.get(i)[0] <= end + hiddenSoFar))
61       {
62         int[] region = hiddenColumns.get(i);
63         positions.add(region[0] - hiddenSoFar);
64         hiddenSoFar += region[1] - region[0] + 1;
65         i++;
66       }
67     }
68     else
69     {
70       positions = new ArrayList<>();
71     }
72
73   }
74
75   /**
76    * Construct an iterator over hiddenColums bounded at [lowerBound,upperBound]
77    * 
78    * @param pos
79    *          a hidden cursor position to start from - may be null
80    * @param lowerBound
81    *          lower bound to iterate from - will be ignored if pos != null
82    * @param upperBound
83    *          upper bound to iterate to
84    * @param hiddenColumns
85    *          the hidden columns collection to use
86    */
87   BoundedStartRegionIterator(HiddenCursorPosition pos, int lowerBound,
88           int upperBound, List<int[]> hiddenColumns)
89   {
90     start = lowerBound;
91     end = upperBound;
92
93     if (hiddenColumns != null)
94     {
95       positions = new ArrayList<>(hiddenColumns.size());
96
97       // navigate to start, keeping count of hidden columns
98       int i = 0;
99       int hiddenSoFar = 0;
100       
101       if (pos != null)
102       {
103         // use the cursor position provided
104         i = pos.getRegionIndex();
105         hiddenSoFar = pos.getHiddenSoFar();
106       }
107       else
108       {
109         // navigate to start
110         while ((i < hiddenColumns.size())
111                 && (hiddenColumns.get(i)[0] < start + hiddenSoFar))
112         {
113           int[] region = hiddenColumns.get(i);
114           hiddenSoFar += region[1] - region[0] + 1;
115           i++;
116         }
117       }
118
119       // iterate from start to end, adding start positions of each
120       // hidden region. Positions are visible columns count, not absolute
121       while (i < hiddenColumns.size()
122               && (hiddenColumns.get(i)[0] <= end + hiddenSoFar))
123       {
124         int[] region = hiddenColumns.get(i);
125         positions.add(region[0] - hiddenSoFar);
126         hiddenSoFar += region[1] - region[0] + 1;
127         i++;
128       }
129     }
130     else
131     {
132       positions = new ArrayList<>();
133     }
134
135   }
136
137   @Override
138   public boolean hasNext()
139   {
140     return (currentPosition < positions.size());
141   }
142
143   /**
144    * Get next hidden region start position
145    * 
146    * @return the start position in *visible* coordinates
147    */
148   @Override
149   public Integer next()
150   {
151     int result = positions.get(currentPosition);
152     currentPosition++;
153     return result;
154   }
155 }
156