javadoc
[jalview.git] / src / jalview / datamodel / ColumnSelection.java
1 /*\r
2  * Jalview - A Sequence Alignment Editor and Viewer\r
3  * Copyright (C) 2007 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
4  *\r
5  * This program is free software; you can redistribute it and/or\r
6  * modify it under the terms of the GNU General Public License\r
7  * as published by the Free Software Foundation; either version 2\r
8  * of the License, or (at your option) any later version.\r
9  *\r
10  * This program is distributed in the hope that it will be useful,\r
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13  * GNU General Public License for more details.\r
14  *\r
15  * You should have received a copy of the GNU General Public License\r
16  * along with this program; if not, write to the Free Software\r
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
18  */\r
19 package jalview.datamodel;\r
20 \r
21 import java.util.*;\r
22 \r
23 import jalview.util.*;\r
24 \r
25 /**\r
26  * NOTE: Columns are zero based.\r
27  */\r
28 public class ColumnSelection\r
29 {\r
30   Vector selected = new Vector();\r
31 \r
32   //Vector of int [] {startCol, endCol}\r
33   Vector hiddenColumns;\r
34 \r
35   /**\r
36    * Add a column to the selection\r
37    *\r
38    * @param col index of column\r
39    */\r
40   public void addElement(int col)\r
41   {\r
42     Integer column = new Integer(col);\r
43     if (!selected.contains(column))\r
44     {\r
45       selected.addElement(column);\r
46     }\r
47   }\r
48 \r
49   /**\r
50    * clears column selection\r
51    */\r
52   public void clear()\r
53   {\r
54     selected.removeAllElements();\r
55   }\r
56 \r
57   /**\r
58    * removes col from selection\r
59    *\r
60    * @param col index of column to be removed\r
61    */\r
62   public void removeElement(int col)\r
63   {\r
64     Integer colInt = new Integer(col);\r
65 \r
66     if (selected.contains(colInt))\r
67     {\r
68       selected.removeElement(colInt);\r
69     }\r
70   }\r
71 \r
72   /**\r
73    * removes a range of columns from the selection\r
74    * @param start int - first column in range to be removed\r
75    * @param end int - last col\r
76    */\r
77   public void removeElements(int start, int end)\r
78   {\r
79     Integer colInt;\r
80     for (int i = start; i < end; i++)\r
81     {\r
82       colInt = new Integer(i);\r
83       if (selected.contains(colInt))\r
84       {\r
85         selected.removeElement(colInt);\r
86       }\r
87     }\r
88   }\r
89 \r
90   /**\r
91    *\r
92    * @return Vector containing selected columns as Integers\r
93    */\r
94   public Vector getSelected()\r
95   {\r
96     return selected;\r
97   }\r
98 \r
99   /**\r
100    *\r
101    * @param col index to search for in column selection\r
102    *\r
103    * @return true if Integer(col) is in selection.\r
104    */\r
105   public boolean contains(int col)\r
106   {\r
107     return selected.contains(new Integer(col));\r
108   }\r
109 \r
110   /**\r
111    * DOCUMENT ME!\r
112    *\r
113    * @param i DOCUMENT ME!\r
114    *\r
115    * @return DOCUMENT ME!\r
116    */\r
117   public int columnAt(int i)\r
118   {\r
119     return ( (Integer) selected.elementAt(i)).intValue();\r
120   }\r
121 \r
122   /**\r
123    * DOCUMENT ME!\r
124    *\r
125    * @return DOCUMENT ME!\r
126    */\r
127   public int size()\r
128   {\r
129     return selected.size();\r
130   }\r
131 \r
132   /**\r
133    * DOCUMENT ME!\r
134    *\r
135    * @return DOCUMENT ME!\r
136    */\r
137   public int getMax()\r
138   {\r
139     int max = -1;\r
140 \r
141     for (int i = 0; i < selected.size(); i++)\r
142     {\r
143       if (columnAt(i) > max)\r
144       {\r
145         max = columnAt(i);\r
146       }\r
147     }\r
148 \r
149     return max;\r
150   }\r
151 \r
152   /**\r
153    * DOCUMENT ME!\r
154    *\r
155    * @return DOCUMENT ME!\r
156    */\r
157   public int getMin()\r
158   {\r
159     int min = 1000000000;\r
160 \r
161     for (int i = 0; i < selected.size(); i++)\r
162     {\r
163       if (columnAt(i) < min)\r
164       {\r
165         min = columnAt(i);\r
166       }\r
167     }\r
168 \r
169     return min;\r
170   }\r
171 \r
172   /**\r
173    * propagate shift in alignment columns to column selection\r
174    *\r
175    * @param start beginning of edit\r
176    * @param left shift in edit (+ve for removal, or -ve for inserts)\r
177    */\r
178   public Vector compensateForEdit(int start, int change)\r
179   {\r
180     Vector deletedHiddenColumns = null;\r
181     for (int i = 0; i < size(); i++)\r
182     {\r
183       int temp = columnAt(i);\r
184 \r
185       if (temp >= start)\r
186       {\r
187         selected.setElementAt(new Integer(temp - change), i);\r
188       }\r
189     }\r
190 \r
191     if (hiddenColumns != null)\r
192     {\r
193       deletedHiddenColumns = new Vector();\r
194       int hSize = hiddenColumns.size();\r
195       for (int i = 0; i < hSize; i++)\r
196       {\r
197         int[] region = (int[]) hiddenColumns.elementAt(i);\r
198         if (region[0] > start && start + change > region[1])\r
199         {\r
200           deletedHiddenColumns.addElement(\r
201               hiddenColumns.elementAt(i));\r
202 \r
203           hiddenColumns.removeElementAt(i);\r
204           i--;\r
205           hSize--;\r
206           continue;\r
207         }\r
208 \r
209         if (region[0] > start)\r
210         {\r
211           region[0] -= change;\r
212           region[1] -= change;\r
213         }\r
214 \r
215         if (region[0] < 0)\r
216         {\r
217           region[0] = 0;\r
218         }\r
219 \r
220       }\r
221 \r
222       this.revealHiddenColumns(0);\r
223     }\r
224 \r
225     return deletedHiddenColumns;\r
226   }\r
227 \r
228   /**\r
229    * propagate shift in alignment columns to column selection\r
230    * special version of compensateForEdit - allowing for edits within hidden regions\r
231    * @param start beginning of edit\r
232    * @param left shift in edit (+ve for removal, or -ve for inserts)\r
233    */\r
234   private void compensateForDelEdits(int start, int change)\r
235   {\r
236     for (int i = 0; i < size(); i++)\r
237     {\r
238       int temp = columnAt(i);\r
239 \r
240       if (temp >= start)\r
241       {\r
242         selected.setElementAt(new Integer(temp - change), i);\r
243       }\r
244     }\r
245 \r
246     if (hiddenColumns != null)\r
247     {\r
248       for (int i = 0; i < hiddenColumns.size(); i++)\r
249       {\r
250         int[] region = (int[]) hiddenColumns.elementAt(i);\r
251         if (region[0] >= start)\r
252         {\r
253           region[0] -= change;\r
254         }\r
255         if (region[1] >= start)\r
256         {\r
257           region[1] -= change;\r
258         }\r
259         if (region[1] < region[0])\r
260         {\r
261           hiddenColumns.removeElementAt(i--);\r
262         }\r
263 \r
264         if (region[0] < 0)\r
265         {\r
266           region[0] = 0;\r
267         }\r
268         if (region[1] < 0)\r
269         {\r
270           region[1] = 0;\r
271         }\r
272       }\r
273     }\r
274   }\r
275 \r
276   /**\r
277    * Adjust hidden column boundaries based on a series of column\r
278    * additions or deletions in visible regions.\r
279    * @param shiftrecord\r
280    * @return\r
281    */\r
282   public ShiftList compensateForEdits(ShiftList shiftrecord)\r
283   {\r
284     if (shiftrecord != null)\r
285     {\r
286       Vector shifts = shiftrecord.shifts;\r
287       if (shifts != null && shifts.size() > 0)\r
288       {\r
289         int shifted = 0;\r
290         for (int i = 0, j = shifts.size(); i < j; i++)\r
291         {\r
292           int[] sh = (int[]) shifts.elementAt(i);\r
293           //compensateForEdit(shifted+sh[0], sh[1]);\r
294           compensateForDelEdits(shifted + sh[0], sh[1]);\r
295           shifted -= sh[1];\r
296         }\r
297       }\r
298       return shiftrecord.getInverse();\r
299     }\r
300     return null;\r
301   }\r
302 \r
303   /**\r
304    * removes intersection of position,length ranges in deletions\r
305    * from the start,end regions marked in intervals.\r
306    * @param deletions\r
307    * @param intervals\r
308    * @return\r
309    */\r
310   private boolean pruneIntervalVector(Vector deletions, Vector intervals)\r
311   {\r
312     boolean pruned = false;\r
313     int i = 0, j = intervals.size() - 1, s = 0, t = deletions.size() - 1;\r
314     int hr[] = (int[]) intervals.elementAt(i);\r
315     int sr[] = (int[]) deletions.elementAt(s);\r
316     while (i <= j && s <= t)\r
317     {\r
318       boolean trailinghn = hr[1] >= sr[0];\r
319       if (!trailinghn)\r
320       {\r
321         if (i < j)\r
322         {\r
323           hr = (int[]) intervals.elementAt(++i);\r
324         }\r
325         else\r
326         {\r
327           i++;\r
328         }\r
329         continue;\r
330       }\r
331       int endshift = sr[0] + sr[1]; // deletion ranges - -ve means an insert\r
332       if (endshift < hr[0] || endshift < sr[0])\r
333       { // leadinghc disjoint or not a deletion\r
334         if (s < t)\r
335         {\r
336           sr = (int[]) deletions.elementAt(++s);\r
337         }\r
338         else\r
339         {\r
340           s++;\r
341         }\r
342         continue;\r
343       }\r
344       boolean leadinghn = hr[0] >= sr[0];\r
345       boolean leadinghc = hr[0] < endshift;\r
346       boolean trailinghc = hr[1] < endshift;\r
347       if (leadinghn)\r
348       {\r
349         if (trailinghc)\r
350         { // deleted hidden region.\r
351           intervals.removeElementAt(i);\r
352           pruned = true;\r
353           j--;\r
354           if (i <= j)\r
355           {\r
356             hr = (int[]) intervals.elementAt(i);\r
357           }\r
358           continue;\r
359         }\r
360         if (leadinghc)\r
361         {\r
362           hr[0] = endshift; // clip c terminal region\r
363           leadinghn = !leadinghn;\r
364           pruned = true;\r
365         }\r
366       }\r
367       if (!leadinghn)\r
368       {\r
369         if (trailinghc)\r
370         {\r
371           if (trailinghn)\r
372           {\r
373             hr[1] = sr[0] - 1;\r
374             pruned = true;\r
375           }\r
376         }\r
377         else\r
378         {\r
379           // sr contained in hr\r
380           if (s < t)\r
381           {\r
382             sr = (int[]) deletions.elementAt(++s);\r
383           }\r
384           else\r
385           {\r
386             s++;\r
387           }\r
388           continue;\r
389         }\r
390       }\r
391     }\r
392     return pruned; // true if any interval was removed or modified by operations.\r
393   }\r
394 \r
395   private boolean pruneColumnList(Vector deletion, Vector list)\r
396   {\r
397     int s = 0, t = deletion.size();\r
398     int[] sr = (int[]) list.elementAt(s++);\r
399     boolean pruned = false;\r
400     int i = 0, j = list.size();\r
401     while (i < j && s <= t)\r
402     {\r
403       int c = ( (Integer) list.elementAt(i++)).intValue();\r
404       if (sr[0] <= c)\r
405       {\r
406         if (sr[1] + sr[0] >= c)\r
407         { // sr[1] -ve means inseriton.\r
408           list.removeElementAt(--i);\r
409           j--;\r
410         }\r
411         else\r
412         {\r
413           if (s < t)\r
414           {\r
415             sr = (int[]) deletion.elementAt(s);\r
416           }\r
417           s++;\r
418         }\r
419       }\r
420     }\r
421     return pruned;\r
422   }\r
423 \r
424   /**\r
425    * remove any hiddenColumns or selected columns and shift remaining\r
426    * based on a series of position, range deletions.\r
427    * @param deletions\r
428    */\r
429   public void pruneDeletions(ShiftList deletions)\r
430   {\r
431     if (deletions != null)\r
432     {\r
433       Vector shifts = deletions.shifts;\r
434       if (shifts != null && shifts.size() > 0)\r
435       {\r
436         // delete any intervals intersecting.\r
437         if (hiddenColumns != null)\r
438         {\r
439           pruneIntervalVector(shifts, hiddenColumns);\r
440           if (hiddenColumns != null && hiddenColumns.size() == 0)\r
441           {\r
442             hiddenColumns = null;\r
443           }\r
444         }\r
445         if (selected != null && selected.size() > 0)\r
446         {\r
447           pruneColumnList(shifts, selected);\r
448           if (selected != null && selected.size() == 0)\r
449           {\r
450             selected = null;\r
451           }\r
452         }\r
453         // and shift the rest.\r
454         this.compensateForEdits(deletions);\r
455       }\r
456     }\r
457   }\r
458 \r
459   /**\r
460    * This Method is used to return all the HiddenColumn regions\r
461    * less than the given index.\r
462    * @param end int\r
463    * @return Vector\r
464    */\r
465   public Vector getHiddenColumns()\r
466   {\r
467     return hiddenColumns;\r
468   }\r
469 \r
470   /**\r
471    * Return absolute column index for a visible column index\r
472    * @param column int column index in alignment view\r
473    * @return alignment column index for column\r
474    */\r
475   public int adjustForHiddenColumns(int column)\r
476   {\r
477     int result = column;\r
478     if (hiddenColumns != null)\r
479     {\r
480       for (int i = 0; i < hiddenColumns.size(); i++)\r
481       {\r
482         int[] region = (int[]) hiddenColumns.elementAt(i);\r
483         if (result >= region[0])\r
484         {\r
485           result += region[1] - region[0] + 1;\r
486         }\r
487       }\r
488     }\r
489     return result;\r
490   }\r
491 \r
492   /**\r
493    * Use this method to find out where a visible column is in the alignment\r
494    * when hidden columns exist\r
495    * @param hiddenColumn int\r
496    * @return int\r
497    */\r
498   public int findColumnPosition(int hiddenColumn)\r
499   {\r
500     int result = hiddenColumn;\r
501     if (hiddenColumns != null)\r
502     {\r
503       int index = 0;\r
504       int gaps = 0;\r
505       do\r
506       {\r
507         int[] region = (int[]) hiddenColumns.elementAt(index);\r
508         if (hiddenColumn > region[1])\r
509         {\r
510           result -= region[1] + 1 - region[0];\r
511         }\r
512         index++;\r
513       }\r
514       while (index < hiddenColumns.size());\r
515 \r
516       result -= gaps;\r
517     }\r
518 \r
519     return result;\r
520   }\r
521 \r
522   /**\r
523    * Use this method to determine where the next hiddenRegion starts\r
524    */\r
525   public int findHiddenRegionPosition(int hiddenRegion)\r
526   {\r
527     int result = 0;\r
528     if (hiddenColumns != null)\r
529     {\r
530       int index = 0;\r
531       int gaps = 0;\r
532       do\r
533       {\r
534         int[] region = (int[]) hiddenColumns.elementAt(index);\r
535         if (hiddenRegion == 0)\r
536         {\r
537           return region[0];\r
538         }\r
539 \r
540         gaps += region[1] + 1 - region[0];\r
541         result = region[1] + 1;\r
542         index++;\r
543       }\r
544       while (index < hiddenRegion + 1);\r
545 \r
546       result -= gaps;\r
547     }\r
548 \r
549     return result;\r
550   }\r
551 \r
552   /**\r
553    * THis method returns the rightmost limit of a\r
554    * region of an alignment with hidden columns.\r
555    * In otherwords, the next hidden column.\r
556    * @param index int\r
557    */\r
558   public int getHiddenBoundaryRight(int alPos)\r
559   {\r
560     if (hiddenColumns != null)\r
561     {\r
562       int index = 0;\r
563       do\r
564       {\r
565         int[] region = (int[]) hiddenColumns.elementAt(index);\r
566         if (alPos < region[0])\r
567         {\r
568           return region[0];\r
569         }\r
570 \r
571         index++;\r
572       }\r
573       while (index < hiddenColumns.size());\r
574     }\r
575 \r
576     return alPos;\r
577 \r
578   }\r
579 \r
580   /**\r
581    * This method returns the leftmost limit of a\r
582    * region of an alignment with hidden columns.\r
583    * In otherwords, the previous hidden column.\r
584    * @param index int\r
585    */\r
586   public int getHiddenBoundaryLeft(int alPos)\r
587   {\r
588     if (hiddenColumns != null)\r
589     {\r
590       int index = hiddenColumns.size() - 1;\r
591       do\r
592       {\r
593         int[] region = (int[]) hiddenColumns.elementAt(index);\r
594         if (alPos > region[1])\r
595         {\r
596           return region[1];\r
597         }\r
598 \r
599         index--;\r
600       }\r
601       while (index > -1);\r
602     }\r
603 \r
604     return alPos;\r
605 \r
606   }\r
607 \r
608   public void hideSelectedColumns()\r
609   {\r
610     while (size() > 0)\r
611     {\r
612       int column = ( (Integer) getSelected().firstElement()).intValue();\r
613       hideColumns(column);\r
614     }\r
615 \r
616   }\r
617 \r
618   public void hideColumns(int start, int end)\r
619   {\r
620     if (hiddenColumns == null)\r
621     {\r
622       hiddenColumns = new Vector();\r
623     }\r
624 \r
625     boolean added = false;\r
626     boolean overlap = false;\r
627 \r
628     for (int i = 0; i < hiddenColumns.size(); i++)\r
629     {\r
630       int[] region = (int[]) hiddenColumns.elementAt(i);\r
631       if (start <= region[1] && end >= region[0])\r
632       {\r
633         hiddenColumns.removeElementAt(i);\r
634         overlap = true;\r
635         break;\r
636       }\r
637       else if (end < region[0] && start < region[0])\r
638       {\r
639         hiddenColumns.insertElementAt(new int[]\r
640                                       {start, end}, i);\r
641         added = true;\r
642         break;\r
643       }\r
644     }\r
645 \r
646     if (overlap)\r
647     {\r
648       hideColumns(start, end);\r
649     }\r
650     else if (!added)\r
651     {\r
652       hiddenColumns.addElement(new int[]\r
653                                {start, end});\r
654     }\r
655 \r
656   }\r
657 \r
658   /**\r
659    * This method will find a range of selected columns\r
660    * around the column specified\r
661    * @param res int\r
662    */\r
663   public void hideColumns(int col)\r
664   {\r
665     // First find out range of columns to hide\r
666     int min = col, max = col + 1;\r
667     while (contains(min))\r
668     {\r
669       removeElement(min);\r
670       min--;\r
671     }\r
672 \r
673     while (contains(max))\r
674     {\r
675       removeElement(max);\r
676       max++;\r
677     }\r
678 \r
679     min++;\r
680     max--;\r
681     if (min > max)\r
682     {\r
683       min = max;\r
684     }\r
685 \r
686     hideColumns(min, max);\r
687   }\r
688 \r
689   public void revealAllHiddenColumns()\r
690   {\r
691     if (hiddenColumns != null)\r
692     {\r
693       for (int i = 0; i < hiddenColumns.size(); i++)\r
694       {\r
695         int[] region = (int[]) hiddenColumns.elementAt(i);\r
696         for (int j = region[0]; j < region[1] + 1; j++)\r
697         {\r
698           addElement(j);\r
699         }\r
700       }\r
701     }\r
702 \r
703     hiddenColumns = null;\r
704   }\r
705 \r
706   public void revealHiddenColumns(int res)\r
707   {\r
708     for (int i = 0; i < hiddenColumns.size(); i++)\r
709     {\r
710       int[] region = (int[]) hiddenColumns.elementAt(i);\r
711       if (res == region[0])\r
712       {\r
713         for (int j = region[0]; j < region[1] + 1; j++)\r
714         {\r
715           addElement(j);\r
716         }\r
717 \r
718         hiddenColumns.removeElement(region);\r
719         break;\r
720       }\r
721     }\r
722     if (hiddenColumns.size() == 0)\r
723     {\r
724       hiddenColumns = null;\r
725     }\r
726   }\r
727 \r
728   public boolean isVisible(int column)\r
729   {\r
730     if (hiddenColumns != null)\r
731       for (int i = 0; i < hiddenColumns.size(); i++)\r
732       {\r
733         int[] region = (int[]) hiddenColumns.elementAt(i);\r
734         if (column >= region[0] && column <= region[1])\r
735         {\r
736           return false;\r
737         }\r
738       }\r
739 \r
740     return true;\r
741   }\r
742 \r
743   /**\r
744    * Copy constructor\r
745    * @param copy\r
746    */\r
747   public ColumnSelection(ColumnSelection copy)\r
748   {\r
749     if (copy != null)\r
750     {\r
751       if (copy.selected != null)\r
752       {\r
753         selected = new Vector();\r
754         for (int i = 0, j = copy.selected.size(); i < j; i++)\r
755         {\r
756           selected.addElement(copy.selected.elementAt(i));\r
757         }\r
758       }\r
759       if (copy.hiddenColumns != null)\r
760       {\r
761         hiddenColumns = new Vector(copy.hiddenColumns.size());\r
762         for (int i = 0, j = copy.hiddenColumns.size(); i < j; i++)\r
763         {\r
764           int[] rh, cp;\r
765           rh = (int[]) copy.hiddenColumns.elementAt(i);\r
766           if (rh != null)\r
767           {\r
768             cp = new int[rh.length];\r
769             System.arraycopy(rh, 0, cp, 0, rh.length);\r
770             hiddenColumns.addElement(cp);\r
771           }\r
772         }\r
773       }\r
774     }\r
775   }\r
776 \r
777   /**\r
778    * ColumnSelection\r
779    */\r
780   public ColumnSelection()\r
781   {\r
782   }\r
783 \r
784   public String[] getVisibleSequenceStrings(int start, int end,\r
785                                             SequenceI[] seqs)\r
786   {\r
787     int i, iSize = seqs.length;\r
788     String selection[] = new String[iSize];\r
789     if (hiddenColumns != null && hiddenColumns.size() > 0)\r
790     {\r
791       for (i = 0; i < iSize; i++)\r
792       {\r
793         StringBuffer visibleSeq = new StringBuffer();\r
794         Vector regions = getHiddenColumns();\r
795 \r
796         int blockStart = start, blockEnd = end;\r
797         int[] region;\r
798         int hideStart, hideEnd;\r
799 \r
800         for (int j = 0; j < regions.size(); j++)\r
801         {\r
802           region = (int[]) regions.elementAt(j);\r
803           hideStart = region[0];\r
804           hideEnd = region[1];\r
805 \r
806           if (hideStart < start)\r
807           {\r
808             continue;\r
809           }\r
810 \r
811           blockStart = Math.min(blockStart, hideEnd + 1);\r
812           blockEnd = Math.min(blockEnd, hideStart);\r
813 \r
814           if (blockStart > blockEnd)\r
815           {\r
816             break;\r
817           }\r
818 \r
819           visibleSeq.append(seqs[i].getSequence(blockStart, blockEnd));\r
820 \r
821           blockStart = hideEnd + 1;\r
822           blockEnd = end;\r
823         }\r
824 \r
825         if (end > blockStart)\r
826         {\r
827           visibleSeq.append(seqs[i].getSequence(blockStart, end));\r
828         }\r
829 \r
830         selection[i] = visibleSeq.toString();\r
831       }\r
832     }\r
833     else\r
834     {\r
835       for (i = 0; i < iSize; i++)\r
836       {\r
837         selection[i] = seqs[i].getSequenceAsString(start, end);\r
838       }\r
839     }\r
840 \r
841     return selection;\r
842   }\r
843 \r
844   /**\r
845    * return all visible segments between the given start and end boundaries\r
846    *\r
847    * @param start (first column inclusive from 0)\r
848    * @param end (last column - not inclusive)\r
849    * @return int[] {i_start, i_end, ..} where intervals lie in start<=i_start<=i_end<end\r
850    */\r
851   public int[] getVisibleContigs(int start, int end)\r
852   {\r
853     if (hiddenColumns != null && hiddenColumns.size() > 0)\r
854     {\r
855       Vector visiblecontigs = new Vector();\r
856       Vector regions = getHiddenColumns();\r
857 \r
858       int vstart = start;\r
859       int[] region;\r
860       int hideStart, hideEnd;\r
861 \r
862       for (int j = 0; vstart < end && j < regions.size(); j++)\r
863       {\r
864         region = (int[]) regions.elementAt(j);\r
865         hideStart = region[0];\r
866         hideEnd = region[1];\r
867 \r
868         if (hideEnd < vstart)\r
869         {\r
870           continue;\r
871         }\r
872         if (hideStart > vstart)\r
873         {\r
874           visiblecontigs.addElement(new int[]\r
875                                     {vstart, hideStart - 1});\r
876         }\r
877         vstart = hideEnd + 1;\r
878       }\r
879 \r
880       if (vstart < end)\r
881       {\r
882         visiblecontigs.addElement(new int[]\r
883                                   {vstart, end - 1});\r
884       }\r
885       int[] vcontigs = new int[visiblecontigs.size() * 2];\r
886       for (int i = 0, j = visiblecontigs.size(); i < j; i++)\r
887       {\r
888         int[] vc = (int[]) visiblecontigs.elementAt(i);\r
889         visiblecontigs.setElementAt(null, i);\r
890         vcontigs[i * 2] = vc[0];\r
891         vcontigs[i * 2 + 1] = vc[1];\r
892       }\r
893       visiblecontigs.removeAllElements();\r
894       return vcontigs;\r
895     }\r
896     else\r
897     {\r
898       return new int[]\r
899           {\r
900           start, end - 1};\r
901     }\r
902   }\r
903 }\r