c79972c514e02096d36c5862e4dc0996c0c751fb
[jalview.git] / src / jalview / datamodel / SearchResults.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8)
3  * Copyright (C) 2012 J Procter, AM Waterhouse, LM Lui, J Engelhardt, 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         }
147         else
148         {
149           // debug
150           // System.err.println("Outwith bounds!" + matchStart+">"+end +"  or "
151           // + matchEnd+"<"+start);
152         }
153       }
154     }
155     return result;
156   }
157
158   public int getSize()
159   {
160     return matches == null ? 0 : matches.length;
161   }
162
163   public SequenceI getResultSequence(int index)
164   {
165     return matches[index].sequence;
166   }
167
168   public int getResultStart(int index)
169   {
170     return matches[index].start;
171   }
172
173   public int getResultEnd(int index)
174   {
175     return matches[index].end;
176   }
177
178   class Match
179   {
180     SequenceI sequence;
181
182     int start;
183
184     int end;
185
186     public Match(SequenceI seq, int start, int end)
187     {
188       sequence = seq;
189       this.start = start;
190       this.end = end;
191     }
192   }
193 }