Remove system.out
[jalview.git] / src / MCview / AppletPDBCanvas.java
1 /*\r
2 * Jalview - A Sequence Alignment Editor and Viewer\r
3 * Copyright (C) 2005 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 MCview;\r
20 \r
21 import jalview.analysis.AlignSeq;\r
22 \r
23 import jalview.datamodel.*;\r
24 \r
25 // JBPNote TODO: This class is quite noisy - needs proper log.info/log.debug\r
26 import java.awt.*;\r
27 import java.awt.event.*;\r
28 \r
29 import java.io.*;\r
30 \r
31 import java.util.*;\r
32 \r
33 \r
34 \r
35 public class AppletPDBCanvas extends Panel implements MouseListener, MouseMotionListener\r
36 {\r
37 \r
38   MCMatrix idmat = new MCMatrix(3, 3);\r
39     MCMatrix objmat = new MCMatrix(3, 3);\r
40     boolean redrawneeded = true;\r
41     int omx = 0;\r
42     int mx = 0;\r
43     int omy = 0;\r
44     int my = 0;\r
45     public PDBfile pdb;\r
46     int bsize;\r
47     Image img;\r
48     Graphics ig;\r
49     Dimension prefsize;\r
50     float[] centre = new float[3];\r
51     float[] width = new float[3];\r
52     float maxwidth;\r
53     float scale;\r
54     String inStr;\r
55     String inType;\r
56     boolean bysequence = true;\r
57     boolean depthcue = true;\r
58     boolean wire = false;\r
59     boolean bymolecule = false;\r
60     boolean zbuffer = true;\r
61     boolean dragging;\r
62     int xstart;\r
63     int xend;\r
64     int ystart;\r
65     int yend;\r
66     int xmid;\r
67     int ymid;\r
68     Font font = new Font("Helvetica", Font.PLAIN, 10);\r
69     jalview.appletgui.SequenceRenderer sr;\r
70     jalview.appletgui.FeatureRenderer  fr;\r
71     jalview.appletgui.SeqCanvas seqcanvas;\r
72     public Sequence sequence;\r
73     final StringBuffer mappingDetails = new StringBuffer();\r
74     String appletToolTip = null;\r
75     int toolx, tooly;\r
76     PDBChain mainchain;\r
77 \r
78     public AppletPDBCanvas(jalview.appletgui.SeqCanvas seqcanvas, Sequence seq)\r
79     {\r
80       this.seqcanvas = seqcanvas;\r
81       this.sequence = seq;\r
82       sr = seqcanvas.getSequenceRenderer();\r
83       fr = seqcanvas.getFeatureRenderer();\r
84 \r
85       seqcanvas.setPDBCanvas(this);\r
86       addKeyListener(new KeyAdapter()\r
87       {\r
88 \r
89         public void keyPressed(KeyEvent evt)\r
90         {\r
91           doKeyPressed(evt);\r
92         }\r
93       });\r
94     }\r
95 \r
96     Bond highlightBond1, highlightBond2;\r
97     public void highlightRes(int ii)\r
98    {\r
99      highlightBond1 = null;\r
100      highlightBond2 = null;\r
101 \r
102      int index = ii - mainchain.seqstart;\r
103 \r
104      System.out.println(ii+" "+mainchain.seqstart+" "+index);\r
105 \r
106      if(index <0 )\r
107        return;\r
108 \r
109      if(index<=mainchain.bonds.size())\r
110      {\r
111        if(index>0)\r
112        {\r
113          highlightBond1 = (Bond) mainchain.bonds.elementAt(index - 1);\r
114        }\r
115 \r
116        if(index!=mainchain.bonds.size())\r
117          highlightBond2 = (Bond) mainchain.bonds.elementAt(index);\r
118      }\r
119 \r
120      redrawneeded = true;\r
121      repaint();\r
122   }\r
123 \r
124 \r
125   public void setPDBFile(PDBfile pdb)\r
126    {\r
127         this.sr = sr;\r
128         this.fr = fr;\r
129         int max = -10;\r
130         int maxchain = -1;\r
131         int pdbstart = 0;\r
132         int pdbend = 0;\r
133         int seqstart = 0;\r
134         int seqend = 0;\r
135 \r
136         for (int i = 0; i < pdb.chains.size(); i++)\r
137         {\r
138 \r
139           mappingDetails.append("\n\nPDB Sequence is :\nSequence = " + ((PDBChain) pdb.chains.elementAt(i)).sequence.getSequence());\r
140           mappingDetails.append("\nNo of residues = " + ((PDBChain) pdb.chains.elementAt(i)).residues.size()+"\n\n");\r
141 \r
142             // Now lets compare the sequences to get\r
143             // the start and end points.\r
144             // Align the sequence to the pdb\r
145             AlignSeq as = new AlignSeq(sequence,\r
146                     ((PDBChain) pdb.chains.elementAt(i)).sequence, "pep");\r
147             as.calcScoreMatrix();\r
148             as.traceAlignment();\r
149             PrintStream  ps = new PrintStream(System.out)\r
150            {\r
151               public void print(String x) {\r
152                    mappingDetails.append(x);\r
153                }\r
154                public void println()\r
155                {\r
156                  mappingDetails.append("\n");\r
157                }\r
158             };\r
159 \r
160             as.printAlignment(ps);\r
161 \r
162             if (as.maxscore > max) {\r
163                 max = as.maxscore;\r
164                 maxchain = i;\r
165 \r
166                 pdbstart = as.seq2start;\r
167                 pdbend = as.seq2end;\r
168                 seqstart = as.seq1start + sequence.getStart()-1;\r
169                 seqend = as.seq1end + sequence.getEnd()-1;\r
170             }\r
171 \r
172             mappingDetails.append("\nPDB start/end "  + pdbstart + " " + pdbend);\r
173             mappingDetails.append("\nSEQ start/end "+ seqstart + " " + seqend);\r
174         }\r
175 \r
176         mainchain = (PDBChain) pdb.chains.elementAt(maxchain);\r
177 \r
178         mainchain.pdbstart = pdbstart;\r
179         mainchain.pdbend = pdbend;\r
180         mainchain.seqstart = seqstart;\r
181         mainchain.seqend = seqend;\r
182         mainchain.isVisible = true;\r
183         mainchain.sequence = sequence;\r
184 \r
185         this.pdb = pdb;\r
186         this.prefsize = new Dimension(getSize().width, getSize().height);\r
187 \r
188         //Initialize the matrices to identity\r
189         for (int i = 0; i < 3; i++) {\r
190             for (int j = 0; j < 3; j++) {\r
191                 if (i != j) {\r
192                     idmat.addElement(i, j, 0);\r
193                     objmat.addElement(i, j, 0);\r
194                 } else {\r
195                     idmat.addElement(i, j, 1);\r
196                     objmat.addElement(i, j, 1);\r
197                 }\r
198             }\r
199         }\r
200 \r
201         addMouseMotionListener(this);\r
202         addMouseListener(this);\r
203 \r
204       /*\r
205        SequenceGroup sg = new SequenceGroup("PDB",\r
206                                             null, true,true,false,\r
207                                             sequence.findIndex(seqstart-1),\r
208                                             sequence.findIndex(seqend-1));\r
209        sg.addSequence(sequence, false);\r
210        sg.setOutlineColour(Color.black);\r
211        seqcanvas.getViewport().getAlignment().addGroup(sg);\r
212        */\r
213 \r
214         findCentre();\r
215         findWidth();\r
216 \r
217         scale = findScale();\r
218 \r
219         updateSeqColours();\r
220     }\r
221 \r
222     public void deleteBonds() {\r
223         scale = 0;\r
224         maxwidth = 0;\r
225 \r
226         width[0] = 0;\r
227         width[1] = 0;\r
228         width[2] = 0;\r
229 \r
230         centre[0] = 0;\r
231         centre[1] = 0;\r
232         centre[2] = 0;\r
233 \r
234         for (int i = 0; i < pdb.chains.size(); i++) {\r
235             ((PDBChain) pdb.chains.elementAt(i)).bonds = null;\r
236         }\r
237     }\r
238 \r
239     public void findWidth() {\r
240         float[] max = new float[3];\r
241         float[] min = new float[3];\r
242 \r
243         max[0] = (float) -1e30;\r
244         max[1] = (float) -1e30;\r
245         max[2] = (float) -1e30;\r
246 \r
247         min[0] = (float) 1e30;\r
248         min[1] = (float) 1e30;\r
249         min[2] = (float) 1e30;\r
250 \r
251         for (int ii = 0; ii < pdb.chains.size(); ii++) {\r
252             if (((PDBChain) pdb.chains.elementAt(ii)).isVisible) {\r
253                 Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;\r
254 \r
255                 for (int i = 0; i < bonds.size(); i++) {\r
256                     Bond tmp = (Bond) bonds.elementAt(i);\r
257 \r
258                     if (tmp.start[0] >= max[0]) {\r
259                         max[0] = tmp.start[0];\r
260                     }\r
261 \r
262                     if (tmp.start[1] >= max[1]) {\r
263                         max[1] = tmp.start[1];\r
264                     }\r
265 \r
266                     if (tmp.start[2] >= max[2]) {\r
267                         max[2] = tmp.start[2];\r
268                     }\r
269 \r
270                     if (tmp.start[0] <= min[0]) {\r
271                         min[0] = tmp.start[0];\r
272                     }\r
273 \r
274                     if (tmp.start[1] <= min[1]) {\r
275                         min[1] = tmp.start[1];\r
276                     }\r
277 \r
278                     if (tmp.start[2] <= min[2]) {\r
279                         min[2] = tmp.start[2];\r
280                     }\r
281 \r
282                     if (tmp.end[0] >= max[0]) {\r
283                         max[0] = tmp.end[0];\r
284                     }\r
285 \r
286                     if (tmp.end[1] >= max[1]) {\r
287                         max[1] = tmp.end[1];\r
288                     }\r
289 \r
290                     if (tmp.end[2] >= max[2]) {\r
291                         max[2] = tmp.end[2];\r
292                     }\r
293 \r
294                     if (tmp.end[0] <= min[0]) {\r
295                         min[0] = tmp.end[0];\r
296                     }\r
297 \r
298                     if (tmp.end[1] <= min[1]) {\r
299                         min[1] = tmp.end[1];\r
300                     }\r
301 \r
302                     if (tmp.end[2] <= min[2]) {\r
303                         min[2] = tmp.end[2];\r
304                     }\r
305                 }\r
306             }\r
307         }\r
308 \r
309         width[0] = (float) Math.abs(max[0] - min[0]);\r
310         width[1] = (float) Math.abs(max[1] - min[1]);\r
311         width[2] = (float) Math.abs(max[2] - min[2]);\r
312 \r
313         maxwidth = width[0];\r
314 \r
315         if (width[1] > width[0]) {\r
316             maxwidth = width[1];\r
317         }\r
318 \r
319         if (width[2] > width[1]) {\r
320             maxwidth = width[2];\r
321         }\r
322 \r
323        // System.out.println("Maxwidth = " + maxwidth);\r
324     }\r
325 \r
326     public float findScale() {\r
327         int dim;\r
328         int width;\r
329         int height;\r
330 \r
331         if (getSize().width != 0) {\r
332             width = getSize().width;\r
333             height = getSize().height;\r
334         } else {\r
335             width = prefsize.width;\r
336             height = prefsize.height;\r
337         }\r
338 \r
339         if (width < height) {\r
340             dim = width;\r
341         } else {\r
342             dim = height;\r
343         }\r
344 \r
345         return (float) (dim / (1.5d * maxwidth));\r
346     }\r
347 \r
348     public void findCentre() {\r
349         float xtot = 0;\r
350         float ytot = 0;\r
351         float ztot = 0;\r
352 \r
353         int bsize = 0;\r
354 \r
355         //Find centre coordinate\r
356         for (int ii = 0; ii < pdb.chains.size(); ii++) {\r
357             if (((PDBChain) pdb.chains.elementAt(ii)).isVisible) {\r
358                 Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;\r
359 \r
360                 bsize += bonds.size();\r
361 \r
362                 for (int i = 0; i < bonds.size(); i++) {\r
363                     xtot = xtot + ((Bond) bonds.elementAt(i)).start[0] +\r
364                         ((Bond) bonds.elementAt(i)).end[0];\r
365 \r
366                     ytot = ytot + ((Bond) bonds.elementAt(i)).start[1] +\r
367                         ((Bond) bonds.elementAt(i)).end[1];\r
368 \r
369                     ztot = ztot + ((Bond) bonds.elementAt(i)).start[2] +\r
370                         ((Bond) bonds.elementAt(i)).end[2];\r
371                 }\r
372             }\r
373         }\r
374 \r
375         centre[0] = xtot / (2 * (float) bsize);\r
376         centre[1] = ytot / (2 * (float) bsize);\r
377         centre[2] = ztot / (2 * (float) bsize);\r
378     }\r
379 \r
380     public void paint(Graphics g)\r
381     {\r
382 \r
383       if(pdb==null)\r
384       {\r
385         g.setColor(Color.black);\r
386         g.setFont(new Font("Verdana", Font.BOLD, 14));\r
387         g.drawString("Error Parsing Pasted PDB data!!", 50, getSize().height/2);\r
388         return;\r
389       }\r
390 \r
391 \r
392         //Only create the image at the beginning -\r
393         //this saves much memory usage\r
394         if ((img == null) || (prefsize.width != getSize().width) ||\r
395                 (prefsize.height != getSize().height)) {\r
396 \r
397          try{     prefsize.width = getSize().width;\r
398            prefsize.height = getSize().height;\r
399 \r
400            scale = findScale();\r
401            img = createImage(prefsize.width, prefsize.height);\r
402            ig = img.getGraphics();\r
403 \r
404            redrawneeded = true;\r
405          }catch(Exception ex)\r
406          {\r
407            ex.printStackTrace();\r
408            System.out.println(getSize());\r
409          }\r
410         }\r
411 \r
412 \r
413         if (redrawneeded)\r
414         {\r
415           drawAll(ig, prefsize.width, prefsize.height);\r
416           redrawneeded = false;\r
417         }\r
418         if(appletToolTip!=null)\r
419         {\r
420           ig.setColor(Color.red);\r
421           ig.drawString(appletToolTip, toolx, tooly);\r
422         }\r
423 \r
424         g.drawImage(img, 0, 0, this);\r
425 \r
426 \r
427     }\r
428 \r
429     public void drawAll(Graphics g, int width, int height)\r
430     {\r
431       g.setColor(Color.black);\r
432       g.fillRect(0, 0, width, height);\r
433       drawScene(g);\r
434       drawLabels(g);\r
435     }\r
436 \r
437 \r
438     public void updateSeqColours()\r
439     {\r
440       if(bysequence && pdb!=null)\r
441       {\r
442         for (int ii = 0; ii < pdb.chains.size(); ii++)\r
443         {\r
444           colourBySequence((PDBChain) pdb.chains.elementAt(ii));\r
445         }\r
446       }\r
447 \r
448       redrawneeded=true;\r
449       repaint();\r
450     }\r
451 \r
452     // This method has been taken out of PDBChain to allow\r
453     // Applet and Application specific sequence renderers to be used\r
454     void colourBySequence(PDBChain chain)\r
455     {\r
456       for (int i = 0; i < chain.bonds.size(); i++)\r
457       {\r
458         Bond tmp = (Bond) chain.bonds.elementAt(i);\r
459         if ( (tmp.at1.resNumber >= ( (chain.offset + chain.pdbstart) - 1)) &&\r
460             (tmp.at1.resNumber <= ( (chain.offset + chain.pdbend) - 1)))\r
461         {\r
462 \r
463           int pos = chain.seqstart +\r
464               (tmp.at1.resNumber - chain.pdbstart - chain.offset);\r
465 \r
466           int index = sequence.findIndex(pos);\r
467 \r
468           if(jalview.util.Comparison.isGap((sequence.getCharAt(index))))\r
469            {\r
470              index--;\r
471            }\r
472 \r
473            tmp.startCol = sr.findSequenceColour(sequence, index);\r
474 \r
475         //  tmp.startCol = fr.findFeatureColour(tmp.startCol, sequence, index);\r
476 \r
477         }\r
478         else\r
479         {\r
480           tmp.startCol = Color.gray;\r
481         }\r
482 \r
483         if ( (tmp.at2.resNumber >= ( (chain.offset + chain.pdbstart) - 1)) &&\r
484             (tmp.at2.resNumber <= ( (chain.pdbend + chain.offset) - 1)))\r
485         {\r
486           int pos = chain.seqstart +\r
487               (tmp.at2.resNumber - chain.pdbstart - chain.offset);\r
488           int index = sequence.findIndex(pos);\r
489           if (jalview.util.Comparison.isGap( (sequence.getCharAt(index))))\r
490           {\r
491             index--;\r
492           }\r
493 \r
494 \r
495             tmp.endCol = sr.findSequenceColour(sequence, index);\r
496       //    tmp.endCol = fr.findFeatureColour(tmp.endCol, sequence, index);\r
497         }\r
498         else\r
499         {\r
500           tmp.endCol = Color.gray;\r
501         }\r
502       }\r
503     }\r
504 \r
505 \r
506     public void drawScene(Graphics g) {\r
507         // Sort the bonds by z coord\r
508         Vector bonds = new Vector();\r
509 \r
510         for (int ii = 0; ii < pdb.chains.size(); ii++)\r
511         {\r
512           if ( ( (PDBChain) pdb.chains.elementAt(ii)).isVisible)\r
513           {\r
514             Vector tmp = ( (PDBChain) pdb.chains.elementAt(ii)).bonds;\r
515 \r
516             for (int i = 0; i < tmp.size(); i++)\r
517             {\r
518                 bonds.addElement(tmp.elementAt(i));\r
519             }\r
520           }\r
521         }\r
522 \r
523         if (zbuffer) {\r
524             Zsort.Zsort(bonds);\r
525         }\r
526 \r
527         for (int i = 0; i < bonds.size(); i++) {\r
528             Bond tmpBond = (Bond) bonds.elementAt(i);\r
529 \r
530 \r
531             xstart = (int) (((tmpBond.start[0] - centre[0]) * scale) +\r
532                 (getSize().width / 2));\r
533             ystart = (int) (((tmpBond.start[1] - centre[1]) * scale) +\r
534                 (getSize().height / 2));\r
535 \r
536             xend = (int) (((tmpBond.end[0] - centre[0]) * scale) +\r
537                 (getSize().width / 2));\r
538             yend = (int) (((tmpBond.end[1] - centre[1]) * scale) +\r
539                 (getSize().height / 2));\r
540 \r
541             xmid = (xend + xstart) / 2;\r
542             ymid = (yend + ystart) / 2;\r
543 \r
544             if (depthcue && !bymolecule)\r
545             {\r
546                 if (tmpBond.start[2] < (centre[2] - (maxwidth / 6))) {\r
547                     g.setColor(tmpBond.startCol.darker().darker());\r
548                     drawLine(g, xstart, ystart, xmid, ymid);\r
549 \r
550                     g.setColor(tmpBond.endCol.darker().darker());\r
551                     drawLine(g, xmid, ymid, xend, yend);\r
552                 } else if (tmpBond.start[2] < (centre[2] + (maxwidth / 6))) {\r
553                     g.setColor(tmpBond.startCol.darker());\r
554                     drawLine(g, xstart, ystart, xmid, ymid);\r
555 \r
556                     g.setColor(tmpBond.endCol.darker());\r
557                     drawLine(g, xmid, ymid, xend, yend);\r
558                 } else {\r
559                     g.setColor(tmpBond.startCol);\r
560                     drawLine(g, xstart, ystart, xmid, ymid);\r
561 \r
562                     g.setColor(tmpBond.endCol);\r
563                     drawLine(g, xmid, ymid, xend, yend);\r
564                 }\r
565             } else if (depthcue && bymolecule) {\r
566                 if (tmpBond.start[2] < (centre[2] - (maxwidth / 6))) {\r
567                     g.setColor(Color.green.darker().darker());\r
568                     drawLine(g, xstart, ystart, xend, yend);\r
569                 } else if (tmpBond.start[2] < (centre[2] + (maxwidth / 6))) {\r
570                     g.setColor(Color.green.darker());\r
571                     drawLine(g, xstart, ystart, xend, yend);\r
572                 } else {\r
573                     g.setColor(Color.green);\r
574                     drawLine(g, xstart, ystart, xend, yend);\r
575                 }\r
576             } else if (!depthcue && !bymolecule) {\r
577                 g.setColor(tmpBond.startCol);\r
578                 drawLine(g, xstart, ystart, xmid, ymid);\r
579                 g.setColor(tmpBond.endCol);\r
580                 drawLine(g, xmid, ymid, xend, yend);\r
581             } else {\r
582                 drawLine(g, xstart, ystart, xend, yend);\r
583             }\r
584 \r
585             if(highlightBond1!=null && highlightBond1==tmpBond)\r
586             {\r
587               g.setColor(Color.white);\r
588               drawLine(g, xmid, ymid, xend, yend);\r
589             }\r
590 \r
591             if(highlightBond2!=null && highlightBond2==tmpBond)\r
592             {\r
593               g.setColor(Color.white);\r
594               drawLine(g, xstart, ystart, xmid, ymid);\r
595             }\r
596 \r
597         }\r
598     }\r
599 \r
600     public void drawLine(Graphics g, int x1, int y1, int x2, int y2) {\r
601         if (!wire) {\r
602             if (((float) Math.abs(y2 - y1) / (float) Math.abs(x2 - x1)) < 0.5) {\r
603                 g.drawLine(x1, y1, x2, y2);\r
604                 g.drawLine(x1 + 1, y1 + 1, x2 + 1, y2 + 1);\r
605                 g.drawLine(x1, y1 - 1, x2, y2 - 1);\r
606             } else {\r
607                 g.setColor(g.getColor().brighter());\r
608                 g.drawLine(x1, y1, x2, y2);\r
609                 g.drawLine(x1 + 1, y1, x2 + 1, y2);\r
610                 g.drawLine(x1 - 1, y1, x2 - 1, y2);\r
611             }\r
612         } else {\r
613             g.drawLine(x1, y1, x2, y2);\r
614         }\r
615     }\r
616 \r
617     public Dimension minimumsize() {\r
618         return prefsize;\r
619     }\r
620 \r
621     public Dimension preferredsize() {\r
622         return prefsize;\r
623     }\r
624 \r
625     public void doKeyPressed(KeyEvent evt)\r
626     {\r
627       if (evt.getKeyCode() == KeyEvent.VK_UP)\r
628       {\r
629         scale = (float) (scale * 1.1);\r
630         redrawneeded = true;\r
631         repaint();\r
632       }\r
633       else if (evt.getKeyCode() == KeyEvent.VK_DOWN)\r
634       {\r
635         scale = (float) (scale * 0.9);\r
636         redrawneeded = true;\r
637         repaint();\r
638       }\r
639     }\r
640 \r
641     public void mousePressed(MouseEvent e) {\r
642         Atom fatom = findAtom(e.getX(), e.getY());\r
643         if(fatom!=null)\r
644         {\r
645           fatom.isSelected = !fatom.isSelected;\r
646           redrawneeded = true;\r
647           repaint();\r
648         }\r
649         mx = e.getX();\r
650         my = e.getY();\r
651         omx = mx;\r
652         omy = my;\r
653         dragging = false;\r
654     }\r
655 \r
656     public void mouseMoved(MouseEvent e) {\r
657 \r
658         Atom fatom = findAtom(e.getX(), e.getY());\r
659 \r
660         PDBChain chain = null;\r
661         if(foundchain!=-1)\r
662         {\r
663           chain = (PDBChain) pdb.chains.elementAt(foundchain);\r
664           if(chain == mainchain)\r
665           {\r
666             int pos = chain.seqstart +\r
667                 (fatom.resNumber - chain.pdbstart - chain.offset) + 1;\r
668 \r
669             int index = seqcanvas.getViewport().getAlignment().findIndex(\r
670                 sequence);\r
671 \r
672             seqcanvas.highlightSearchResults(new int[]\r
673                                              {index, pos, pos});\r
674           }\r
675         }\r
676         else\r
677           seqcanvas.highlightSearchResults(null);\r
678 \r
679         if (fatom != null) {\r
680             toolx = e.getX();\r
681             tooly = e.getY();\r
682 \r
683             appletToolTip = chain.id+":"+ fatom.resNumber+" "+ fatom.resName;\r
684             redrawneeded = true;\r
685             repaint();\r
686         } else {\r
687             appletToolTip = null;\r
688             redrawneeded = true;\r
689             repaint();\r
690         }\r
691     }\r
692 \r
693     public void mouseClicked(MouseEvent e) {\r
694     }\r
695 \r
696     public void mouseEntered(MouseEvent e) {\r
697     }\r
698 \r
699     public void mouseExited(MouseEvent e) {\r
700     }\r
701 \r
702     public void mouseDragged(MouseEvent evt) {\r
703         int x = evt.getX();\r
704         int y = evt.getY();\r
705         mx = x;\r
706         my = y;\r
707 \r
708         MCMatrix objmat = new MCMatrix(3, 3);\r
709         objmat.setIdentity();\r
710 \r
711         if ((evt.getModifiers() & Event.META_MASK) != 0) {\r
712             objmat.rotatez((float) ((mx - omx)));\r
713         } else {\r
714             objmat.rotatex((float) ((my - omy)));\r
715             objmat.rotatey((float) ((omx - mx)));\r
716         }\r
717 \r
718         //Alter the bonds\r
719         for (int ii = 0; ii < pdb.chains.size(); ii++) {\r
720             Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;\r
721 \r
722             for (int i = 0; i < bonds.size(); i++) {\r
723                 Bond tmpBond = (Bond) bonds.elementAt(i);\r
724 \r
725                 //Translate the bond so the centre is 0,0,0\r
726                 tmpBond.translate(-centre[0], -centre[1], -centre[2]);\r
727 \r
728                 //Now apply the rotation matrix\r
729                 tmpBond.start = objmat.vectorMultiply(tmpBond.start);\r
730                 tmpBond.end = objmat.vectorMultiply(tmpBond.end);\r
731 \r
732                 //Now translate back again\r
733                 tmpBond.translate(centre[0], centre[1], centre[2]);\r
734             }\r
735         }\r
736 \r
737         objmat = null;\r
738 \r
739         omx = mx;\r
740         omy = my;\r
741 \r
742         dragging = true;\r
743 \r
744         redrawneeded = true;\r
745 \r
746         repaint();\r
747     }\r
748 \r
749     public void mouseReleased(MouseEvent evt) {\r
750         dragging = false;\r
751         return;\r
752     }\r
753 \r
754     void drawLabels(Graphics g) {\r
755 \r
756         for (int ii = 0; ii < pdb.chains.size(); ii++)\r
757         {\r
758             PDBChain chain = (PDBChain) pdb.chains.elementAt(ii);\r
759 \r
760             if (chain.isVisible)\r
761             {\r
762                 Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;\r
763 \r
764                 for (int i = 0; i < bonds.size(); i++)\r
765                 {\r
766                     Bond tmpBond = (Bond) bonds.elementAt(i);\r
767 \r
768                     if (tmpBond.at1.isSelected)\r
769                     {\r
770                         labelAtom(g, tmpBond, 1);\r
771                     }\r
772 \r
773                     if (tmpBond.at2.isSelected)\r
774                     {\r
775 \r
776                         labelAtom(g, tmpBond, 2);\r
777                     }\r
778                 }\r
779             }\r
780         }\r
781     }\r
782 \r
783     public void labelAtom(Graphics g, Bond b, int n) {\r
784         g.setFont(font);\r
785 \r
786         if (n == 1) {\r
787             int xstart = (int) (((b.start[0] - centre[0]) * scale) +\r
788                 (getSize().width / 2));\r
789             int ystart = (int) (((b.start[1] - centre[1]) * scale) +\r
790                 (getSize().height / 2));\r
791 \r
792             g.setColor(Color.red);\r
793             g.drawString(b.at1.resName + "-" + b.at1.resNumber, xstart, ystart);\r
794         }\r
795 \r
796         if (n == 2) {\r
797             int xstart = (int) (((b.end[0] - centre[0]) * scale) +\r
798                 (getSize().width / 2));\r
799             int ystart = (int) (((b.end[1] - centre[1]) * scale) +\r
800                 (getSize().height / 2));\r
801 \r
802             g.setColor(Color.red);\r
803             g.drawString(b.at2.resName + "-" + b.at2.resNumber, xstart, ystart);\r
804         }\r
805     }\r
806 \r
807     int foundchain = -1;\r
808     public Atom findAtom(int x, int y) {\r
809         Atom fatom = null;\r
810 \r
811         foundchain = -1;\r
812 \r
813         for (int ii = 0; ii < pdb.chains.size(); ii++) {\r
814             PDBChain chain = (PDBChain) pdb.chains.elementAt(ii);\r
815 \r
816             if (chain.isVisible) {\r
817                 Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;\r
818 \r
819                 for (int i = 0; i < bonds.size(); i++) {\r
820                     Bond tmpBond = (Bond) bonds.elementAt(i);\r
821 \r
822                     int truex = (int) (((tmpBond.start[0] - centre[0]) * scale) +\r
823                         (getSize().width / 2));\r
824 \r
825                     if (Math.abs(truex - x) <= 2) {\r
826                         int truey = (int) (((tmpBond.start[1] - centre[1]) * scale) +\r
827                             (getSize().height / 2));\r
828 \r
829                         if (Math.abs(truey - y) <= 2)\r
830                         {\r
831                             fatom = tmpBond.at1;\r
832                             foundchain = ii;\r
833                             break;\r
834                         }\r
835                     }\r
836                 }\r
837             }\r
838 \r
839             if (fatom != null) //)&& chain.ds != null)\r
840              {\r
841                 chain = (PDBChain) pdb.chains.elementAt(foundchain);\r
842             }\r
843         }\r
844 \r
845         return fatom;\r
846     }\r
847 \r
848     public void update(Graphics g)\r
849     {\r
850       paint(g);\r
851     }\r
852 \r
853     public void setAllchainsVisible(boolean b)\r
854     {\r
855       for (int ii = 0; ii < pdb.chains.size(); ii++)\r
856       {\r
857         PDBChain chain = (PDBChain) pdb.chains.elementAt(ii);\r
858         chain.isVisible = b;\r
859       }\r
860       mainchain.isVisible = true;\r
861       findCentre();\r
862     }\r
863 \r
864 }\r