JAL-2759 Rearranged iterators
[jalview.git] / src / jalview / datamodel / HiddenColumnsCursor.java
1 package jalview.datamodel;
2
3 import java.util.List;
4
5 public class HiddenColumnsCursor
6 {
7   // absolute position of first hidden column
8   private int firstColumn;
9
10   // absolute position of last hidden column
11   private int lastColumn;
12
13   // index of last visited region
14   private int regionIndex;
15
16   // number of hidden columns before last visited region
17   private int hiddenSoFar;
18
19   // flag to indicate if current cursor settings are valid
20   private boolean isValid;
21
22   private List<int[]> hiddenColumns;
23
24   protected HiddenColumnsCursor()
25   {
26     isValid = false;
27   }
28
29   /**
30    * Set the cursor to a position
31    * 
32    * @param first
33    *          absolute position of first hidden column
34    * @param last
35    *          absolute position of last hidden column
36    * @param index
37    *          index of last visited region
38    * @param hiddenCount
39    *          number of hidden columns before last visited region
40    */
41   protected void resetCursor(// int first, int last, int index, int hiddenCount,
42           List<int[]> hiddenCols)
43   {
44     isValid = true;
45     if ((hiddenCols != null) && (!hiddenCols.isEmpty()))
46     {
47       hiddenColumns = hiddenCols;
48       firstColumn = hiddenColumns.get(0)[0];
49       lastColumn = hiddenColumns.get(hiddenColumns.size() - 1)[1];
50       regionIndex = 0;
51       hiddenSoFar = 0;
52     }
53   }
54
55   protected void updateCursor(int index, int hiddenCount)
56   {
57     regionIndex = index;
58     hiddenSoFar = hiddenCount;
59   }
60
61   /**
62    * Get the index of the region that column is within (if column is hidden) or
63    * which is to the right of column (if column is visible). If no hidden
64    * columns are to the right, will return size of hiddenColumns. If hidden
65    * columns is empty returns -1.
66    * 
67    * @param column
68    *          absolute position of a column in the alignment
69    * @return region index
70    */
71   protected int findRegionForColumn(int column)
72   {
73     if (hiddenColumns == null)
74     {
75       return -1;
76     }
77
78     if ((hiddenColumns.get(regionIndex)[0] <= column)
79             && (hiddenColumns.get(regionIndex)[1] >= column))
80     {
81       // we hit the jackpot
82       return regionIndex;
83     }
84     else if (column < firstColumn)
85     {
86       return 0;
87     }
88     else if (column > lastColumn)
89     {
90       return hiddenColumns.size();
91     }
92     else if (column > hiddenColumns.get(regionIndex)[1])
93     {
94       // iterate from where we are now, if we're lucky we'll be close by
95       // (but still better than iterating from 0)
96       while ((regionIndex < hiddenColumns.size())
97               && (hiddenColumns.get(regionIndex)[0] <= column))
98       {
99         int[] region = hiddenColumns.get(regionIndex);
100         hiddenSoFar += region[1] - region[0] + 1;
101         regionIndex++;
102       }
103
104     }
105     else // (column < hiddenColumns.get(regionIndex)[0])
106     {
107       int lastHidden = 0;
108       while ((regionIndex >= 0)
109               && (hiddenColumns.get(regionIndex)[0] > column))
110       {
111         int[] region = hiddenColumns.get(regionIndex);
112         hiddenSoFar -= lastHidden;
113         lastHidden = region[1] - region[0] + 1;
114         regionIndex--;
115       }
116       hiddenSoFar -= lastHidden;
117     }
118     return regionIndex;
119   }
120
121   protected int getHiddenOffset(int column)
122   {
123     if (hiddenColumns == null)
124     {
125       return -1;
126     }
127
128     if (column < firstColumn)
129     {
130       return 0;
131     }
132     else if ((regionIndex < hiddenColumns.size())
133       && (hiddenColumns.get(regionIndex)[0] <= column
134       + hiddenSoFar))
135     {
136
137       // iterate from where we are now, if we're lucky we'll be close by
138       // (but still better than iterating from 0)
139       while ((regionIndex < hiddenColumns.size())
140               && (hiddenColumns.get(regionIndex)[0] <= column
141                       + hiddenSoFar))
142       {
143         int[] region = hiddenColumns.get(regionIndex);
144         hiddenSoFar += region[1] - region[0] + 1;
145         regionIndex++;
146       }
147     }
148     else if (regionIndex < hiddenColumns.size())
149     {
150       int lastHidden = hiddenColumns.get(regionIndex)[1]
151               - hiddenColumns.get(regionIndex)[0] + 1;
152
153       while ((regionIndex >= 0)
154               && (hiddenColumns.get(regionIndex)[0] <= column + hiddenSoFar
155                       - lastHidden))
156       {
157         int[] region = hiddenColumns.get(regionIndex);
158         hiddenSoFar -= lastHidden;
159         lastHidden = region[1] - region[0] + 1;
160         regionIndex--;
161       }
162
163     }
164   
165     int result = hiddenSoFar;
166     if ((regionIndex >= 0) && (regionIndex < hiddenColumns.size())
167             && (hiddenColumns.get(regionIndex)[0] <= column + hiddenSoFar)
168             && (hiddenColumns.get(regionIndex)[1] >= column + hiddenSoFar))
169     {
170       int[] region = hiddenColumns.get(regionIndex);
171       result += region[1] - region[0] + 1;
172     }
173
174     return result;
175   }
176
177   /* public int findVisiblePositionFromAbsolute(int column)
178   {
179   
180   }
181   
182   public int findAbsolutePositionFromVisible(int column)
183   {
184   
185   }*/
186 }