JAL-1115 refactor base collection for Alignment from Vector to locally synchronized...
[jalview.git] / src / jalview / datamodel / HiddenSequences.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)
3  * Copyright (C) 2011 J Procter, AM Waterhouse, J Engelhardt, LM Lui, G Barton, M Clamp, S Searle
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 of the License, or (at your option) any later version.
10  * 
11  * Jalview is distributed in the hope that it will be useful, but 
12  * WITHOUT ANY WARRANTY; without even the implied warranty 
13  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
14  * PURPOSE.  See the GNU General Public License for more details.
15  * 
16  * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 package jalview.datamodel;
19
20 import java.util.*;
21
22 public class HiddenSequences
23 {
24   /**
25    * holds a list of hidden sequences associated with an alignment.
26    */
27   public SequenceI[] hiddenSequences;
28
29   AlignmentI alignment;
30
31   public HiddenSequences(AlignmentI al)
32   {
33     alignment = al;
34   }
35
36   public int getSize()
37   {
38     if (hiddenSequences == null)
39     {
40       return 0;
41     }
42     int count = 0;
43     for (int i = 0; i < hiddenSequences.length; i++)
44     {
45       if (hiddenSequences[i] != null)
46       {
47         count++;
48       }
49     }
50
51     return count;
52   }
53
54   public int getWidth()
55   {
56     int width = 0;
57     for (int i = 0; i < hiddenSequences.length; i++)
58     {
59       if (hiddenSequences[i] != null
60               && hiddenSequences[i].getLength() > width)
61       {
62         width = hiddenSequences[i].getLength();
63       }
64     }
65
66     return width;
67   }
68
69   /**
70    * Call this method if sequences are removed from the main alignment
71    */
72   public void adjustHeightSequenceDeleted(int seqIndex)
73   {
74     if (hiddenSequences == null)
75     {
76       return;
77     }
78
79     int alHeight = alignment.getHeight();
80
81     SequenceI[] tmp = new SequenceI[alHeight + getSize()];
82     int deletionIndex = adjustForHiddenSeqs(seqIndex);
83
84     for (int i = 0; i < hiddenSequences.length; i++)
85     {
86       if (hiddenSequences[i] == null)
87       {
88         continue;
89       }
90
91       if (i > deletionIndex)
92       {
93         tmp[i - 1] = hiddenSequences[i];
94       }
95       else
96       {
97         tmp[i] = hiddenSequences[i];
98       }
99     }
100
101     hiddenSequences = tmp;
102
103   }
104
105   /**
106    * Call this method if sequences are added to or removed from the main
107    * alignment
108    */
109   public void adjustHeightSequenceAdded()
110   {
111     if (hiddenSequences == null)
112     {
113       return;
114     }
115
116     int alHeight = alignment.getHeight();
117
118     SequenceI[] tmp = new SequenceI[alHeight + getSize()];
119     System.arraycopy(hiddenSequences, 0, tmp, 0, hiddenSequences.length);
120     hiddenSequences = tmp;
121   }
122
123   public void hideSequence(SequenceI sequence)
124   {
125     if (hiddenSequences == null)
126     {
127       hiddenSequences = new SequenceI[alignment.getHeight()];
128     }
129
130     int alignmentIndex = alignment.findIndex(sequence);
131     alignmentIndex = adjustForHiddenSeqs(alignmentIndex);
132
133     if (hiddenSequences[alignmentIndex] != null)
134     {
135       System.out.println("ERROR!!!!!!!!!!!");
136     }
137
138     hiddenSequences[alignmentIndex] = sequence;
139
140     alignment.deleteSequence(sequence);
141   }
142
143   public Vector showAll(Map<SequenceI, SequenceCollectionI> hiddenRepSequences)
144   {
145     Vector revealedSeqs = new Vector();
146     for (int i = 0; i < hiddenSequences.length; i++)
147     {
148       if (hiddenSequences[i] != null)
149       {
150         Vector tmp = showSequence(i, hiddenRepSequences);
151         for (int t = 0; t < tmp.size(); t++)
152         {
153           revealedSeqs.addElement(tmp.elementAt(t));
154         }
155       }
156     }
157     return revealedSeqs;
158   }
159
160   public Vector showSequence(int alignmentIndex, Map<SequenceI, SequenceCollectionI> hiddenRepSequences)
161   {
162     Vector revealedSeqs = new Vector();
163     SequenceI repSequence = alignment.getSequenceAt(alignmentIndex);
164     if (repSequence != null && hiddenRepSequences != null
165             && hiddenRepSequences.containsKey(repSequence))
166     {
167       hiddenRepSequences.remove(repSequence);
168       revealedSeqs.addElement(repSequence);
169     }
170
171     int start = adjustForHiddenSeqs(alignmentIndex - 1);
172     int end = adjustForHiddenSeqs(alignmentIndex);
173     if (end >= hiddenSequences.length)
174     {
175       end = hiddenSequences.length - 1;
176     }
177
178     List<SequenceI> asequences;
179     synchronized (asequences = alignment.getSequences())
180     {
181       for (int index = end; index > start; index--)
182       {
183         SequenceI seq = hiddenSequences[index];
184         hiddenSequences[index] = null;
185
186         if (seq != null)
187         {
188           if (seq.getLength() > 0)
189           {
190             revealedSeqs.addElement(seq);
191             asequences.add(alignmentIndex, seq);
192           }
193           else
194           {
195             System.out.println(seq.getName()
196                     + " has been deleted whilst hidden");
197           }
198         }
199
200       }
201     }
202
203     return revealedSeqs;
204   }
205
206   public SequenceI getHiddenSequence(int alignmentIndex)
207   {
208     return hiddenSequences[alignmentIndex];
209   }
210
211   public int findIndexWithoutHiddenSeqs(int alignmentIndex)
212   {
213     int index = 0;
214     int hiddenSeqs = 0;
215     if (hiddenSequences.length <= alignmentIndex)
216     {
217       alignmentIndex = hiddenSequences.length - 1;
218     }
219
220     while (index <= alignmentIndex)
221     {
222       if (hiddenSequences[index] != null)
223       {
224         hiddenSeqs++;
225       }
226       index++;
227     }
228     ;
229
230     return (alignmentIndex - hiddenSeqs);
231   }
232
233   public int adjustForHiddenSeqs(int alignmentIndex)
234   {
235     int index = 0;
236     int hSize = hiddenSequences.length;
237     while (index <= alignmentIndex && index < hSize)
238     {
239       if (hiddenSequences[index] != null)
240       {
241         alignmentIndex++;
242       }
243       index++;
244     }
245     ;
246
247     return alignmentIndex;
248   }
249
250   public AlignmentI getFullAlignment()
251   {
252     int isize = hiddenSequences.length;
253     SequenceI[] seq = new Sequence[isize];
254
255     int index = 0;
256     for (int i = 0; i < hiddenSequences.length; i++)
257     {
258       if (hiddenSequences[i] != null)
259       {
260         seq[i] = hiddenSequences[i];
261       }
262       else
263       {
264         seq[i] = alignment.getSequenceAt(index);
265         index++;
266       }
267     }
268
269     return new Alignment(seq);
270   }
271
272   public boolean isHidden(SequenceI seq)
273   {
274     for (int i = 0; i < hiddenSequences.length; i++)
275     {
276       if (hiddenSequences[i] != null && hiddenSequences[i] == seq)
277       {
278         return true;
279       }
280     }
281
282     return false;
283   }
284 }