Merge branch 'releases/Release_2_11_3_Branch'
[jalview.git] / src / jalview / datamodel / StartRegionIterator.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21 package jalview.datamodel;
22
23 import java.util.ArrayList;
24 import java.util.Iterator;
25 import java.util.List;
26
27 /**
28  * An iterator which iterates over visible start positions of hidden column
29  * regions in a range.
30  */
31 public class StartRegionIterator implements Iterator<Integer>
32 {
33   // start position to iterate from
34   private int start;
35
36   // end position to iterate to
37   private int end;
38
39   // current index in hiddenColumns
40   private int currentPosition = 0;
41
42   // local copy or reference to hiddenColumns
43   private List<Integer> positions = null;
44
45   /**
46    * Construct an iterator over hiddenColums bounded at [lowerBound,upperBound]
47    * 
48    * @param lowerBound
49    *          lower bound to iterate from
50    * @param upperBound
51    *          upper bound to iterate to
52    * @param useCopyCols
53    *          whether to make a local copy of hiddenColumns for iteration (set
54    *          to true if calling from outwith the HiddenColumns class)
55    */
56   StartRegionIterator(int lowerBound, int upperBound,
57           List<int[]> hiddenColumns)
58   {
59     this(null, lowerBound, upperBound, hiddenColumns);
60   }
61
62   /**
63    * Construct an iterator over hiddenColums bounded at [lowerBound,upperBound]
64    * 
65    * @param pos
66    *          a hidden cursor position to start from - may be null
67    * @param lowerBound
68    *          lower bound to iterate from - will be ignored if pos != null
69    * @param upperBound
70    *          upper bound to iterate to
71    * @param hiddenColumns
72    *          the hidden columns collection to use
73    */
74   StartRegionIterator(HiddenCursorPosition pos, int lowerBound,
75           int upperBound, List<int[]> hiddenColumns)
76   {
77     start = lowerBound;
78     end = upperBound;
79
80     if (hiddenColumns != null)
81     {
82       positions = new ArrayList<>(hiddenColumns.size());
83
84       // navigate to start, keeping count of hidden columns
85       int i = 0;
86       int hiddenSoFar = 0;
87
88       if (pos != null)
89       {
90         // use the cursor position provided
91         i = pos.getRegionIndex();
92         hiddenSoFar = pos.getHiddenSoFar();
93       }
94       else
95       {
96         // navigate to start
97         while ((i < hiddenColumns.size())
98                 && (hiddenColumns.get(i)[0] < start + hiddenSoFar))
99         {
100           int[] region = hiddenColumns.get(i);
101           hiddenSoFar += region[1] - region[0] + 1;
102           i++;
103         }
104       }
105
106       // iterate from start to end, adding start positions of each
107       // hidden region. Positions are visible columns count, not absolute
108       while (i < hiddenColumns.size()
109               && (hiddenColumns.get(i)[0] <= end + hiddenSoFar))
110       {
111         int[] region = hiddenColumns.get(i);
112         positions.add(region[0] - hiddenSoFar);
113         hiddenSoFar += region[1] - region[0] + 1;
114         i++;
115       }
116     }
117     else
118     {
119       positions = new ArrayList<>();
120     }
121
122   }
123
124   @Override
125   public boolean hasNext()
126   {
127     return (currentPosition < positions.size());
128   }
129
130   /**
131    * Get next hidden region start position
132    * 
133    * @return the start position in *visible* coordinates
134    */
135   @Override
136   public Integer next()
137   {
138     int result = positions.get(currentPosition);
139     currentPosition++;
140     return result;
141   }
142 }