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