lastest modifies
[brisk.git] / web / commons.js
1 /*
2  *  brisk / fieldify - commons.js
3  *
4  *  Copyright (C) 2006-2016 Matteo Nastasi
5  *                          mailto: nastasi@alternativeoutput.it
6  *                                  matteo.nastasi@milug.org
7  *                          web: http://www.alternativeoutput.it
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABLILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * General Public License for more details. You should have received a
18  * copy of the GNU General Public License along with this program; if
19  * not, write to the Free Software Foundation, Inc, 59 Temple Place -
20  * Suite 330, Boston, MA 02111-1307, USA.
21  *
22  */
23
24 var __mop_commons_vers="0.1.0"
25
26 var PLAYERS_N = 3;
27 var EXIT_BAN_TIME = 3600;
28 var cookiepath = "/brisk/";
29
30 var mlang_commons = { 'imgload_a' : { 'it' : 'Immagini caricate ',
31                                       'en' : 'Loaded images ' },
32                       'imgload_b' : { 'it' : '%.',
33                                       'en' : '%.' },
34                       'gamleav'   : { 'it' : 'Sei sicuro di volere lasciare questa mano?' ,
35                                       'en' : 'Are you sure to leave this game?' },
36                       'brileav'   : { 'it' : '    Vuoi veramente abbandonare la briscola ?\n(clicca annulla o cancel se vuoi ricaricare la briscola)',
37                                       'en' : '    Are you really sure to leave briscola ?\n(click cancel yo reload it)' },
38                       'brireco'   : { 'it' : 'Ripristino della briscola fallito, per non perdere la sessione ricaricare la pagina manualmente.',
39                                       'en' : 'Recovery of briscola failed, to keep the current session reload the page manually.' },
40                       'btn_sit'   : { 'it' : 'Mi siedo.',
41                                       'en' : 'Sit down.' },
42                       'btn_exit'  : { 'it' : 'Esco.',
43                                       'en' : 'Exit.' },
44                       'tit_list'  : { '0'  : { 'it' : '',
45                                                'en' : '' },
46                                       '1'  : { 'it' : '(solo aut.)',
47                                                'en' : '(only aut.)' },
48                                       '2'  : { 'it' : '(isolam.to)',
49                                                'en' : '(isolation)' } },
50                       'tos_refu'  : { 'it' : 'Rifiutando di sottoscrivere i nuovi termini del servizio non ti sarà più possibile accedere come utente registrato al sito, sei proprio sicuro di voler rifiutare le nuove condizioni d\'uso ?',
51                                       'en' : 'EN Rifiutando di sottoscrivere i nuovi termini del servizio non ti sarà più possibile accedere come utente registrato al sito, sei proprio sicuro di voler rifiutare le nuove condizioni d\'uso ?'
52                                     }
53                     };
54
55 function $(id) { return document.getElementById(id); }
56
57 function $C(cls) { return document.getElementsByClassName(cls); }
58
59 function dec2hex(d, padding)
60 {
61     var hex = Number(d).toString(16);
62     padding = typeof (padding) === "undefined" || padding === null ? padding = 2 : padding;
63
64     while (hex.length < padding) {
65         hex = "0" + hex;
66     }
67
68     return hex;
69 }
70
71 function ends_with(s, suffix)
72 {
73     if (s.indexOf(suffix, s.length - suffix.length) !== -1) {
74         return true;
75     }
76     return false;
77 }
78
79 function getStyle(x,IEstyleProp, MozStyleProp)
80 {
81     if (x.currentStyle) {
82         var y = x.currentStyle[IEstyleProp];
83     } else if (window.getComputedStyle) {
84         var y = document.defaultView.getComputedStyle(x,null).getPropertyValue(MozStyleProp);
85     }
86     return y;
87 }
88
89 /* replacement of setInterval on IE */
90 (function(){
91     /*if not IE, do nothing*/
92     if(!document.uniqueID){return;};
93
94     /*Copy the default setInterval behavior*/
95     var nativeSetInterval = window.setInterval;
96     window.setInterval = function(fn,ms) {
97         var param = [];
98         if(arguments.length <= 2)       {
99             return nativeSetInterval(fn,ms);
100         }
101         else {
102             for(var i=2;i<arguments.length;i+=1) {
103                 param[i-2] =  arguments[i];
104             }
105         }
106
107         if(typeof(fn)=='function') {
108
109             return (function (fn,ms,param) {
110                 var fo = function () {
111                     fn.apply(window,param);
112                 };
113                 return nativeSetInterval(fo,ms);
114             })(fn,ms,param);
115         }
116         else if(typeof(fn)=='string')
117         {
118             return  nativeSetInterval(fn,ms);
119         }
120         else
121         {
122             throw Error('setInterval Error\nInvalid function type');
123         };
124     };
125
126     /*Copy the default setTimeout behavior*/
127     var nativeSetTimeout = window.setTimeout;
128     window.setTimeout = function(fn,ms) {
129         var param = [];
130         if(arguments.length <= 2)       {
131             return nativeSetTimeout(fn,ms);
132         }
133         else {
134             for(var i=2;i<arguments.length;i+=1) {
135                 param[i-2] =  arguments[i];
136             }
137         }
138
139         if(typeof(fn)=='function') {
140
141             return (function (fn,ms,param) {
142                 var fo = function () {
143                     fn.apply(window,param);
144                 };
145                 return nativeSetTimeout(fo,ms);
146             })(fn,ms,param);
147         }
148         else if(typeof(fn)=='string')
149         {
150             return  nativeSetTimeout(fn,ms);
151         }
152         else
153         {
154             throw Error('setTimeout Error\nInvalid function type');
155         };
156     };
157
158 })()
159
160 function addEvent(obj, type, fn)
161 {
162     if (obj.addEventListener) {
163         obj.addEventListener( type, fn, false);
164     }
165     else if (obj.attachEvent) {
166         obj["e"+type+fn] = fn;
167         obj[type+fn] = function() { obj["e"+type+fn]( window.event ); }
168         obj.attachEvent( "on"+type, obj[type+fn] );
169     }
170     else
171         throw new Error("Event registration not supported");
172 }
173
174 function removeEvent(obj,type,fn)
175 {
176     if (obj.removeEventListener) {
177         obj.removeEventListener( type, fn, false );
178     }
179     else if (obj.detachEvent) {
180         obj.detachEvent( "on"+type, obj[type+fn] );
181         obj[type+fn] = null;
182         obj["e"+type+fn] = null;
183     }
184 }
185
186     // var card_pos = RANGE 0 <= x < cards_ea_n
187
188 function show_bigpict(obj, act, x, y)
189 {
190    var big, sfx;
191
192    if (arguments.length > 4)
193        sfx = arguments[4];
194    else
195        sfx = '';
196
197    big = $(obj.id+"_big"+sfx);
198    if (act == "over") {
199        big.style.left = obj.offsetLeft + x+"px";
200        big.style.top  = obj.offsetTop  + y+"px";
201        big.style.visibility = "visible";
202        }
203    else {
204        big.style.visibility = "hidden";
205        }
206 }
207
208 function rnd_int(min, max) {
209   return Math.floor(Math.random() * (max - min + 1) + min);
210 }
211
212 function error_images()
213 {
214     // alert("GHESEMU!");
215     setTimeout(preload_images, 2000, g_preload_img_arr, g_imgct-1);
216 }
217
218 function abort_images()
219 {
220     // alert("ABORTAIMAGES");
221     setTimeout(preload_images, 2000, g_preload_img_arr, g_imgct-1);
222 }
223
224 function unload_images()
225 {
226     // alert("ABORTAIMAGES");
227     setTimeout(preload_images, 2000, g_preload_img_arr, g_imgct-1);
228 }
229
230 function reset_images()
231 {
232     // alert("ABORTAIMAGES");
233     setTimeout(preload_images, 2000, g_preload_img_arr, g_imgct-1);
234 }
235
236 function update_images()
237 {
238     // MLANG "Immagine caricate" + g_preload_imgsz_arr[g_imgct] + "%."
239     $("imgct").innerHTML = mlang_commons['imgload_a'][g_lang]+g_preload_imgsz_arr[g_imgct]+"%.";
240     if (g_imgct+1 < g_preload_img_arr.length) {
241         g_imgct++;
242         setTimeout(preload_images, 100, g_preload_img_arr, g_imgct-1);
243     }
244     // $("imgct").innerHTML += "U";
245 }
246
247 function preload_images(arr,idx)
248 {
249     var im = new Image;
250
251     // $("imgct").innerHTML = "Stiamo caricando "+arr[idx]+"%.<br>";
252     im.onload =   update_images;
253     im.onerror =  error_images;
254     im.onabort =  abort_images;
255     im.onunload = unload_images;
256     im.onreset =  reset_images;
257     im.src =      arr[idx];
258     // $("imgct").innerHTML += "P";
259 }
260
261 function safestatus(a)
262 {
263     try{
264         return (a.status);
265     } catch(b)
266         { return (-1); }
267 }
268
269 function createXMLHttpRequest() {
270     if (typeof(ActiveXObject) != 'undefined') { // Konqueror complain as unknown object
271         try { return new ActiveXObject("Msxml2.XMLHTTP");    } catch(e) {}
272         try { return new ActiveXObject("Microsoft.XMLHTTP"); } catch(e) {}
273     }
274     try { return new XMLHttpRequest();                   } catch(e) {}
275     alert("XMLHttpRequest not supported");
276     return null;
277 }
278
279 function send_mesg(mesg)
280 {
281     var xhr_wr = createXMLHttpRequest();
282     var is_conn = (sess == "not_connected" ? false : true);
283
284     // alert("xhr_wr: "+xhr_wr+"  is_conn: "+is_conn);
285     xhr_wr.open('GET', 'index_wr.php?&'+(is_conn ? 'sess='+sess : '')+'&stp='+gst.st+'&mesg='+mesg, (is_conn ? true : false));
286     xhr_wr.setRequestHeader("If-Modified-Since", new Date().toUTCString());
287     xhr_wr.onreadystatechange = function() { return; };
288     if (typeof(g_debug) == 'number' && g_debug > 0
289         && typeof(console) == 'object' && typeof(console.log) == 'function') {
290             var ldate = new Date();
291             console.log(ldate.getTime()+':MESG:'+mesg);
292     }
293     xhr_wr.send(null);
294
295     if (!is_conn) {
296         if (xhr_wr.responseText != null) {
297             eval(xhr_wr.responseText);
298         }
299     }
300 }
301
302 /*
303   sync request to server
304   server_request([arg0=arg1[, arg2=arg3[, ...]]])
305   if var name == '__POST__' than all other vars will be managed as POST content
306                                  and the call will be a POST
307  */
308 function server_request(page, sess)
309 {
310     var xhr_wr = createXMLHttpRequest();
311     var tout = -1;
312     var i, collect = "", post_collect = null, is_post = false;
313
314     if (arguments.length > 0) {
315         for (i = 2 ; i < arguments.length ; i+= 2) {
316             if (arguments[i] == "__POST__") {
317                 is_post = true;
318                 post_collect = "";
319                 i -= 1;
320                 continue;
321             }
322             if (is_post)
323                 post_collect += (post_collect == "" ? "" : "&") + arguments[i] + "=" + encodeURIComponent(arguments[i+1]);
324             else
325                 collect += (i == 0 ? "" : "&") + arguments[i] + "=" + encodeURIComponent(arguments[i+1]);
326         }
327     }
328     var uri = page + '?' + (sess != null ? 'sess=' + sess + '&' : '') + collect;
329     if (is_post) {
330         xhr_wr.open('POST', uri, false);
331         xhr_wr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
332     }
333     else {
334         xhr_wr.open('GET', uri, false);
335     }
336     if (tout > 0) {
337         xhr_wr.timeout = tout;
338     }
339
340     xhr_wr.onreadystatechange = function() {
341         console.log('we are here');
342         return; };
343     xhr_wr.send(post_collect);
344
345     if (xhr_wr.responseText != null) {
346         // console.log("server_request:resp: "+xhr_wr.responseText);
347         return (xhr_wr.responseText);
348     }
349     else
350         return (null);
351 }
352
353
354 function server_asyncreq(async_req, page, sess)
355 {
356     var xhr_wr = createXMLHttpRequest();
357     var tout = -1;
358     var i, collect = "", post_collect = null, is_post = false;
359
360     if (arguments.length > 0) {
361         for (i = 3 ; i < arguments.length ; i+= 2) {
362             if (arguments[i] == "__POST__") {
363                 is_post = true;
364                 post_collect = "";
365                 i -= 1;
366                 continue;
367             }
368             else if (arguments[i] == "__TOUT__") {
369                 tout = arguments[i+1];
370                 continue;
371             }
372             if (is_post)
373                 post_collect += (post_collect == "" ? "" : "&") + arguments[i] + "=" + encodeURIComponent(arguments[i+1]);
374             else
375                 collect += (i == 0 ? "" : "&") + arguments[i] + "=" + encodeURIComponent(arguments[i+1]);
376         }
377     }
378     var already_quest = (page.indexOf('?') != -1);
379     var uri = page + (already_quest ? '&' : '?') + (sess != null ? 'sess=' + sess + '&' : '') + collect;
380     if (is_post) {
381         xhr_wr.open('POST', uri, true);
382         xhr_wr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
383     }
384     else {
385         xhr_wr.open('GET', uri, true);
386     }
387     if (tout > 0) {
388         xhr_wr.timeout = tout;
389     }
390
391     xhr_wr.onreadystatechange = async_req;
392     xhr_wr.send(post_collect);
393
394     return;
395 }
396
397 /* Stat: CHAT and TABLE */
398
399 function chatt_checksend(obj,e)
400 {
401     var keynum;
402     var keychar;
403     var numcheck;
404
405     if(window.event) { // IE
406         keynum = e.keyCode;
407     }
408     else if(e.which) { // Netscape/Firefox/Opera
409         keynum = e.which;
410     }
411     // alert("OBJ: "+obj);
412     if (keynum == 13 && obj.value != "") { // Enter
413         act_chatt(obj.value);
414         obj.value = "";
415     }
416 }
417 function act_chatt(value)
418 {
419     if (value.substring(0, 6) == "/info ") {
420         info_show(value.substring(6));
421     }
422     else {
423         send_mesg("chatt|"+encodeURIComponent(value));
424     }
425     /*
426     obj.disabled = true;
427     obj.value = "";
428     obj.disabled = false;
429     obj.focus();
430     */
431     return false;
432 }
433
434 /* Stat: ROOM */
435 function act_ping()
436 {
437     send_mesg("ping");
438 }
439
440 function act_sitdown(table)
441 {
442     send_mesg("sitdown|"+table);
443 }
444
445 function act_wakeup()
446 {
447     send_mesg("wakeup");
448 }
449
450 function act_splash()
451 {
452     send_mesg("splash");
453 }
454
455 function act_help()
456 {
457     send_mesg("help");
458 }
459
460 function act_passwdhowto()
461 {
462     send_mesg("passwdhowto");
463 }
464
465 function act_mesgtoadm()
466 {
467     send_mesg("mesgtoadm");
468 }
469
470 function act_tav()
471 {
472     act_chatt('/tav '+$('txt_in').value);
473     $('txt_in').value = '';
474 }
475
476 function act_about()
477 {
478     send_mesg("about");
479 }
480
481 function act_placing()
482 {
483     send_mesg("placing");
484 }
485
486 function act_roadmap()
487 {
488     send_mesg("roadmap");
489 }
490
491 function act_lascio()
492 {
493     send_mesg("lascio");
494 }
495
496 function safelascio()
497 {
498     var res;
499     // MLANG "Sei sicuro di volere lasciare questa mano?"
500     res = window.confirm(mlang_commons['gamleav'][g_lang]);
501     if (res)
502         act_lascio();
503 }
504
505 function act_logout(exitlock)
506 {
507     send_mesg("logout|"+exitlock);
508 }
509
510 function act_reloadroom()
511 {
512     window.onunload = null;
513     window.onbeforeunload = null;
514     document.location.assign("index.php");
515 }
516
517 function act_shutdown()
518 {
519     var c = 0;
520
521     send_mesg("shutdown");
522     // while (xhr_wr.readyState != 4)
523     //  c++;
524 }
525
526 function postact_logout()
527 {
528     // alert("postact_logout");
529     try {
530         xstm.abort();
531     } catch (e) {}
532
533     // eraseCookie("sess");
534     document.location.assign("index.php");
535 }
536
537 /*
538   type - 'hard' or 'soft'
539   code - if soft: accept (0), refuse (1), download (2), later (3)
540          if hard: accept (0), refuse (1), download (2)
541  */
542 function act_tosmgr(type, code, tos_curr, tos_vers)
543 {
544     if (type != "soft" && type != "hard") {
545         return false;
546     }
547     switch (code) {
548     case 0:
549     case 1:
550         send_mesg("tosmgr|"+type+"|"+code+"|"+tos_curr+"|"+tos_vers);
551         break;
552     case 2:
553         break;
554     default:
555         break;
556     }
557
558     return true;
559 }
560
561 function tos_confirm(val, url)
562 {
563     var dlm;
564
565     switch (val) {
566     case 1:
567         return (window.confirm(mlang_commons['tos_refu'][g_lang]));
568         break;
569     case 2:
570         dlm = new download_mgr(url);
571         return false;
572         break;
573     default:
574         return true;
575         break;
576     }
577 }
578
579 /*
580   function slowimg(img,x1,y1,deltat,free,action,srcend)
581   img    - image to move
582   x1,y1  - destination coords
583   deltat - time for each frame (in msec)
584   free   - when the release the local block for other operations (range: 0 - 1)
585   action - function to run when the image is moved
586   srcend - image to switch when the image is moved
587 */
588
589 function sleep(st, delay)
590 {
591     // alert("LOC_NEW PRE: "+st.st_loc_new);
592
593     st.st_loc_new++;
594
595     setTimeout(function(obj){ if (obj.st_loc_new > obj.st_loc) { obj.st_loc++; }},
596                delay, st);
597 }
598
599 function slowimg(img,x1,y1,deltat,free,action,srcend) {
600     this.img = img;
601
602     // this.x0  = parseInt(document.defaultView.getComputedStyle(this.img, "").getPropertyValue("left"));
603     this.x0 = parseInt(getStyle(this.img,"left", "left"));
604 // alert("img.x0 = "+this.x0);
605     // this.y0  = parseInt(document.defaultView.getComputedStyle(this.img, "").getPropertyValue("top"));
606     this.y0  = parseInt(getStyle(this.img,"top", "top"));
607     this.x1  = x1;
608     this.y1  = y1;
609     this.deltat = deltat;
610     this.free = free;
611     this.action = action;
612     this.srcend = srcend;
613 }
614
615 slowimg.prototype = {
616     img: null,
617     st: null,
618     x0: 0,
619     y0: 0,
620     x1: 0,
621     y1: 0,
622     dx: 0,
623     dy: 0,
624     free: 0,
625     step_n:    0,
626     step_cur:  0,
627     step_free: 0,
628     time:      0,
629     deltat:   40,
630     tout: 0,
631     action: null,
632     srcend: null,
633
634     setstart: function(x0,y0)
635     {
636         this.x0 = x0;
637         this.y0 = y0;
638     },
639
640     setaction: function(act)
641     {
642         this.action = act;
643     },
644
645
646     settime: function(time)
647     {
648         this.time = (time < this.deltat ? this.deltat : time);
649         this.step_n = parseInt(this.time / this.deltat);
650         this.dx = (this.x1 - this.x0) / this.step_n;
651         this.dy = (this.y1 - this.y0) / this.step_n;
652         if (this.step_n * this.deltat == this.time) {
653             this.step_n--;
654         }
655         if (this.free < 1) {
656             this.step_free = parseInt(this.step_n * this.free);
657         }
658     },
659
660     start: function(st)
661     {
662         // $("logz").innerHTML += "               xxxxxxxxxxxxxxxxxxxxxSTART<br>";
663         this.st = st;
664         this.st.st_loc_new++;
665
666         this.img.style.visibility = "visible";
667         setTimeout(function(obj){ obj.animate(); }, this.deltat, this);
668     },
669
670     animate: function()
671     {
672         // $("log").innerHTML = "Val " + this.step_cur + " N: " + this.step_n + "<br>";
673         if (this.step_cur == 0) {
674             var date = new Date();
675             // $("logz").innerHTML = "Timestart: " + date + "<br>";
676         }
677         if (this.step_cur <= this.step_n) {
678             this.img.style.left = this.x0 + this.dx * this.step_cur;
679             this.img.style.top  = this.y0 + this.dy * this.step_cur;
680             this.step_cur++;
681             setTimeout(function(obj){ obj.animate(); }, this.deltat, this);
682             if (this.step_cur == this.step_free && this.st != null) {
683                 if (this.st.st_loc < this.st.st_loc_new) {
684                     // alert("QUI1  " + this.step_cur + "  ZZ  "+  this.step_free);
685                     this.st.st_loc++;
686                     this.st = null;
687                 }
688             }
689         }
690         else {
691             this.img.style.left = this.x1;
692             this.img.style.top  = this.y1;
693             // $("logz").innerHTML += "xxxxxxxxxxxxxxxCLEAR<br>";
694             var date = new Date();
695             // $("logz").innerHTML += "Timestop: " + date + "<br>";
696
697             if (this.action != null) {
698                 eval(this.action);
699             }
700
701             if (this.st != null && this.st.st_loc < this.st.st_loc_new) {
702                 // alert("QUI2");
703                 this.st.st_loc++;
704                 this.st = null;
705             }
706             if (this.srcend != null) {
707                 this.img.src = this.srcend;
708             }
709         }
710     }
711 }
712
713 function div_show(div)
714 {
715     div.style.top = parseInt((document.body.clientHeight - parseInt(getStyle(div,"height", "height"))) / 2) + document.body.scrollTop;
716     div.style.visibility = "visible";
717 }
718
719 /*
720   st
721   text
722   tout: if < 0 => infinite
723   butt: [ strings ]
724   w:
725   h:
726   is_opa:
727   block_time:
728   */
729
730 function notify_document(st, text, tout, butt, confirm_func, confirm_func_args, w, h, is_opa, block_time)
731 {
732     var i, clo, clodiv_ctx, clodiv_wai, box;
733
734     this.st = st;
735
736     this.ancestor = document.body;
737     this.confirm_func = confirm_func;
738     this.confirm_func_args = confirm_func_args;
739     this.st.st_loc_new++;
740
741     clodiv_ctx = document.createElement("div");
742     clodiv_ctx.className = "notify_clo";
743
744     for (i = 0 ; i < butt.length ; i++) {
745         this.input_add(butt[i], i, this.hide, clodiv_ctx);
746     }
747
748     if (block_time > 0) {
749         clodiv_wai = document.createElement("div");
750         clodiv_wai.className = "notify_clo";
751
752         this.input_add("leggere, prego.", 0, null, clodiv_wai);
753         this.clodiv = clodiv_wai;
754         this.clodiv_pkg = clodiv_ctx;
755         clodiv_ctx.style.display = 'none';
756     }
757     else {
758         this.clodiv = clodiv_ctx;
759     }
760
761     cont = document.createElement("div");
762
763     cont.style.borderBottomStyle = "solid";
764     cont.style.borderBottomWidth = "1px";
765     cont.style.borderBottomColor = "gray";
766     cont.style.height = (h - 50)+"px";
767     cont.style.overflow = "auto";
768     cont.style.textAlign = "left";
769     cont.style.padding = "8px";
770     cont.style.fontFamily = "monospace";
771     cont.innerHTML = text;
772
773     box =  document.createElement("div");
774     if (is_opa)
775         box.className = "notify_opaque";
776     else
777         box.className = "notify";
778
779     box.style.zIndex = 200;
780     box.style.width  = w+"px";
781     box.style.marginLeft  = -parseInt(w/2)+"px";
782     box.style.height = h+"px";
783     box.style.top = parseInt((document.body.clientHeight - h) / 2) + document.body.scrollTop;
784     box.appendChild(cont);
785     box.appendChild(this.clodiv);
786     box.style.visibility = "visible";
787
788     this.notitag = box;
789
790     this.ancestor.appendChild(box);
791
792     if (tout > 0) {
793         this.toutid = setTimeout(function(obj){ obj.unblock(); }, tout, this);
794     }
795
796     if (block_time != 0) {
797         this.tblkid = setTimeout(function(obj){ obj.notitag.removeChild(obj.clodiv); obj.clodiv = obj.clodiv_pkg; obj.clodiv.style.display = '';  obj.notitag.appendChild(obj.clodiv); }, block_time, this);
798     }
799 }
800
801 notify_document.prototype = {
802     ancestor: null,
803     st: null,
804     notitag: null,
805     toutid: null,
806     clo: null,
807
808     clodiv: null,
809     clodiv_pkg: null,
810
811     butt: null,
812     tblkid: null,
813
814     confirm_func: null,
815     confirm_func_args: [],
816
817     ret: -1,
818
819     /*
820       s:          button string
821       idx:        button index
822       onclick_cb: name of the onclick callback (with signature f(idx) ) or null
823       anc:        parent dom object
824
825       return new button dom object
826       */
827     input_add: function(s, idx, onclick_cb, anc)
828     {
829         var clo;
830
831         clo = document.createElement("input");
832         clo.type    = "submit";
833         clo.className = "button";
834         clo.style.bottom = "4px";
835         clo.style.margin = "2px";
836         clo.obj     = this;
837         clo.obj_idx = idx;
838         clo.value   = s;
839         if (onclick_cb)
840             clo.onclick = function () { onclick_cb.call(this.obj, this.obj_idx); };
841
842         formsub_hilite(clo);
843         anc.appendChild(clo);
844
845         return (clo);
846     },
847
848     ret_get: function()
849     {
850         // alert("quiz: "+this.rett);
851         return this.ret;
852     },
853
854     unblock: function()
855     {
856         if (this.st.st_loc < this.st.st_loc_new) {
857             this.st.st_loc++;
858         }
859     },
860
861     hide: function(val)
862     {
863         if (this.confirm_func != null) {
864             var args;
865
866             args = [ val ].concat(this.confirm_func_args);
867
868             if (this.confirm_func.apply(null, args) == false) {
869                 return false;
870             }
871         }
872         this.ret = val;
873         clearTimeout(this.toutid);
874         this.ancestor.removeChild(this.notitag);
875         this.unblock();
876     }
877 }
878
879
880
881
882 function notify_ex(st, text, tout, butt, w, h, is_opa, block_time)
883 {
884     var clo, box;
885     var t = this;
886
887     this.st = st;
888
889     this.ancestor = document.body;
890
891     this.st.st_loc_new++;
892
893     clo = document.createElement("input");
894     clo.type = "submit";
895     clo.className = "button";
896     clo.style.bottom = "4px";
897     clo.obj = this;
898     if (block_time > 0) {
899         clo.value = "leggere, prego.";
900         this.butt = butt;
901     }
902     else {
903         clo.value = butt;
904         clo.onclick = function () { this.obj.hide() };
905     }
906
907     clodiv = document.createElement("div");
908     clodiv.className = "notify_clo";
909     this.clo = clo;
910     this.clodiv = clodiv;
911
912     clodiv.appendChild(clo);
913
914     cont = document.createElement("div");
915
916     cont.style.borderBottomStyle = "solid";
917     cont.style.borderBottomWidth = "1px";
918     cont.style.borderBottomColor = "gray";
919     cont.style.height = (h - 30)+"px";
920     cont.style.overflow = "auto";
921     cont.innerHTML = text;
922
923     box =  document.createElement("div");
924     if (is_opa)
925         box.className = "notify_opaque";
926     else
927         box.className = "notify";
928
929     box.style.zIndex = 200;
930     box.style.width  = w+"px";
931     box.style.marginLeft  = -parseInt(w/2)+"px";
932     box.style.height = h+"px";
933     box.style.top = parseInt((document.body.clientHeight - h) / 2) + document.body.scrollTop;
934     box.appendChild(cont);
935     box.appendChild(clodiv);
936     box.style.visibility = "visible";
937
938     this.notitag = box;
939
940     this.ancestor.appendChild(box);
941
942     this.toutid = setTimeout(function(obj){ obj.unblock(); }, tout, this);
943
944     if (block_time != 0) {
945         this.tblkid = setTimeout(function(obj){ obj.clo.value = obj.butt; obj.clo.onclick = function () { this.obj.hide() }; formsub_hilite(obj.clo); obj.clo.focus(); }, block_time, this);
946     }
947     else {
948         formsub_hilite(clo);
949         clo.focus();
950     }
951
952 }
953
954
955 notify_ex.prototype = {
956     ancestor: null,
957     st: null,
958     notitag: null,
959     toutid: null,
960     clo: null,
961     clodiv: null,
962     butt: null,
963     tblkid: null,
964
965     unblock: function()
966     {
967         if (this.st.st_loc < this.st.st_loc_new) {
968             this.st.st_loc++;
969         }
970     },
971
972     hide: function()
973     {
974         clearTimeout(this.toutid);
975         this.ancestor.removeChild(this.notitag);
976         this.unblock();
977     }
978 }
979
980
981 notify.prototype = notify_ex.prototype;                // Define sub-class
982 notify.prototype.constructor = notify;
983 notify.baseConstructor = notify_ex;
984 notify.superClass = notify_ex.prototype;
985
986 function notify(st, text, tout, butt, w, h)
987 {
988     notify_ex.call(this, st, text, tout, butt, w, h, false, 0);
989 }
990
991 function globst() {
992     this.st = -1;
993     this.st_loc = -1;
994     this.st_loc_new = -1;
995     this.comms  = new Array;
996 }
997
998 globst.prototype = {
999     st: -1,
1000     st_loc: -1,
1001     st_loc_new: -1,
1002     comms: null,
1003     sleep_hdl: null,
1004
1005     sleep: function(delay) {
1006         st.st_loc_new++;
1007
1008         if (!this.the_end) {
1009             this.sleep_hdl = setTimeout(function(obj){ if (obj.st_loc_new > obj.st_loc) { obj.st_loc++; obj.sleep_hdl = null; }},
1010                                         delay, this);
1011         }
1012     },
1013
1014     abort: function() {
1015         if (this.sleep_hdl != null) {
1016             clearTimeout(this.sleep_hdl);
1017             this.sleep_hdl = null;
1018         }
1019     }
1020 }
1021
1022 function remark_step()
1023 {
1024     var ct = $("remark").l_remct;
1025
1026     if (ct != 0) {
1027         ct++;
1028         if (ct > 2)
1029             ct = 1;
1030         $("remark").className = "remark"+ct;
1031         $("remark").l_remct = ct;
1032         setTimeout(remark_step,500);
1033     }
1034     else
1035         $("remark").className = "remark0";
1036
1037     return;
1038 }
1039
1040 function remark_on()
1041 {
1042     if ($("remark").l_remct == 0) {
1043         $("remark").l_remct = 1;
1044         setTimeout(remark_step,500);
1045     }
1046 }
1047
1048 function remark_off()
1049 {
1050     $("remark").l_remct = 0;
1051     $("remark").className = "remark0";
1052 }
1053
1054
1055 function italizer(ga)
1056 {
1057     var pre, pos;
1058     if (ga[0] & 2)
1059         return "<i>"+ga[1]+"</i>";
1060     else
1061         return ga[1];
1062 }
1063
1064
1065 function exitlock_show(num, islock)
1066 {
1067     g_exitlock = num;
1068
1069     num = (num < 3 ? num : 3);
1070     $("exitlock").src = "img/exitlock"+num+(islock ? "n" : "y")+".png";
1071     // alert("EXITLOCK: "+$("exitlock").src);
1072     $("exitlock").style.visibility = "visible";
1073 }
1074
1075 var fin = 0;
1076
1077 //    exitlock_show(0, true);
1078
1079
1080 var chatt_lines = new Array();
1081 var chatt_lines_n = 0;
1082
1083 var CHATT_MAXLINES = 40;
1084
1085 function user_decorator(user, is_real)
1086 {
1087     var name, i, sp = "", cl = "";
1088     var flags = user[0] & 0x03 | ((user[0] & 0x0c0000) >> 16);
1089
1090     // console.log(user[1]+" FLAGS: "+flags);
1091
1092     for (i = 0 ; i < 4 ; i++) {
1093         if (flags & (1 << i)) {
1094             cl += sp + "au" + i + (is_real ? "" : "_off");
1095             sp = " ";
1096         }
1097     }
1098
1099     if (flags != 0) {
1100         name = "<span class='" + cl + "'><span class='" +
1101         (is_real && (flags & 0xfffffe && ((flags & 0x01) == 0)) ? "id_usr" : "") +
1102         "'>" + user[1] + "</span></span>";
1103     }
1104     else {
1105         name = user[1];
1106     }
1107
1108     return (name);
1109 }
1110
1111 function user_dec_and_state(el)
1112 {
1113     var content = "";
1114     var val_el;
1115
1116     content = user_decorator(el, true);
1117     content += state_add(el[0],(typeof(el[2]) != 'undefined' ? el[2] : null));
1118
1119     return (content);
1120 }
1121
1122
1123 /* PRO CHATT */
1124 function chatt_sub(dt,data,str)
1125 {
1126     var must_scroll = false;
1127     var name;
1128     var flags;
1129     var isauth;
1130     var bolder = [ (data[0] | 1), data[1] ];
1131     name = user_decorator(bolder, false);
1132
1133     if ($("txt").scrollTop + parseInt(getStyle($("txt"),"height", "height")) -  $("txt").scrollHeight >= 0)
1134         must_scroll = true;
1135
1136     // alert("ARRIVA NAME: "+ name + "  STR:"+str);
1137     if (chatt_lines_n == CHATT_MAXLINES) {
1138         $("txt").innerHTML = "";
1139         for (i = 0 ; i < (CHATT_MAXLINES - 1) ; i++) {
1140             chatt_lines[i] = chatt_lines[i+1];
1141             $("txt").innerHTML += chatt_lines[i];
1142         }
1143         chatt_lines[i] = dt+name+": "+str+ "<br>";
1144         $("txt").innerHTML += chatt_lines[i];
1145     }
1146     else {
1147         chatt_lines[chatt_lines_n] = dt+name+": "+str+ "<br>";
1148         $("txt").innerHTML += chatt_lines[chatt_lines_n];
1149         chatt_lines_n++;
1150     }
1151     // $("txt").innerHTML;
1152
1153
1154     if (must_scroll) {
1155         $("txt").scrollTop = 10000000;
1156     }
1157     // alert("scTOP "+$("txt").scrollTop+"  scHEIGHT: "+$("txt").scrollHeight+" HEIGHT: "+getStyle($("txt"),"height", "height") );
1158 }
1159
1160 /*
1161  *  GESTIONE DEI COOKIES
1162  */
1163 function createCookie(name,value,hours,path) {
1164         if (hours) {
1165                 var date = new Date();
1166                 date.setTime(date.getTime()+(hours*60*60*1000));
1167                 var expires = "; expires="+date.toGMTString();
1168         }
1169         else var expires = "";
1170         document.cookie = name+"="+value+expires+"; path="+path;
1171 }
1172
1173 function readCookie(name) {
1174         var nameEQ = name + "=";
1175         var ca = document.cookie.split(';');
1176         for(var i=0;i < ca.length;i++) {
1177                 var c = ca[i];
1178                 while (c.charAt(0)==' ')
1179                     c = c.substring(1,c.length);
1180                 if (c.indexOf(nameEQ) == 0)
1181                     return c.substring(nameEQ.length,c.length);
1182         }
1183         return null;
1184 }
1185
1186 function eraseCookie(name) {
1187         createCookie(name,"",-1);
1188 }
1189
1190 function onbeforeunload_cb () {
1191     return("");
1192 }
1193
1194 function onunload_cb () {
1195
1196     if (typeof(xstm) != "undefined")
1197         xstm.the_end = true;
1198
1199     act_shutdown();
1200
1201     return(false);
1202 }
1203
1204 function room_checkspace(emme,tables,inpe)
1205 {
1206     nome = "<b>";
1207     for (i = 0 ; i < emme ; i++)
1208         nome += "m";
1209     nome += "</b>";
1210
1211     alta = "";
1212     for (i = 0 ; i < 5 ; i++)
1213         alta += nome+"<br>";
1214
1215     for (i = 0 ; i < tables ; i++) {
1216         $("table"+i).innerHTML = alta;
1217         // MLANG Mi siedo.
1218         $("table_act"+i).innerHTML = "<input type=\"button\" class=\"button\" name=\"xhenter"+i+"\"  value=\""+mlang_commons['btn_sit'][g_lang]+"\" onclick=\"act_sitdown(1);\">";
1219         }
1220
1221     stand = "<table class=\"table_standup\"><tbody><tr>";
1222     for (i = 0 ; i < inpe ; i++) {
1223         stand += "<td>"+nome+"</td>";
1224         if ((i+1) % 4 == 0) {
1225             stand += "</tr><tr>";
1226         }
1227     }
1228     stand += "</tr>";
1229     $("standup").innerHTML = stand;
1230
1231     // VERIFY: what is this button ?
1232     // MLANG Esco.
1233     $("esco").innerHTML = "<input class=\"button\" name=\"logout\" type=\"button\" value=\""+mlang_commons['btn_exit'][g_lang]+"\" onclick=\"act_logout();\" type=\"button\">";
1234 }
1235
1236 function  unescapeHTML(cont) {
1237     var div = document.createElement('div');
1238     var memo = "";
1239     var i;
1240
1241     div.innerHTML = cont;
1242     if (div.childNodes[0]) {
1243         if (div.childNodes.length > 1) {
1244             if (div.childNodes.toArray)
1245                 alert("si puo");
1246             else {
1247                 var length = div.childNodes.length, results = new Array(length);
1248             while (length--)
1249                 results[length] = div.childNodes[length];
1250
1251             for (i=0 ; i<results.length ; i++)
1252                 memo = memo + results[i].nodeValue;
1253             }
1254
1255             return (memo);
1256         }
1257         else {
1258             return (div.childNodes[0].nodeValue);
1259         }
1260     }
1261     else {
1262         return ('');
1263     }
1264 }
1265
1266 function playsound(tag, sound) {
1267    // g_withflash is a global var
1268    if (g_withflash) {
1269       $(tag).innerHTML = '<OBJECT classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" '+
1270 'codebase="http://active.macromedia.com/flash2/cabs/swflash.cab#version=4,0,0,0" id="mysound" WIDTH=1 HEIGHT=1>' +
1271 '<PARAM NAME="movie" VALUE="../playsound.swf"><PARAM NAME="PLAY" VALUE="true"><PARAM NAME="LOOP" VALUE="false">' +
1272 '<PARAM NAME=FlashVars VALUE="streamUrl='+sound+'">' +
1273 '<EMBED swliveconnect="true" name="mysound" src="../playsound.swf" FlashVars="streamUrl='+sound+'" PLAY="true" LOOP="false" '+
1274 ' WIDTH=1 HEIGHT=1 TYPE="application/x-shockwave-flash" PLUGINSPAGE="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash"></OBJECT>';
1275    }
1276 }
1277
1278 function topbanner_init()
1279 {
1280     setInterval(topbanner_cb, 666);
1281 ;
1282 }
1283
1284 function topbanner_cb()
1285 {
1286     var a, b;
1287
1288     a = $('topbanner').style.backgroundColor;
1289     b = $('topbanner').style.borderLeftColor;
1290
1291     $('topbanner').style.backgroundColor = b;
1292     $('topbanner').style.borderColor = a+" "+a+" "+a+" "+a;
1293
1294     // console.log("A: "+a+"  B: "+b);
1295 }
1296
1297 function sidebanner_init(idx)
1298 {
1299     setInterval(function () { sidebanner_cb(idx); }, 666);
1300 }
1301
1302 function sidebanner_cb(idx)
1303 {
1304     var a, b;
1305
1306     a = $('sidebanner'+idx).style.backgroundColor;
1307     b = $('sidebanner'+idx).style.borderLeftColor;
1308
1309     $('sidebanner'+idx).style.backgroundColor = b;
1310     $('sidebanner'+idx).style.borderColor = a+" "+a+" "+a+" "+a;
1311
1312     // console.log("A: "+a+"  B: "+b);
1313 }
1314
1315
1316 function langtolng(lang)
1317 {
1318     if (lang == "en")
1319         return ("-en");
1320     else
1321         return ("");
1322 }
1323
1324 function formtext_hilite(obj)
1325 {
1326     obj.className = 'input_text';
1327     addEvent(obj, "focus", function () { this.className = 'input_text_hi'; });
1328     addEvent(obj, "blur",  function () { this.className = 'input_text'; });
1329 }
1330
1331 function formsub_hilite(obj)
1332 {
1333     obj.className = 'input_sub';
1334     addEvent(obj, "focus", function () { this.className = 'input_sub_hi'; });
1335     addEvent(obj, "blur",  function () { this.className = 'input_sub'; });
1336 }
1337
1338 // return the value of the radio button that is checked
1339 // return an empty string if none are checked, or
1340 // there are no radio buttons
1341 function get_checked_value(radioObj) {
1342         if(!radioObj)
1343                 return "";
1344         var radioLength = radioObj.length;
1345         if(radioLength == undefined)
1346                 if(radioObj.checked)
1347                         return radioObj.value;
1348                 else
1349                         return "";
1350         for(var i = 0; i < radioLength; i++) {
1351                 if(radioObj[i].checked) {
1352                         return radioObj[i].value;
1353                 }
1354         }
1355         return "";
1356 }
1357
1358 // set the radio button with the given value as being checked
1359 // do nothing if there are no radio buttons
1360 // if the given value does not exist, all the radio buttons
1361 // are reset to unchecked
1362 function set_checked_value(radioObj, newValue) {
1363         if(!radioObj)
1364                 return;
1365         var radioLength = radioObj.length;
1366         if(radioLength == undefined) {
1367                 radioObj.checked = (radioObj.value == newValue.toString());
1368                 return;
1369         }
1370         for(var i = 0; i < radioLength; i++) {
1371                 radioObj[i].checked = false;
1372                 if(radioObj[i].value == newValue.toString()) {
1373                         radioObj[i].checked = true;
1374                 }
1375         }
1376 }
1377
1378 function url_append_arg(url, name, value)
1379 {
1380     var pos, sep, pref, rest;
1381
1382     if ((pos = url.indexOf('?'+name+'=')) == -1) {
1383         pos = url.indexOf('&'+name+'=');
1384     }
1385     if (pos == -1) {
1386         if ((pos = url.indexOf('?')) != -1)
1387             sep = '&';
1388         else
1389             sep = '?';
1390
1391         return (url+sep+name+"="+encodeURIComponent(value));
1392     }
1393     else {
1394         pref = url.substring(0, pos+1);
1395         rest = url.substring(pos+1);
1396         // alert("rest: "+rest+"  pos: "+pos);
1397         if ((pos = rest.indexOf('&')) != -1) {
1398             rest = rest.substring(pos);
1399         }
1400         else {
1401             rest = "";
1402         }
1403         return (pref+name+"="+encodeURIComponent(value)+rest);
1404     }
1405 }
1406
1407 function url_append_args(url)
1408 {
1409     var i, ret;
1410
1411     ret = url;
1412     for (i = 1 ; i < arguments.length-1 ; i+= 2) {
1413         ret = url_append_arg(ret, arguments[i], arguments[i+1]);
1414     }
1415
1416     return (ret);
1417 }
1418
1419 function url_complete(parent, url)
1420 {
1421     var p, p2, rest;
1422     var host = "", path = "";
1423
1424     // host extraction
1425     p = parent.indexOf("://");
1426     if (p > -1) {
1427         rest = parent.substring(p+3);
1428         p2 = rest.indexOf("/");
1429         if (p2 > -1) {
1430             host = parent.substring(0, p+3+p2);
1431             rest = parent.substring(p+3+p2);
1432         }
1433         else {
1434             host = rest;
1435             rest = "";
1436         }
1437     }
1438     else {
1439         rest = parent;
1440     }
1441
1442     // path extraction
1443     p = rest.lastIndexOf("/");
1444     if (p > -1) {
1445         path = rest.substring(0, p+1);
1446     }
1447
1448     // alert("host: ["+host+"]  path: ["+path+"]");
1449     if (url.substring(0,6) == 'http:/' || url.substring(0,7) == 'https:/' || url.substring(0,4) == 'ws:/') {
1450         return (url);
1451     }
1452     else if (url.substring(0,1) == '/') {
1453         return (host+url);
1454     }
1455     else {
1456         return (host+path+url);
1457     }
1458 }
1459
1460 function download_mgr(url)
1461 {
1462     var ifra;
1463
1464     if ((ifra = $('the_downloader')) == null) {
1465         ifra = document.createElement("iframe");
1466         ifra.style.display = "none";
1467         ifra.id = 'the_downloader';
1468         document.body.appendChild(ifra);
1469     }
1470
1471     ifra.contentWindow.location.href = url;
1472
1473     this.ifra = ifra;
1474 }
1475
1476 download_mgr.prototype = {
1477     ifra: null
1478 }
1479
1480 function submit_click(obj)
1481 {
1482     obj.form.elements['realsub'].value = obj.id;
1483 }
1484
1485 function class_check(item, cls_name)
1486 {
1487     if ((" " + item.className + " ").indexOf(" " + cls_name + " ") == -1)
1488         return (false);
1489     else
1490         return (true);
1491 }
1492
1493 function class_add(item, cls_name)
1494 {
1495     for (i = 1 ; i < arguments.length ; i++) {
1496         if (! class_check(item, arguments[i])) {
1497             item.className = item.className + " " + arguments[i];
1498         }
1499     }
1500 }
1501
1502 function class_rem(item, cls_name)
1503 {
1504     for (i = 1 ; i < arguments.length ; i++) {
1505         var item_spc = " " + item.className + " ";
1506         var cls_spc = " " + arguments[i] + " ";
1507         var cls_out;
1508
1509         var pos = item_spc.indexOf(cls_spc);
1510         if (pos != -1) {
1511             cls_out = item_spc.substring(0, pos) + item_spc.substring(pos + cls_spc.length - 1);
1512             if (cls_out == " ") {
1513                 item.className = "";
1514             }
1515             else {
1516                 item.className = cls_out.substring(1, cls_out.length - 1);
1517             }
1518         }
1519     }
1520 }
1521
1522 function class_subst(item, cls_out, cls_in)
1523 {
1524     class_rem(item, cls_out);
1525     class_add(item, cls_in);
1526 }
1527
1528 function nexst(after)
1529 {
1530     if (after != undefined) {
1531         this._after = after;
1532     }
1533 }
1534
1535 nexst.next = function(st)
1536 {
1537     if (st === null || st === undefined)
1538         st = new nexst();
1539     st._step++;
1540
1541     return st;
1542 };
1543
1544 nexst.prev = function(st)
1545 {
1546     st._step--;
1547 }
1548
1549 nexst.reprise = function ()
1550 {
1551     var thiz, args_in, args = [];
1552
1553     if (arguments.length > 1) {
1554         thiz = arguments[0];
1555         args_in = arguments[1];
1556         }
1557     else {
1558         thiz = null;
1559         args_in = arguments[0];
1560         }
1561
1562     for (var i = 0 ; i < args_in.length ; i++) {
1563         args[i] = args_in[i];
1564     }
1565     return args_in.callee.apply(thiz, args);
1566 };
1567
1568 nexst.prototype = {
1569     _step: 0,     // current step for the async multistep command
1570     _data: null,  // data returned at the end of the async command
1571     _subst: null, // substatus for nested async command
1572     _after: null, // callback (as 'arguments' object) to run at the end
1573                   // of last step
1574
1575     step_set: function(step) {
1576         this._step = step;
1577     },
1578
1579     step_get: function() {
1580         return this._step;
1581     },
1582
1583     data_set: function(data) {
1584         this._data = data;
1585     },
1586
1587     data_get: function() {
1588         return this._data;
1589     },
1590
1591     subst_set: function(subst) {
1592         this._subst = subst;
1593     },
1594
1595     subst_get: function() {
1596         return this._subst;
1597     },
1598
1599     after_set: function(after) {
1600         this._after = after;
1601     },
1602
1603     after_get: function() {
1604         return this._after;
1605     },
1606
1607     done_set: function() {
1608         this.done = true;
1609     },
1610
1611     done_get: function() {
1612         return (this.done);
1613     }
1614 };