JAL-1264 show/hide annotations; JAL-1481 Find tooltip
[jalview.git] / src / jalview / datamodel / SearchResults.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
3  * Copyright (C) 2014 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 public class SearchResults
24 {
25
26   Match[] matches;
27
28   /**
29    * This method replaces the old search results which merely held an alignment
30    * index of search matches. This broke when sequences were moved around the
31    * alignment
32    * 
33    * @param seq
34    *          Sequence
35    * @param start
36    *          int
37    * @param end
38    *          int
39    */
40   public void addResult(SequenceI seq, int start, int end)
41   {
42     if (matches == null)
43     {
44       matches = new Match[]
45       { new Match(seq, start, end) };
46       return;
47     }
48
49     int mSize = matches.length;
50
51     Match[] tmp = new Match[mSize + 1];
52     int m;
53     for (m = 0; m < mSize; m++)
54     {
55       tmp[m] = matches[m];
56     }
57
58     tmp[m] = new Match(seq, start, end);
59
60     matches = tmp;
61   }
62
63   /**
64    * Quickly check if the given sequence is referred to in the search results
65    * 
66    * @param sequence
67    *          (specific alignment sequence or a dataset sequence)
68    * @return true if the results involve sequence
69    */
70   public boolean involvesSequence(SequenceI sequence)
71   {
72     if (matches == null || matches.length == 0)
73     {
74       return false;
75     }
76     SequenceI ds = sequence.getDatasetSequence();
77     for (int m = 0; m < matches.length; m++)
78     {
79       if (matches[m].sequence != null
80               && (matches[m].sequence == sequence || matches[m].sequence == ds))
81       {
82         return true;
83       }
84     }
85     return false;
86   }
87
88   /**
89    * This Method returns the search matches which lie between the start and end
90    * points of the sequence in question. It is optimised for returning objects
91    * for drawing on SequenceCanvas
92    */
93   public int[] getResults(SequenceI sequence, int start, int end)
94   {
95     if (matches == null)
96     {
97       return null;
98     }
99
100     int[] result = null;
101     int[] tmp = null;
102     int resultLength, matchStart = 0, matchEnd = 0;
103     boolean mfound;
104     for (int m = 0; m < matches.length; m++)
105     {
106       mfound = false;
107       if (matches[m].sequence == sequence)
108       {
109         mfound = true;
110         // locate aligned position
111         matchStart = sequence.findIndex(matches[m].start) - 1;
112         matchEnd = sequence.findIndex(matches[m].end) - 1;
113       }
114       else if (matches[m].sequence == sequence.getDatasetSequence())
115       {
116         mfound = true;
117         // locate region in local context
118         matchStart = sequence.findIndex(matches[m].start) - 1;
119         matchEnd = sequence.findIndex(matches[m].end) - 1;
120       }
121       if (mfound)
122       {
123         if (matchStart <= end && matchEnd >= start)
124         {
125           if (matchStart < start)
126           {
127             matchStart = start;
128           }
129
130           if (matchEnd > end)
131           {
132             matchEnd = end;
133           }
134
135           if (result == null)
136           {
137             result = new int[]
138             { matchStart, matchEnd };
139           }
140           else
141           {
142             resultLength = result.length;
143             tmp = new int[resultLength + 2];
144             System.arraycopy(result, 0, tmp, 0, resultLength);
145             result = tmp;
146             result[resultLength] = matchStart;
147             result[resultLength + 1] = matchEnd;
148           }
149         }
150         else
151         {
152           // debug
153           // System.err.println("Outwith bounds!" + matchStart+">"+end +"  or "
154           // + matchEnd+"<"+start);
155         }
156       }
157     }
158     return result;
159   }
160
161   public int getSize()
162   {
163     return matches == null ? 0 : matches.length;
164   }
165
166   public SequenceI getResultSequence(int index)
167   {
168     return matches[index].sequence;
169   }
170
171   public int getResultStart(int index)
172   {
173     return matches[index].start;
174   }
175
176   public int getResultEnd(int index)
177   {
178     return matches[index].end;
179   }
180
181   class Match
182   {
183     SequenceI sequence;
184
185     int start;
186
187     int end;
188
189     public Match(SequenceI seq, int start, int end)
190     {
191       sequence = seq;
192       this.start = start;
193       this.end = end;
194     }
195   }
196 }