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