34f72eb6a428916f91428b8c4a8b7ba338f37086
[jalview.git] / examples / javascript / jalview.js
1 /**
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8)
3  * Copyright (C) 2012 J Procter, AM Waterhouse, LM Lui, J Engelhardt, G Barton, M Clamp, S Searle
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  */
18 // default console to report messages
19 var _console = document.getElementById("stdout");
20 var _jvapps = new Array();
21 // jvjmols is a list associating a jmol id to { modelstofiles }
22 var _jvjmols = new Hashtable();
23 // array of model names used to lookup index in Jmol
24 var _modeltofiles = new Array();
25 // counter for jmol structures
26 var mnum = 1;
27
28 function setConsole(console) {
29         _console = console;
30 }
31
32 function getDestinationFrms(source, frames) {
33         var frms = new Array();
34         var frid = "";
35         for (frm in frames) {
36                 try {
37                         frid = (source!=null) && (("" + source.getSequenceSetId()) == ("" + frames[frm].currentAlignFrame
38                                         .getSequenceSetId()));
39                 } catch (q) {
40                 };
41                 
42                 if (!frames[frm].equals(source) && !frid
43                                 && !frames[frm].currentAlignFrame.equals(source)) {
44                         frms[frms.length] = frames[frm];
45                 }
46         }
47         return frms;
48 }
49
50 function mouseover(list1, list2, list3, list4) {
51         // list1 = new Object(list1);
52         var list = new Array(("" + list1), ("" + list2), ("" + list3), ("" + list4));
53         var msg = "Mouse over :\n" + "AlignFrame obj: " + list1 + " Seq : "
54                         + list[1] + "\nPos: " + list[2] + "(" + list[3] + ")\n";
55
56         var flist = getDestinationFrms(list1, _jvapps);
57         if (_console) {
58                 _console.value = msg + "\n";
59         }
60
61         for (follower in flist) {
62                 if (_console) {
63                         _console.value += "Sending to " + flist[follower] + "\n";
64                 }
65                 flist[follower].highlight(list[1], list[2], "true");
66         }
67         return true;
68 }
69
70 function sellist(list1, list2, list3, list4) {
71         // list1 = new Object(list1);
72         var list = new Array(("" + list1), ("" + list2), ("" + list3), ("" + list4));
73         var msg = "Selection:\n" + "AlignFrame obj: " + list[0] + " id : "
74                         + list[1] + "\nSeqs " + list[2] + "\nColumns " + list[3] + "\n";
75         var flist = getDestinationFrms(list1, _jvapps);
76         if (_console) {
77                 _console.value = msg + "\n";
78         }
79         
80         for (follower in flist) {
81                 if (_console) {
82                         _console.value += "Sending to " + flist[follower] + "\n";
83                 }
84                 flist[follower].selectIn(flist[follower].getDefaultTargetFrame(),
85                                 list[2], list[3])
86         }
87         return true;
88 }
89
90 function viewlist(list1, list2, list3, list4) {
91         // list1 = new Object(list1);
92         var list = new Array(("" + list1), ("" + list2), ("" + list3), ("" + list4));
93         var msg = "Viewport extent change::\n" + "AlignFrame obj: " + list[0]
94                         + " id : " + list[1] + "\nRow from " + list[2] + " and to "
95                         + list[3] + "\nVisible columns: " + list[4] + "\n";
96         var flist = getDestinationFrms(list1, _jvapps);
97         if (_console) {
98                 _console.value = msg + "\n";
99         }
100
101         for (follower in flist) {
102                 if (_console) {
103                         _console.value += "Sending to " + flist[follower] + "\n";
104                 }
105                 flist[follower].scrollToViewIn(flist[follower].getDefaultTargetFrame(),
106                                 list[2], "-1");
107         }
108         return true;
109 }
110
111 // register a jalview applet and add some handlers to it
112 // jmolView is a reference to a jmol applet that is displaying the PDB files listed (in order) in the modeltofiles Array
113 function linkJvJmol(applet, jmolView, modeltofiles) {
114         var i = _jvapps.length;
115         while (i--) {
116                 if (_jvapps[i].equals(applet)) {
117                         throw ("Ignoring additional linkJvJmol call for "
118                                         + applet.getName() + ".");
119                 }
120         }
121         _jvapps[_jvapps.length] = applet;
122         applet.setMouseoverListener("mouseover");
123         applet.setSelectionListener("sellist");
124         // viewListener not fully implemented in 2.7
125         // try { applet.setViewListener("viewlist"); } catch (err) {};
126         if (jmolView)
127         {
128                 var sep = applet.getSeparator();
129                 var oldjm=jmolView;
130                 // recover full id of Jmol applet
131                 jmolView=_jmolGetApplet(jmolView).id;
132                 var jmbinding=_jvjmols.get(jmolView);
133                 if (!jmbinding)
134                 {       
135                         jmbinding=new Object();
136                         jmbinding._modelstofiles=new Array();
137                         jmbinding._fullmpath=new Array();
138                         jmbinding._filetonum=new Hashtable();
139                         jmbinding._jmol=jmolView;
140                         jmbinding._jmhandle=oldjm;
141                         _jvjmols.put(jmolView,jmbinding);
142                 }
143                 
144                 jmbinding._modelstofiles=jmbinding._modelstofiles.concat(jmbinding._modelstofiles,modeltofiles);
145                 jmbinding._jmol=jmolView;
146                 // now update structureListener list
147                 mtf="";
148                 var dbase = document.baseURI.substring(0,document.baseURI.lastIndexOf("/")+1);
149                 for (m in jmbinding._modelstofiles)
150                 { if (m>0) { mtf+=sep; }
151                 mtf+=jmbinding._modelstofiles[m];
152                 if (jmbinding._modelstofiles[m].indexOf("//")==-1)
153                         { jmbinding._fullmpath[m] = dbase+((jmbinding._modelstofiles[m].indexOf("/")==0) ? jmbinding._modelstofiles[m].substring(1) : jmbinding._modelstofiles[m]); }
154                   jmbinding._filetonum.put(jmbinding._modelstofiles[m], m+1); 
155                   jmbinding._filetonum.put(jmbinding._fullmpath[m], m+1);
156                   
157                   }
158                 applet.setStructureListener("_structure", mtf);
159         }
160 }
161
162 /*function _addJmolModel(jmolid, modelname) {
163         modelname=""+modelname;
164         var jminf = _jvjmols[jmolid];
165         if (!jminf) {
166                 jminf = new Object();
167                 jminf._modelstofiles = new Array(); //new Hashtable();
168                 jminf._jmol = jmolid;
169                 jminf._modellist=new Array();
170                 _jvjmols[jmolid] = jminf;
171         }
172         var obj = new Object();
173         jminf._modeltofiles[modelname] = obj; // .put(modelname, obj);
174         obj.id = modelname;
175         obj.mnum = jminf._modeltofiles.length;
176         jminf._modellist+=modelname;
177 }*/
178
179
180
181 // jmol Jalview Methods
182
183 function _structure(list1, list2, list3, list4) {
184         var follower;
185         // if (_console) { if (!_console.value) { _console.value="";} }
186         if (list1 == "mouseover") {
187                 var list = new Array(("" + list1), ("" + list2), ("" + list3),
188                                 ("" + list4));
189                 // 1 is pdb file, 2 is residue number, 3 is chain
190                 // list1 = new Object(list1);
191                 var base = list[1].indexOf(document.baseURI
192                                 .substring(0, document.baseURI.lastIndexOf('/'))
193                                 ); // .indexOf(_path);
194                 if (base==0) { base = document.baseURI.lastIndexOf('/'); }
195                 var sid = list[1]; // .substring(base);
196                 base = list[1].substring(0, base);
197                 if (_console) {
198                         _console.value += "Model is " + list[1] + ", Structure id is : "
199                                         + sid + "\n";
200                 }
201                 ;
202                 var siddat;
203                 for ( var jmolappi in _jvjmols.values()) {
204                         var jmolapp=_jvjmols.values()[jmolappi];
205                         var msg = "";
206                         if (siddat = jmolapp._filetonum.get(sid)) {
207                                 // we don't putin chain number because there isn't one ?
208                                 // skip select 0 bit
209                                 var ch = ""+list[3];
210                                 if ((""+list[2]).trim().length==1)
211                                         {
212                                         ch+=":"+list[2];
213                                         }
214                                 msg = "select (" + ch + " /" + siddat + ") ;";
215                         }
216                         if (msg) {
217                                 if (_console) {
218                                         _console.value += "Sending '" + msg + "' to jmol." + "\n";
219                                 }
220                         }
221                         jmolScriptWait(msg, "" + jmolapp._jmhandle);
222                         // only do highlight for one jmol ?
223                         // return 1;
224                 }
225         }
226         if (list1 == "colourstruct") {
227                 if (_console) {
228                         _console.value += 'colourStruct("' + list1 + '","' + list2
229                         + '") [' + list4 + ']' + "\n";
230                 }
231                 setTimeout('colourStruct("'+list4+'","' + list1 + '","' + list2 + '")', 1);
232                 return 1;
233         }
234         return 1;
235 }
236 // last colour message
237 var _lastMsg = "";
238 // indicator - if _colourStruct==0 then no colouring is going on
239 var _colourStruct = 0;
240
241 function colourStruct(involves, msg, handle) {
242         if (_colourStruct == 0) {
243                 _colourStruct = 1;
244                 for (ap in _jvapps) {
245                         var _msg = "";
246                         do {
247                                 if (_msg.match(/\S/)) {
248                                         _lastMsg += _msg;
249                                 }
250                                 _msg = "" + _jvapps[ap].getJsMessage(msg, handle);
251                         } while (_msg.match(/\S/));
252                 }
253                 // locate the jmol that should get the message
254                 for (var jmol in _jvjmols.values())
255                         {
256                         var jml=_jvjmols.values()[jmol];
257                         if (jml._filetonum.get(involves))
258                                 {
259                                         colourStructs(jml._jmhandle);
260                                 }
261                         }
262                 _colourStruct = 0;
263         } else {
264                 // setTimeout('colourStruct("'+msg+'","'+handle+'")',3);
265         }
266 }
267
268 function colourStructs(jmolapp) {
269         dbg(0, "Colouring the structures\n");
270         jmolScriptWait("set selectionhalos false;" + _lastMsg
271                         + "; select 0; set selectionhalos true;", jmolapp);
272         _lastMsg = "";
273 }
274 var _jmolhovermsg="";
275 function _jmolhover(jmid, atomlabel, atomidx) {
276         var msg=""+jmid+" "+atomlabel+" "+atomidx;
277         if (_jmolhovermsg==msg)
278                 {
279                 return;
280                 }
281         _jmolhovermsg=msg;
282         modeltofiles = _jvjmols.get(jmid)._modelstofiles;
283         // atomlabel=(""+atomlabel).match(/\[(.+)\](\d+):(.)\.(\S+)\s*\/(\d+)\..+/);
284         // relaxed third parameter - may be null or a model number for multi model
285         // views
286         atomlabel = ("" + atomlabel)
287                         .match(/\[(.+)\](\d+):(.)\.([^\/]+)(\/\d+\.|).+/);
288         atomidx = "" + atomidx;
289         if (atomlabel[5]) {
290                 atomlabel[5] = atomlabel[5].match(/\/(.+)\./)[1];
291                 atomlabel[5] = parseInt(atomlabel[5])-1;
292         } else {
293                 // default - first model
294                 atomlabel[5] = 0;
295         }
296         // use atomlabel[5] to look up model filename so we can highlight associated positions in any jalviews
297         for (ap in _jvapps) {
298                 _jvapps[ap].mouseOverStructure(atomlabel[2], atomlabel[3],
299                                 document.baseURI
300                                                 .substring(0, document.baseURI.lastIndexOf('/'))
301                                                 + "/" + 
302                                                 modeltofiles[atomlabel[5]]);
303                 msg = _jmolhovermsg;
304         }
305 }
306 function _jmolpick(jmid, atomlabel, atomidx) {
307         atomlabel = "" + atomlabel;
308         atomidx = "" + atomidx;
309         // label is atom id, atom number, and xyz coordinates in the form:
310         // C6 #6 -0.30683374 -1.6836332 -0.716934
311         // atom index, starting with 0.
312
313 }
314 function _jmolMessagecallback(jmid, statmess) {
315         // if (statmess.indexOf("Script Terminated")==0)
316         {
317                 var thisTime = new Date();
318                 if (_console) {
319                         _console.value += "Last script execution took : "
320                                         + (thisTime.valueOf() - _lastTime.valueOf()) / 1000.0
321                                         + " seconds.";
322                 }
323                 _lastTime = thisTime;
324
325         }
326 }