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