Redundant code commented out
[jalview.git] / src / MCview / PDBCanvas.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer
3  * Copyright (C) 2007 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 MCview;
20
21 import java.io.*;
22 import java.util.*;
23
24 // JBPNote TODO: This class is quite noisy - needs proper log.info/log.debug
25 import java.awt.*;
26 import java.awt.event.*;
27 import javax.swing.*;
28
29 import jalview.analysis.*;
30 import jalview.datamodel.*;
31
32 public class PDBCanvas
33     extends JPanel implements MouseListener, MouseMotionListener
34 {
35   MCMatrix idmat = new MCMatrix(3, 3);
36   MCMatrix objmat = new MCMatrix(3, 3);
37   boolean redrawneeded = true;
38   int omx = 0;
39   int mx = 0;
40   int omy = 0;
41   int my = 0;
42   public PDBfile pdb;
43   int bsize;
44   Image img;
45   Graphics ig;
46   Dimension prefsize;
47   float[] centre = new float[3];
48   float[] width = new float[3];
49   float maxwidth;
50   float scale;
51   String inStr;
52   String inType;
53   boolean bysequence = true;
54   boolean depthcue = true;
55   boolean wire = false;
56   boolean bymolecule = false;
57   boolean zbuffer = true;
58   boolean dragging;
59   int xstart;
60   int xend;
61   int ystart;
62   int yend;
63   int xmid;
64   int ymid;
65   Font font = new Font("Helvetica", Font.PLAIN, 10);
66   jalview.gui.SeqCanvas seqcanvas;
67   public Sequence sequence;
68   final StringBuffer mappingDetails = new StringBuffer();
69   PDBChain mainchain;
70   Vector highlightRes;
71   boolean pdbAction = false;
72   boolean seqColoursReady = false;
73   jalview.gui.FeatureRenderer fr;
74   Color backgroundColour = Color.black;
75
76   public PDBCanvas(jalview.gui.SeqCanvas seqcanvas, Sequence seq)
77   {
78     this.seqcanvas = seqcanvas;
79     this.sequence = seq;
80   }
81
82   public void setPDBFile(PDBfile pdb)
83   {
84     int max = -10;
85     int maxchain = -1;
86     int pdbstart = 0;
87     int pdbend = 0;
88     int seqstart = 0;
89     int seqend = 0;
90     AlignSeq maxAlignseq = null;
91
92     for (int i = 0; i < pdb.chains.size(); i++)
93     {
94
95       mappingDetails.append("\n\nPDB Sequence is :\nSequence = " +
96                             ( (PDBChain) pdb.chains.elementAt(i)).sequence.
97                             getSequenceAsString());
98       mappingDetails.append("\nNo of residues = " +
99                             ( (PDBChain) pdb.chains.elementAt(i)).residues.size() +
100                             "\n\n");
101
102       // Now lets compare the sequences to get
103       // the start and end points.
104       // Align the sequence to the pdb
105       AlignSeq as = new AlignSeq(sequence,
106                                  ( (PDBChain) pdb.chains.elementAt(i)).sequence,
107                                  AlignSeq.PEP);
108       as.calcScoreMatrix();
109       as.traceAlignment();
110       PrintStream ps = new PrintStream(System.out)
111       {
112         public void print(String x)
113         {
114           mappingDetails.append(x);
115         }
116
117         public void println()
118         {
119           mappingDetails.append("\n");
120         }
121       };
122
123       as.printAlignment(ps);
124
125       if (as.maxscore > max)
126       {
127         max = as.maxscore;
128         maxchain = i;
129         pdbstart = as.seq2start;
130         pdbend = as.seq2end;
131         seqstart = as.seq1start + sequence.getStart() - 1;
132         seqend = as.seq1end + sequence.getEnd() - 1;
133         maxAlignseq = as;
134       }
135
136       mappingDetails.append("\nPDB start/end " + pdbstart + " " + pdbend);
137       mappingDetails.append("\nSEQ start/end " + seqstart + " " + seqend);
138     }
139
140     mainchain = (PDBChain) pdb.chains.elementAt(maxchain);
141
142     mainchain.pdbstart = pdbstart;
143     mainchain.pdbend = pdbend;
144     mainchain.seqstart = seqstart;
145     mainchain.seqend = seqend;
146     mainchain.isVisible = true;
147     mainchain.makeExactMapping(maxAlignseq, sequence);
148     mainchain.transferRESNUMFeatures(sequence, null);
149     seqcanvas.getFeatureRenderer().featuresAdded();
150     this.pdb = pdb;
151     this.prefsize = new Dimension(getWidth(), getHeight());
152
153     //Initialize the matrices to identity
154     for (int i = 0; i < 3; i++)
155     {
156       for (int j = 0; j < 3; j++)
157       {
158         if (i != j)
159         {
160           idmat.addElement(i, j, 0);
161           objmat.addElement(i, j, 0);
162         }
163         else
164         {
165           idmat.addElement(i, j, 1);
166           objmat.addElement(i, j, 1);
167         }
168       }
169     }
170
171     addMouseMotionListener(this);
172     addMouseListener(this);
173
174     addMouseWheelListener(new MouseWheelListener()
175     {
176       public void mouseWheelMoved(MouseWheelEvent e)
177       {
178         if (e.getWheelRotation() > 0)
179         {
180           scale = (float) (scale * 1.1);
181           redrawneeded = true;
182           repaint();
183         }
184
185         else
186         {
187           scale = (float) (scale * 0.9);
188           redrawneeded = true;
189           repaint();
190         }
191       }
192     });
193
194     findCentre();
195     findWidth();
196
197     setupBonds();
198
199     scale = findScale();
200
201     ToolTipManager.sharedInstance().registerComponent(this);
202     ToolTipManager.sharedInstance().setInitialDelay(0);
203     ToolTipManager.sharedInstance().setDismissDelay(10000);
204   }
205
206   Vector visiblebonds;
207   void setupBonds()
208   {
209     seqColoursReady = false;
210     // Sort the bonds by z coord
211     visiblebonds = new Vector();
212
213     for (int ii = 0; ii < pdb.chains.size(); ii++)
214     {
215       if ( ( (PDBChain) pdb.chains.elementAt(ii)).isVisible)
216       {
217         Vector tmp = ( (PDBChain) pdb.chains.elementAt(ii)).bonds;
218
219         for (int i = 0; i < tmp.size(); i++)
220         {
221           visiblebonds.addElement(tmp.elementAt(i));
222         }
223       }
224     }
225
226     updateSeqColours();
227     seqColoursReady = true;
228     redrawneeded = true;
229     repaint();
230   }
231
232   public void findWidth()
233   {
234     float[] max = new float[3];
235     float[] min = new float[3];
236
237     max[0] = (float) - 1e30;
238     max[1] = (float) - 1e30;
239     max[2] = (float) - 1e30;
240
241     min[0] = (float) 1e30;
242     min[1] = (float) 1e30;
243     min[2] = (float) 1e30;
244
245     for (int ii = 0; ii < pdb.chains.size(); ii++)
246     {
247       if ( ( (PDBChain) pdb.chains.elementAt(ii)).isVisible)
248       {
249         Vector bonds = ( (PDBChain) pdb.chains.elementAt(ii)).bonds;
250
251         for (int i = 0; i < bonds.size(); i++)
252         {
253           Bond tmp = (Bond) bonds.elementAt(i);
254
255           if (tmp.start[0] >= max[0])
256           {
257             max[0] = tmp.start[0];
258           }
259
260           if (tmp.start[1] >= max[1])
261           {
262             max[1] = tmp.start[1];
263           }
264
265           if (tmp.start[2] >= max[2])
266           {
267             max[2] = tmp.start[2];
268           }
269
270           if (tmp.start[0] <= min[0])
271           {
272             min[0] = tmp.start[0];
273           }
274
275           if (tmp.start[1] <= min[1])
276           {
277             min[1] = tmp.start[1];
278           }
279
280           if (tmp.start[2] <= min[2])
281           {
282             min[2] = tmp.start[2];
283           }
284
285           if (tmp.end[0] >= max[0])
286           {
287             max[0] = tmp.end[0];
288           }
289
290           if (tmp.end[1] >= max[1])
291           {
292             max[1] = tmp.end[1];
293           }
294
295           if (tmp.end[2] >= max[2])
296           {
297             max[2] = tmp.end[2];
298           }
299
300           if (tmp.end[0] <= min[0])
301           {
302             min[0] = tmp.end[0];
303           }
304
305           if (tmp.end[1] <= min[1])
306           {
307             min[1] = tmp.end[1];
308           }
309
310           if (tmp.end[2] <= min[2])
311           {
312             min[2] = tmp.end[2];
313           }
314         }
315       }
316     }
317     /*
318              System.out.println("xmax " + max[0] + " min " + min[0]);
319              System.out.println("ymax " + max[1] + " min " + min[1]);
320              System.out.println("zmax " + max[2] + " min " + min[2]);*/
321
322     width[0] = (float) Math.abs(max[0] - min[0]);
323     width[1] = (float) Math.abs(max[1] - min[1]);
324     width[2] = (float) Math.abs(max[2] - min[2]);
325
326     maxwidth = width[0];
327
328     if (width[1] > width[0])
329     {
330       maxwidth = width[1];
331     }
332
333     if (width[2] > width[1])
334     {
335       maxwidth = width[2];
336     }
337
338     // System.out.println("Maxwidth = " + maxwidth);
339   }
340
341   public float findScale()
342   {
343     int dim;
344     int width;
345     int height;
346
347     if (getWidth() != 0)
348     {
349       width = getWidth();
350       height = getHeight();
351     }
352     else
353     {
354       width = prefsize.width;
355       height = prefsize.height;
356     }
357
358     if (width < height)
359     {
360       dim = width;
361     }
362     else
363     {
364       dim = height;
365     }
366
367     return (float) (dim / (1.5d * maxwidth));
368   }
369
370   public void findCentre()
371   {
372     float xtot = 0;
373     float ytot = 0;
374     float ztot = 0;
375
376     int bsize = 0;
377
378     //Find centre coordinate
379     for (int ii = 0; ii < pdb.chains.size(); ii++)
380     {
381       if ( ( (PDBChain) pdb.chains.elementAt(ii)).isVisible)
382       {
383         Vector bonds = ( (PDBChain) pdb.chains.elementAt(ii)).bonds;
384
385         bsize += bonds.size();
386
387         for (int i = 0; i < bonds.size(); i++)
388         {
389           xtot = xtot + ( (Bond) bonds.elementAt(i)).start[0] +
390               ( (Bond) bonds.elementAt(i)).end[0];
391
392           ytot = ytot + ( (Bond) bonds.elementAt(i)).start[1] +
393               ( (Bond) bonds.elementAt(i)).end[1];
394
395           ztot = ztot + ( (Bond) bonds.elementAt(i)).start[2] +
396               ( (Bond) bonds.elementAt(i)).end[2];
397         }
398       }
399     }
400
401     centre[0] = xtot / (2 * (float) bsize);
402     centre[1] = ytot / (2 * (float) bsize);
403     centre[2] = ztot / (2 * (float) bsize);
404   }
405
406   public void paintComponent(Graphics g)
407   {
408     super.paintComponent(g);
409
410     if (!seqColoursReady)
411     {
412       g.setColor(Color.black);
413       g.setFont(new Font("Verdana", Font.BOLD, 14));
414       g.drawString("Retrieving PDB data....", 20, getHeight() / 2);
415       return;
416     }
417
418     //Only create the image at the beginning -
419     //this saves much memory usage
420     if ( (img == null)
421         || (prefsize.width != getWidth())
422         || (prefsize.height != getHeight()))
423
424     {
425       prefsize.width = getWidth();
426       prefsize.height = getHeight();
427
428       scale = findScale();
429       img = createImage(prefsize.width, prefsize.height);
430       ig = img.getGraphics();
431       Graphics2D ig2 = (Graphics2D) ig;
432
433       ig2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
434                            RenderingHints.VALUE_ANTIALIAS_ON);
435
436       redrawneeded = true;
437     }
438
439     if (redrawneeded)
440     {
441       drawAll(ig, prefsize.width, prefsize.height);
442       redrawneeded = false;
443     }
444
445     g.drawImage(img, 0, 0, this);
446
447     pdbAction = false;
448   }
449
450   public void drawAll(Graphics g, int width, int height)
451   {
452     g.setColor(backgroundColour);
453     g.fillRect(0, 0, width, height);
454     drawScene(g);
455     drawLabels(g);
456   }
457
458   public void updateSeqColours()
459   {
460     if (pdbAction)
461     {
462       return;
463     }
464
465     // System.out.println("update seq colours");
466     if (bysequence && pdb != null)
467     {
468       for (int ii = 0; ii < pdb.chains.size(); ii++)
469       {
470         colourBySequence( (PDBChain) pdb.chains.elementAt(ii));
471       }
472     }
473
474     redrawneeded = true;
475     repaint();
476   }
477
478   int findTrueIndex(int pos)
479   {
480     // returns the alignment position for a residue
481     int j = sequence.getStart(); // first position in PDB atom coordinate sequence
482     int i = 0;
483
484     while ( (i < sequence.getLength()) && (j <= pos + 1))
485     {
486       if (!jalview.util.Comparison.isGap(sequence.getCharAt(i)))
487       {
488         j++;
489       }
490
491       i++;
492     }
493
494     if (i > 1)
495     {
496       i--;
497     }
498
499     if (j < pos)
500     {
501       return sequence.getEnd() + 1;
502     }
503     else
504     {
505       return i;
506     }
507   }
508
509   // This method has been taken out of PDBChain to allow
510   // Applet and Application specific sequence renderers to be used
511   void colourBySequence(PDBChain chain)
512   {
513     // System.out.println("colour by seq");
514     boolean showFeatures = false;
515
516  //NO LONGER USED SINCE APPJMOL
517 // if (seqcanvas.getViewport().getShowSequenceFeatures())
518     {
519       showFeatures = true;
520       if (fr == null)
521       {
522     //NO LONGER USED SINCE APPJMOL
523 //    fr = new jalview.gui.FeatureRenderer(seqcanvas.getViewport());
524       }
525
526       fr.transferSettings(seqcanvas.getFeatureRenderer());
527     }
528
529     Bond tmp;
530     for (int i = 0; i < chain.bonds.size(); i++)
531     {
532       tmp = (Bond) chain.bonds.elementAt(i);
533
534       if (chain != mainchain)
535       {
536         continue;
537       }
538
539       //if ( (tmp.at1.resNumber >= ( (chain.offset + chain.pdbstart) - 1)) &&
540       //    (tmp.at1.resNumber <= ( (chain.offset + chain.pdbend) - 1)))
541       {
542         int index = findTrueIndex(tmp.at1.alignmentMapping);
543         //sequence.findIndex(tmp.at1.alignmentMapping);
544         if (index != -1)
545         {
546           tmp.startCol = seqcanvas.getSequenceRenderer().
547               getResidueBoxColour(sequence, index);
548
549           if (showFeatures)
550           {
551             tmp.startCol = fr.findFeatureColour(tmp.startCol, sequence, index);
552           }
553
554           if (tmp.startCol == null)
555           {
556             tmp.startCol = Color.white;
557           }
558         }
559       }
560
561       //if ( (tmp.at2.resNumber >= ( (chain.offset + chain.pdbstart) - 1)) &&
562       //    (tmp.at2.resNumber <= ( (chain.pdbend + chain.offset) - 1)))
563       {
564
565         int index = findTrueIndex(tmp.at2.alignmentMapping);
566         //sequence.findIndex( tmp.at2.alignmentMapping );
567         if (index != -1)
568         {
569           tmp.endCol = seqcanvas.getSequenceRenderer().
570               getResidueBoxColour(sequence, index);
571
572           if (showFeatures)
573           {
574             tmp.endCol = fr.findFeatureColour(tmp.endCol, sequence, index);
575           }
576
577           if (tmp.endCol == null)
578           {
579             tmp.endCol = Color.white;
580           }
581         }
582       }
583     }
584   }
585
586   Zsort zsort;
587   public void drawScene(Graphics g)
588   {
589     if (zbuffer)
590     {
591       if (zsort == null)
592       {
593         zsort = new Zsort();
594       }
595
596       zsort.Zsort(visiblebonds);
597     }
598
599     Bond tmpBond = null;
600     for (int i = 0; i < visiblebonds.size(); i++)
601     {
602       tmpBond = (Bond) visiblebonds.elementAt(i);
603
604       xstart = (int) ( ( (tmpBond.start[0] - centre[0]) * scale) +
605                       (getWidth() / 2));
606       ystart = (int) ( ( (tmpBond.start[1] - centre[1]) * scale) +
607                       (getHeight() / 2));
608
609       xend = (int) ( ( (tmpBond.end[0] - centre[0]) * scale) +
610                     (getWidth() / 2));
611       yend = (int) ( ( (tmpBond.end[1] - centre[1]) * scale) +
612                     (getHeight() / 2));
613
614       xmid = (xend + xstart) / 2;
615       ymid = (yend + ystart) / 2;
616       if (depthcue && !bymolecule)
617       {
618         if (tmpBond.start[2] < (centre[2] - (maxwidth / 6)))
619         {
620
621           g.setColor(tmpBond.startCol.darker().darker());
622           drawLine(g, xstart, ystart, xmid, ymid);
623           g.setColor(tmpBond.endCol.darker().darker());
624           drawLine(g, xmid, ymid, xend, yend);
625
626         }
627         else if (tmpBond.start[2] < (centre[2] + (maxwidth / 6)))
628         {
629           g.setColor(tmpBond.startCol.darker());
630           drawLine(g, xstart, ystart, xmid, ymid);
631
632           g.setColor(tmpBond.endCol.darker());
633           drawLine(g, xmid, ymid, xend, yend);
634         }
635         else
636         {
637           g.setColor(tmpBond.startCol);
638           drawLine(g, xstart, ystart, xmid, ymid);
639
640           g.setColor(tmpBond.endCol);
641           drawLine(g, xmid, ymid, xend, yend);
642         }
643       }
644       else if (depthcue && bymolecule)
645       {
646         if (tmpBond.start[2] < (centre[2] - (maxwidth / 6)))
647         {
648           g.setColor(Color.green.darker().darker());
649           drawLine(g, xstart, ystart, xend, yend);
650         }
651         else if (tmpBond.start[2] < (centre[2] + (maxwidth / 6)))
652         {
653           g.setColor(Color.green.darker());
654           drawLine(g, xstart, ystart, xend, yend);
655         }
656         else
657         {
658           g.setColor(Color.green);
659           drawLine(g, xstart, ystart, xend, yend);
660         }
661       }
662       else if (!depthcue && !bymolecule)
663       {
664         g.setColor(tmpBond.startCol);
665         drawLine(g, xstart, ystart, xmid, ymid);
666         g.setColor(tmpBond.endCol);
667         drawLine(g, xmid, ymid, xend, yend);
668       }
669       else
670       {
671         drawLine(g, xstart, ystart, xend, yend);
672       }
673
674       if (highlightBond1 != null && highlightBond1 == tmpBond)
675       {
676         g.setColor(tmpBond.endCol.brighter().brighter().brighter().brighter());
677         drawLine(g, xmid, ymid, xend, yend);
678       }
679
680       if (highlightBond2 != null && highlightBond2 == tmpBond)
681       {
682         g.setColor(tmpBond.startCol.brighter().brighter().brighter().brighter());
683         drawLine(g, xstart, ystart, xmid, ymid);
684       }
685
686     }
687
688   }
689
690   public void drawLine(Graphics g, int x1, int y1, int x2, int y2)
691   {
692     if (!wire)
693     {
694       if ( ( (float) Math.abs(y2 - y1) / (float) Math.abs(x2 - x1)) < 0.5)
695       {
696         g.drawLine(x1, y1, x2, y2);
697         g.drawLine(x1 + 1, y1 + 1, x2 + 1, y2 + 1);
698         g.drawLine(x1, y1 - 1, x2, y2 - 1);
699       }
700       else
701       {
702         g.setColor(g.getColor().brighter());
703         g.drawLine(x1, y1, x2, y2);
704         g.drawLine(x1 + 1, y1, x2 + 1, y2);
705         g.drawLine(x1 - 1, y1, x2 - 1, y2);
706       }
707     }
708     else
709     {
710       g.drawLine(x1, y1, x2, y2);
711     }
712   }
713
714   public Dimension minimumsize()
715   {
716     return prefsize;
717   }
718
719   public Dimension preferredsize()
720   {
721     return prefsize;
722   }
723
724   public void keyPressed(KeyEvent evt)
725   {
726     if (evt.getKeyCode() == KeyEvent.VK_UP)
727     {
728       scale = (float) (scale * 1.1);
729       redrawneeded = true;
730       repaint();
731     }
732     else if (evt.getKeyCode() == KeyEvent.VK_DOWN)
733     {
734       scale = (float) (scale * 0.9);
735       redrawneeded = true;
736       repaint();
737     }
738   }
739
740   public void mousePressed(MouseEvent e)
741   {
742     pdbAction = true;
743     Atom fatom = findAtom(e.getX(), e.getY());
744     if (fatom != null)
745     {
746       fatom.isSelected = !fatom.isSelected;
747
748       redrawneeded = true;
749       repaint();
750       if (foundchain != -1)
751       {
752         PDBChain chain = (PDBChain) pdb.chains.elementAt(foundchain);
753         if (chain == mainchain)
754         {
755           if (fatom.alignmentMapping != -1)
756           {
757             if (highlightRes == null)
758             {
759               highlightRes = new Vector();
760             }
761
762             if (highlightRes.contains(fatom.alignmentMapping + ""))
763             {
764               highlightRes.remove(fatom.alignmentMapping + "");
765             }
766             else
767             {
768               highlightRes.add(fatom.alignmentMapping + "");
769             }
770           }
771         }
772       }
773
774     }
775     mx = e.getX();
776     my = e.getY();
777     omx = mx;
778     omy = my;
779     dragging = false;
780   }
781
782   public void mouseMoved(MouseEvent e)
783   {
784     pdbAction = true;
785     if (highlightBond1 != null)
786     {
787       highlightBond1.at2.isSelected = false;
788       highlightBond2.at1.isSelected = false;
789       highlightBond1 = null;
790       highlightBond2 = null;
791     }
792
793     Atom fatom = findAtom(e.getX(), e.getY());
794
795     PDBChain chain = null;
796     if (foundchain != -1)
797     {
798       chain = (PDBChain) pdb.chains.elementAt(foundchain);
799       if (chain == mainchain)
800       {
801         highlightSeqcanvas(fatom.alignmentMapping);
802       }
803     }
804
805     if (fatom != null)
806     {
807       this.setToolTipText(chain.id + ":" + fatom.resNumber + " " +
808                           fatom.resName);
809     }
810     else
811     {
812       highlightSeqcanvas( -1);
813       this.setToolTipText(null);
814     }
815   }
816
817   void highlightSeqcanvas(int pos)
818   {
819     SearchResults searchResults = new SearchResults();
820     if (highlightRes != null)
821     {
822       for (int i = 0; i < highlightRes.size(); i++)
823       {
824         int a = Integer.parseInt(highlightRes.elementAt(
825             i).toString()) + 1;
826
827         searchResults.addResult(sequence, a, a);
828       }
829     }
830
831     if (pos != -1)
832     {
833       searchResults.addResult(sequence, pos + 1, pos + 1);
834     }
835
836     seqcanvas.highlightSearchResults(searchResults);
837   }
838
839   public void mouseClicked(MouseEvent e)
840   {}
841
842   public void mouseEntered(MouseEvent e)
843   {}
844
845   public void mouseExited(MouseEvent e)
846   {}
847
848   public void mouseDragged(MouseEvent evt)
849   {
850     int x = evt.getX();
851     int y = evt.getY();
852     mx = x;
853     my = y;
854
855     MCMatrix objmat = new MCMatrix(3, 3);
856     objmat.setIdentity();
857
858     if ( (evt.getModifiers() & Event.META_MASK) != 0)
859     {
860       objmat.rotatez( (float) ( (mx - omx)));
861     }
862     else
863     {
864       objmat.rotatex( (float) ( (my - omy)));
865       objmat.rotatey( (float) ( (omx - mx)));
866     }
867
868     //Alter the bonds
869     for (int ii = 0; ii < pdb.chains.size(); ii++)
870     {
871       Vector bonds = ( (PDBChain) pdb.chains.elementAt(ii)).bonds;
872
873       for (int i = 0; i < bonds.size(); i++)
874       {
875         Bond tmpBond = (Bond) bonds.elementAt(i);
876
877         //Translate the bond so the centre is 0,0,0
878         tmpBond.translate( -centre[0], -centre[1], -centre[2]);
879
880         //Now apply the rotation matrix
881         tmpBond.start = objmat.vectorMultiply(tmpBond.start);
882         tmpBond.end = objmat.vectorMultiply(tmpBond.end);
883
884         //Now translate back again
885         tmpBond.translate(centre[0], centre[1], centre[2]);
886       }
887     }
888
889     objmat = null;
890
891     omx = mx;
892     omy = my;
893
894     dragging = true;
895
896     redrawneeded = true;
897
898     repaint();
899   }
900
901   public void mouseReleased(MouseEvent evt)
902   {
903     dragging = false;
904     return;
905   }
906
907   void drawLabels(Graphics g)
908   {
909
910     for (int ii = 0; ii < pdb.chains.size(); ii++)
911     {
912       PDBChain chain = (PDBChain) pdb.chains.elementAt(ii);
913
914       if (chain.isVisible)
915       {
916         Vector bonds = ( (PDBChain) pdb.chains.elementAt(ii)).bonds;
917
918         for (int i = 0; i < bonds.size(); i++)
919         {
920           Bond tmpBond = (Bond) bonds.elementAt(i);
921
922           if (tmpBond.at1.isSelected)
923           {
924             labelAtom(g, tmpBond, 1);
925           }
926
927           if (tmpBond.at2.isSelected)
928           {
929
930             labelAtom(g, tmpBond, 2);
931           }
932         }
933       }
934     }
935   }
936
937   public void labelAtom(Graphics g, Bond b, int n)
938   {
939     g.setFont(font);
940     g.setColor(Color.red);
941     if (n == 1)
942     {
943       int xstart = (int) ( ( (b.start[0] - centre[0]) * scale) +
944                           (getWidth() / 2));
945       int ystart = (int) ( ( (b.start[1] - centre[1]) * scale) +
946                           (getHeight() / 2));
947
948       g.drawString(b.at1.resName + "-" + b.at1.resNumber, xstart, ystart);
949     }
950
951     if (n == 2)
952     {
953       int xstart = (int) ( ( (b.end[0] - centre[0]) * scale) +
954                           (getWidth() / 2));
955       int ystart = (int) ( ( (b.end[1] - centre[1]) * scale) +
956                           (getHeight() / 2));
957
958       g.drawString(b.at2.resName + "-" + b.at2.resNumber, xstart, ystart);
959     }
960   }
961
962   int foundchain = -1;
963   public Atom findAtom(int x, int y)
964   {
965     Atom fatom = null;
966
967     foundchain = -1;
968
969     for (int ii = 0; ii < pdb.chains.size(); ii++)
970     {
971       PDBChain chain = (PDBChain) pdb.chains.elementAt(ii);
972       int truex;
973       Bond tmpBond = null;
974
975       if (chain.isVisible)
976       {
977         Vector bonds = ( (PDBChain) pdb.chains.elementAt(ii)).bonds;
978
979         for (int i = 0; i < bonds.size(); i++)
980         {
981           tmpBond = (Bond) bonds.elementAt(i);
982
983           truex = (int) ( ( (tmpBond.start[0] - centre[0]) * scale) +
984                          (getWidth() / 2));
985
986           if (Math.abs(truex - x) <= 2)
987           {
988             int truey = (int) ( ( (tmpBond.start[1] - centre[1]) * scale) +
989                                (getHeight() / 2));
990
991             if (Math.abs(truey - y) <= 2)
992             {
993               fatom = tmpBond.at1;
994               foundchain = ii;
995               break;
996             }
997           }
998         }
999
1000         // Still here? Maybe its the last bond
1001
1002         truex = (int) ( ( (tmpBond.end[0] - centre[0]) * scale) +
1003                        (getWidth() / 2));
1004
1005         if (Math.abs(truex - x) <= 2)
1006         {
1007           int truey = (int) ( ( (tmpBond.end[1] - centre[1]) * scale) +
1008                              (getHeight() / 2));
1009
1010           if (Math.abs(truey - y) <= 2)
1011           {
1012             fatom = tmpBond.at2;
1013             foundchain = ii;
1014             break;
1015           }
1016         }
1017
1018       }
1019
1020       if (fatom != null) //)&& chain.ds != null)
1021       {
1022         chain = (PDBChain) pdb.chains.elementAt(foundchain);
1023       }
1024     }
1025
1026     return fatom;
1027   }
1028
1029   Bond highlightBond1, highlightBond2;
1030   public void highlightRes(int ii)
1031   {
1032     if (!seqColoursReady)
1033     {
1034       return;
1035     }
1036
1037     if (highlightRes != null
1038         && highlightRes.contains( (ii - 1) + ""))
1039     {
1040       return;
1041     }
1042
1043     int index = -1;
1044     Bond tmpBond;
1045     for (index = 0; index < mainchain.bonds.size(); index++)
1046     {
1047       tmpBond = (Bond) mainchain.bonds.elementAt(index);
1048       if (tmpBond.at1.alignmentMapping == ii - 1)
1049       {
1050         if (highlightBond1 != null)
1051         {
1052           highlightBond1.at2.isSelected = false;
1053         }
1054
1055         if (highlightBond2 != null)
1056         {
1057           highlightBond2.at1.isSelected = false;
1058         }
1059
1060         highlightBond1 = null;
1061         highlightBond2 = null;
1062
1063         if (index > 0)
1064         {
1065           highlightBond1 = (Bond) mainchain.bonds.elementAt(index - 1);
1066           highlightBond1.at2.isSelected = true;
1067         }
1068
1069         if (index != mainchain.bonds.size())
1070         {
1071           highlightBond2 = (Bond) mainchain.bonds.elementAt(index);
1072           highlightBond2.at1.isSelected = true;
1073         }
1074
1075         break;
1076       }
1077     }
1078
1079     redrawneeded = true;
1080     repaint();
1081   }
1082
1083   public void setAllchainsVisible(boolean b)
1084   {
1085     for (int ii = 0; ii < pdb.chains.size(); ii++)
1086     {
1087       PDBChain chain = (PDBChain) pdb.chains.elementAt(ii);
1088       chain.isVisible = b;
1089     }
1090     mainchain.isVisible = true;
1091     findCentre();
1092     setupBonds();
1093   }
1094 }