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