apply gpl development license
[jalview.git] / src / jalview / datamodel / SearchResults.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Development Version 2.4.1)
3  * Copyright (C) 2009 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
4  * 
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  * 
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  * 
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
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    * Quickly check if the given sequence is referred to in the search results
62    * @param sequence (specific alignment sequence or a dataset sequence)
63    * @return true if the results involve sequence
64    */
65   public boolean involvesSequence(SequenceI sequence)
66   {
67     if (matches==null || matches.length==0)
68     {
69       return false;
70     }
71     SequenceI ds = sequence.getDatasetSequence();
72     for (int m=0; m<matches.length; m++)
73     {
74       if (matches[m].sequence!=null &&
75               (matches[m].sequence==sequence 
76               || matches[m].sequence==ds))
77       {
78         return true;
79       }
80     }
81     return false;
82   }
83   /**
84    * This Method returns the search matches which lie between the start and end
85    * points of the sequence in question. It is optimised for returning objects
86    * for drawing on SequenceCanvas
87    */
88   public int[] getResults(SequenceI sequence, int start, int end)
89   {
90     if (matches == null)
91     {
92       return null;
93     }
94
95     int[] result = null;
96     int[] tmp = null;
97     int resultLength, matchStart = 0, matchEnd = 0;
98     boolean mfound;
99     for (int m = 0; m < matches.length; m++)
100     {
101       mfound = false;
102       if (matches[m].sequence == sequence)
103       {
104         mfound = true;
105         // locate aligned position
106         matchStart = sequence.findIndex(matches[m].start) - 1;
107         matchEnd = sequence.findIndex(matches[m].end) - 1;
108       }
109       else if (matches[m].sequence == sequence.getDatasetSequence())
110       {
111         mfound = true;
112         // locate region in local context
113         matchStart = sequence.findIndex(matches[m].start) - 1;
114         matchEnd = sequence.findIndex(matches[m].end) - 1;
115       }
116       if (mfound)
117       {
118         if (matchStart <= end && matchEnd >= start)
119         {
120           if (matchStart < start)
121           {
122             matchStart = start;
123           }
124
125           if (matchEnd > end)
126           {
127             matchEnd = end;
128           }
129
130           if (result == null)
131           {
132             result = new int[]
133             { matchStart, matchEnd };
134           }
135           else
136           {
137             resultLength = result.length;
138             tmp = new int[resultLength + 2];
139             System.arraycopy(result, 0, tmp, 0, resultLength);
140             result = tmp;
141             result[resultLength] = matchStart;
142             result[resultLength + 1] = matchEnd;
143           }
144         }
145       }
146     }
147     return result;
148   }
149
150   public int getSize()
151   {
152     return matches == null ? 0 : matches.length;
153   }
154
155   public SequenceI getResultSequence(int index)
156   {
157     return matches[index].sequence;
158   }
159
160   public int getResultStart(int index)
161   {
162     return matches[index].start;
163   }
164
165   public int getResultEnd(int index)
166   {
167     return matches[index].end;
168   }
169
170   class Match
171   {
172     SequenceI sequence;
173
174     int start;
175
176     int end;
177
178     public Match(SequenceI seq, int start, int end)
179     {
180       sequence = seq;
181       this.start = start;
182       this.end = end;
183     }
184   }
185 }