confirmation function added to notify_document js function
[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.innerHTML = text;
701
702     box =  document.createElement("div");
703     if (is_opa)
704         box.className = "notify_opaque";
705     else
706         box.className = "notify";
707
708     box.style.zIndex = 200;
709     box.style.width  = w+"px";
710     box.style.marginLeft  = -parseInt(w/2)+"px";
711     box.style.height = h+"px";
712     box.style.top = parseInt((document.body.clientHeight - h) / 2) + document.body.scrollTop;
713     box.appendChild(cont);
714     box.appendChild(this.clodiv);
715     box.style.visibility = "visible";
716
717     this.notitag = box;
718
719     this.ancestor.appendChild(box);
720
721     if (tout > 0) {
722         this.toutid = setTimeout(function(obj){ obj.unblock(); }, tout, this);
723     }
724
725     if (block_time != 0) {
726         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);
727     }
728 }
729
730 notify_document.prototype = {
731     ancestor: null,
732     st: null,
733     notitag: null,
734     toutid: null,
735     clo: null,
736
737     clodiv: null,
738     clodiv_pkg: null,
739
740     butt: null,
741     tblkid: null,
742
743     confirm_func: null,
744
745     ret: -1,
746
747     /*
748       s:          button string
749       idx:        button index
750       onclick_cb: name of the onclick callback (with signature f(idx) ) or null
751       anc:        parent dom object
752
753       return new button dom object
754       */
755     input_add: function(s, idx, onclick_cb, anc)
756     {
757         var clo;
758
759         clo = document.createElement("input");
760         clo.type    = "submit";
761         clo.className = "button";
762         clo.style.bottom = "4px";
763         clo.style.margin = "2px";
764         clo.obj     = this;
765         clo.obj_idx = idx;
766         clo.value   = s;
767         if (onclick_cb)
768             clo.onclick = function () { onclick_cb.call(this.obj, this.obj_idx); };
769
770         formsub_hilite(clo);
771         anc.appendChild(clo);
772
773         return (clo);
774     },
775
776     ret_get: function()
777     {
778         // alert("quiz: "+this.rett);
779         return this.ret;
780     },
781
782     unblock: function()
783     {
784         if (this.st.st_loc < this.st.st_loc_new) {
785             this.st.st_loc++;
786         }
787     },
788
789     hide: function(val)
790     {
791         if (this.confirm_func != null) {
792             if (this.confirm_func(val) == false) {
793                 return false;
794             }
795         }
796         this.ret = val;
797         clearTimeout(this.toutid);
798         this.ancestor.removeChild(this.notitag);
799         this.unblock();
800     }
801 }
802
803
804
805
806 function notify_ex(st, text, tout, butt, w, h, is_opa, block_time)
807 {
808     var clo, box;
809     var t = this;
810     
811     this.st = st;
812
813     this.ancestor = document.body;
814     
815     this.st.st_loc_new++;
816
817     clo = document.createElement("input");
818     clo.type = "submit";
819     clo.className = "button";
820     clo.style.bottom = "4px";
821     clo.obj = this;
822     if (block_time > 0) {
823         clo.value = "leggere, prego.";
824         this.butt = butt;
825     }
826     else {
827         clo.value = butt;
828         clo.onclick = function () { this.obj.hide() };
829     }
830
831     clodiv = document.createElement("div");
832     clodiv.className = "notify_clo";
833     this.clo = clo;
834     this.clodiv = clodiv;
835
836     clodiv.appendChild(clo);
837
838     cont = document.createElement("div");
839
840     cont.style.borderBottomStyle = "solid";
841     cont.style.borderBottomWidth = "1px";
842     cont.style.borderBottomColor = "gray";
843     cont.style.height = (h - 30)+"px";
844     cont.style.overflow = "auto";
845     cont.innerHTML = text;
846
847     box =  document.createElement("div");
848     if (is_opa)
849         box.className = "notify_opaque";
850     else
851         box.className = "notify";
852
853     box.style.zIndex = 200;
854     box.style.width  = w+"px";
855     box.style.marginLeft  = -parseInt(w/2)+"px";
856     box.style.height = h+"px";
857     box.style.top = parseInt((document.body.clientHeight - h) / 2) + document.body.scrollTop;
858     box.appendChild(cont);
859     box.appendChild(clodiv);
860     box.style.visibility = "visible";
861
862     this.notitag = box;
863     
864     this.ancestor.appendChild(box);
865     
866     this.toutid = setTimeout(function(obj){ obj.unblock(); }, tout, this);
867
868     if (block_time != 0) {
869         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);
870     }
871     else {
872         formsub_hilite(clo);
873         clo.focus();
874     }
875
876 }
877
878
879 notify_ex.prototype = {
880     ancestor: null,
881     st: null,
882     notitag: null,
883     toutid: null,
884     clo: null,
885     clodiv: null, 
886     butt: null,
887     tblkid: null,
888
889     unblock: function()
890     {
891         if (this.st.st_loc < this.st.st_loc_new) {
892             this.st.st_loc++;
893         }
894     },
895     
896     hide: function()
897     {
898         clearTimeout(this.toutid);
899         this.ancestor.removeChild(this.notitag);
900         this.unblock();
901     }
902 }
903
904
905 notify.prototype = notify_ex.prototype;                // Define sub-class
906 notify.prototype.constructor = notify;
907 notify.baseConstructor = notify_ex;
908 notify.superClass = notify_ex.prototype;
909
910 function notify(st, text, tout, butt, w, h)
911 {
912     notify_ex.call(this, st, text, tout, butt, w, h, false, 0);
913 }
914         
915
916 function $(id) { 
917     return document.getElementById(id); 
918 }
919
920
921 function globst() {
922     this.st = -1;
923     this.st_loc = -1;
924     this.st_loc_new = -1;
925     this.comms  = new Array;
926 }
927
928 globst.prototype = {
929     st: -1,
930     st_loc: -1,
931     st_loc_new: -1,
932     comms: null,
933     sleep_hdl: null,
934
935     sleep: function(delay) {
936         st.st_loc_new++;
937
938         if (!this.the_end) {
939             this.sleep_hdl = setTimeout(function(obj){ if (obj.st_loc_new > obj.st_loc) { obj.st_loc++; obj.sleep_hdl = null; }},
940                                         delay, this);
941         }
942     },
943
944     abort: function() {
945         if (this.sleep_hdl != null) {
946             clearTimeout(this.sleep_hdl);
947             this.sleep_hdl = null;
948         }
949     }
950 }
951
952 function remark_step()
953 {
954     var ct = $("remark").l_remct;
955     
956     if (ct != 0) {
957         ct++;
958         if (ct > 2)
959             ct = 1;
960         $("remark").className = "remark"+ct;
961         $("remark").l_remct = ct;
962         setTimeout(remark_step,500);
963     }
964     else
965         $("remark").className = "remark0";
966     
967     return;
968 }
969
970 function remark_on()
971 {
972     if ($("remark").l_remct == 0) {
973         $("remark").l_remct = 1;
974         setTimeout(remark_step,500);
975     }
976 }
977
978 function remark_off()
979 {
980     $("remark").l_remct = 0;
981     $("remark").className = "remark0";
982 }
983
984
985 function italizer(ga)
986 {
987     var pre, pos;
988     if (ga[0] & 2) 
989         return "<i>"+ga[1]+"</i>";
990     else
991         return ga[1];
992 }
993
994
995 function exitlock_show(num, islock)
996 {
997     g_exitlock = num;
998
999     num = (num < 3 ? num : 3);
1000     $("exitlock").src = "img/exitlock"+num+(islock ? "n" : "y")+".png";
1001     // alert("EXITLOCK: "+$("exitlock").src);
1002     $("exitlock").style.visibility = "visible";
1003 }
1004
1005 var fin = 0;
1006
1007 //    exitlock_show(0, true);
1008
1009
1010 var chatt_lines = new Array();
1011 var chatt_lines_n = 0;
1012
1013 var CHATT_MAXLINES = 40;
1014
1015 function user_decorator(user)
1016 {
1017     var name;
1018     var flags = user[0];
1019     if ((flags & 0x03) != 0)
1020         name = "<span class='au" + (flags & 0x03) + "'>"+user[1]+"</span>";
1021     else
1022         name = user[1];
1023
1024     return (name);
1025 }
1026
1027 function user_dec_and_state(el)
1028 {
1029     var content = "";
1030     var val_el;
1031
1032     content = user_decorator(el);
1033     content += state_add(el[0],(typeof(el[2]) != 'undefined' ? el[2] : null));
1034     
1035     return (content);
1036 }
1037
1038
1039 /* PRO CHATT */
1040 function chatt_sub(dt,data,str)
1041 {
1042     var must_scroll = false;
1043     var name;
1044     var flags;
1045     var isauth;
1046     var bolder = [ (data[0] | 1), data[1] ];
1047     name = user_decorator(bolder);
1048
1049     if ($("txt").scrollTop + parseInt(getStyle($("txt"),"height", "height")) -  $("txt").scrollHeight >= 0)
1050         must_scroll = true;
1051
1052     // alert("ARRIVA NAME: "+ name + "  STR:"+str);
1053     if (chatt_lines_n == CHATT_MAXLINES) {
1054         $("txt").innerHTML = "";
1055         for (i = 0 ; i < (CHATT_MAXLINES - 1) ; i++) {
1056             chatt_lines[i] = chatt_lines[i+1];
1057             $("txt").innerHTML += chatt_lines[i];
1058         }
1059         chatt_lines[i] = dt+name+": "+str+ "<br>";
1060         $("txt").innerHTML += chatt_lines[i];
1061     }
1062     else {
1063         chatt_lines[chatt_lines_n] = dt+name+": "+str+ "<br>";
1064         $("txt").innerHTML += chatt_lines[chatt_lines_n];
1065         chatt_lines_n++;
1066     }
1067     // $("txt").innerHTML;
1068
1069     
1070     if (must_scroll) {
1071         $("txt").scrollTop = 10000000;
1072     }
1073     // alert("scTOP "+$("txt").scrollTop+"  scHEIGHT: "+$("txt").scrollHeight+" HEIGHT: "+getStyle($("txt"),"height", "height") );
1074 }
1075
1076 /*
1077  *  GESTIONE DEI COOKIES
1078  */
1079 function createCookie(name,value,hours,path) {
1080         if (hours) {
1081                 var date = new Date();
1082                 date.setTime(date.getTime()+(hours*60*60*1000));
1083                 var expires = "; expires="+date.toGMTString();
1084         }
1085         else var expires = "";
1086         document.cookie = name+"="+value+expires+"; path="+path;
1087 }
1088
1089 function readCookie(name) {
1090         var nameEQ = name + "=";
1091         var ca = document.cookie.split(';');
1092         for(var i=0;i < ca.length;i++) {
1093                 var c = ca[i];
1094                 while (c.charAt(0)==' ') c = c.substring(1,c.length);
1095                 if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
1096         }
1097         return null;
1098 }
1099
1100 function eraseCookie(name) {
1101         createCookie(name,"",-1);
1102 }
1103
1104 function onbeforeunload_cb () {
1105     return("");
1106 }
1107
1108 function onunload_cb () {
1109     
1110     if (typeof(hstm) != "undefined")
1111         hstm.the_end = true; 
1112
1113     act_shutdown();
1114     
1115     return(false);
1116 }
1117
1118 function room_checkspace(emme,tables,inpe)
1119 {
1120     nome = "<b>";
1121     for (i = 0 ; i < emme ; i++) 
1122         nome += "m";
1123     nome += "</b>";
1124
1125     alta = "";
1126     for (i = 0 ; i < 5 ; i++) 
1127         alta += nome+"<br>";
1128
1129     for (i = 0 ; i < tables ; i++) {
1130         $("table"+i).innerHTML = alta;
1131         // MLANG Mi siedo.
1132         $("table_act"+i).innerHTML = "<input type=\"button\" class=\"button\" name=\"xhenter"+i+"\"  value=\""+mlang_commons['btn_sit'][g_lang]+"\" onclick=\"act_sitdown(1);\">";
1133         }
1134
1135     stand = "<table class=\"table_standup\"><tbody><tr>";
1136     for (i = 0 ; i < inpe ; i++) {
1137         stand += "<td>"+nome+"</td>";
1138         if ((i+1) % 4 == 0) {
1139             stand += "</tr><tr>";
1140         }
1141     }
1142     stand += "</tr>";
1143     $("standup").innerHTML = stand;
1144
1145     // VERIFY: what is this button ?
1146     // MLANG Esco.
1147     $("esco").innerHTML = "<input class=\"button\" name=\"logout\" type=\"button\" value=\""+mlang_commons['btn_exit'][g_lang]+"\" onclick=\"act_logout();\" type=\"button\">";
1148 }
1149
1150 function  unescapeHTML(cont) {
1151     var div = document.createElement('div');
1152     var memo = "";
1153     var i;
1154
1155     div.innerHTML = cont;
1156     if (div.childNodes[0]) {
1157         if (div.childNodes.length > 1) {
1158             if (div.childNodes.toArray)
1159                 alert("si puo");
1160             else {
1161                 var length = div.childNodes.length, results = new Array(length);
1162             while (length--)
1163                 results[length] = div.childNodes[length];
1164                 
1165             for (i=0 ; i<results.length ; i++)
1166                 memo = memo + results[i].nodeValue;
1167             }
1168
1169             return (memo);
1170         }
1171         else {
1172             return (div.childNodes[0].nodeValue);
1173         }
1174     }
1175     else {
1176         return ('');
1177     }
1178 }
1179
1180 function playsound(tag, sound) {
1181    // g_withflash is a global var
1182    if (g_withflash) {
1183       $(tag).innerHTML = '<OBJECT classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" '+
1184 'codebase="http://active.macromedia.com/flash2/cabs/swflash.cab#version=4,0,0,0" id="mysound" WIDTH=1 HEIGHT=1>' +
1185 '<PARAM NAME="movie" VALUE="../playsound.swf"><PARAM NAME="PLAY" VALUE="true"><PARAM NAME="LOOP" VALUE="false">' +
1186 '<PARAM NAME=FlashVars VALUE="streamUrl='+sound+'">' +
1187 '<EMBED swliveconnect="true" name="mysound" src="../playsound.swf" FlashVars="streamUrl='+sound+'" PLAY="true" LOOP="false" '+
1188 ' WIDTH=1 HEIGHT=1 TYPE="application/x-shockwave-flash" PLUGINSPAGE="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash"></OBJECT>';
1189    }
1190 }
1191
1192 function topbanner_init()
1193 {
1194     setInterval(topbanner_cb, 666);
1195 ;
1196 }
1197
1198 function topbanner_cb()
1199 {
1200     var a, b;
1201
1202     a = $('topbanner').style.backgroundColor;
1203     b = $('topbanner').style.borderLeftColor;
1204
1205     $('topbanner').style.backgroundColor = b;
1206     $('topbanner').style.borderColor = a+" "+a+" "+a+" "+a;
1207
1208     // console.log("A: "+a+"  B: "+b);
1209 }
1210
1211 function sidebanner_init()
1212 {
1213     setInterval(sidebanner_cb, 666);
1214 }
1215
1216 function sidebanner2_init()
1217 {
1218     setInterval(sidebanner2_cb, 666);
1219 }
1220
1221 function sidebanner_cb()
1222 {
1223     var a, b;
1224
1225     a = $('sidebanner').style.backgroundColor;
1226     b = $('sidebanner').style.borderLeftColor;
1227
1228     $('sidebanner').style.backgroundColor = b;
1229     $('sidebanner').style.borderColor = a+" "+a+" "+a+" "+a;
1230
1231     // console.log("A: "+a+"  B: "+b);
1232 }
1233
1234 function sidebanner2_cb()
1235 {
1236     var a, b;
1237
1238     a = $('sidebanner2').style.backgroundColor;
1239     b = $('sidebanner2').style.borderLeftColor;
1240
1241     $('sidebanner2').style.backgroundColor = b;
1242     $('sidebanner2').style.borderColor = a+" "+a+" "+a+" "+a;
1243
1244     // console.log("A: "+a+"  B: "+b);
1245 }
1246
1247
1248 function langtolng(lang)
1249 {
1250     if (lang == "en")
1251         return ("-en");
1252     else
1253         return ("");
1254 }
1255
1256 function formtext_hilite(obj)
1257 {
1258     obj.className = 'input_text';
1259     addEvent(obj, "focus", function () { this.className = 'input_text_hi'; });
1260     addEvent(obj, "blur",  function () { this.className = 'input_text'; });
1261 }
1262
1263 function formsub_hilite(obj)
1264 {
1265     obj.className = 'input_sub';
1266     addEvent(obj, "focus", function () { this.className = 'input_sub_hi'; });
1267     addEvent(obj, "blur",  function () { this.className = 'input_sub'; });
1268 }
1269
1270 // return the value of the radio button that is checked
1271 // return an empty string if none are checked, or
1272 // there are no radio buttons
1273 function get_checked_value(radioObj) {
1274         if(!radioObj)
1275                 return "";
1276         var radioLength = radioObj.length;
1277         if(radioLength == undefined)
1278                 if(radioObj.checked)
1279                         return radioObj.value;
1280                 else
1281                         return "";
1282         for(var i = 0; i < radioLength; i++) {
1283                 if(radioObj[i].checked) {
1284                         return radioObj[i].value;
1285                 }
1286         }
1287         return "";
1288 }
1289
1290 // set the radio button with the given value as being checked
1291 // do nothing if there are no radio buttons
1292 // if the given value does not exist, all the radio buttons
1293 // are reset to unchecked
1294 function set_checked_value(radioObj, newValue) {
1295         if(!radioObj)
1296                 return;
1297         var radioLength = radioObj.length;
1298         if(radioLength == undefined) {
1299                 radioObj.checked = (radioObj.value == newValue.toString());
1300                 return;
1301         }
1302         for(var i = 0; i < radioLength; i++) {
1303                 radioObj[i].checked = false;
1304                 if(radioObj[i].value == newValue.toString()) {
1305                         radioObj[i].checked = true;
1306                 }
1307         }
1308 }
1309
1310 function url_append_arg(url, name, value)
1311 {
1312     var pos, sep, pref, rest;
1313
1314     if ((pos = url.indexOf('?'+name+'=')) == -1) {
1315         pos = url.indexOf('&'+name+'=');
1316     }
1317     if (pos == -1) {
1318         if ((pos = url.indexOf('?')) != -1)
1319             sep = '&';
1320         else
1321             sep = '?';
1322
1323         return (url+sep+name+"="+encodeURIComponent(value));
1324     }
1325     else {
1326         pref = url.substring(0, pos+1);
1327         rest = url.substring(pos+1);
1328         // alert("rest: "+rest+"  pos: "+pos);
1329         if ((pos = rest.indexOf('&')) != -1) {
1330             rest = rest.substring(pos);
1331         }
1332         else {
1333             rest = "";
1334         }
1335         return (pref+name+"="+encodeURIComponent(value)+rest);
1336     }
1337 }
1338
1339 function url_append_args(url)
1340 {
1341     var i, ret;
1342
1343     ret = url;
1344     for (i = 1 ; i < arguments.length-1 ; i+= 2) {
1345         ret = url_append_arg(ret, arguments[i], arguments[i+1]);
1346     }
1347
1348     return (ret);
1349 }
1350
1351 function url_complete(parent, url)
1352 {
1353     var p, p2, rest;
1354     var host = "", path = "";
1355
1356     // host extraction
1357     p = parent.indexOf("://");
1358     if (p > -1) {
1359         rest = parent.substring(p+3);
1360         p2 = rest.indexOf("/");
1361         if (p2 > -1) {
1362             host = parent.substring(0, p+3+p2);
1363             rest = parent.substring(p+3+p2);
1364         }
1365         else {
1366             host = rest;
1367             rest = "";
1368         }
1369     }
1370     else {
1371         rest = parent;
1372     }
1373
1374     // path extraction
1375     p = rest.lastIndexOf("/");
1376     if (p > -1) {
1377         path = rest.substring(0, p+1);
1378     }
1379
1380     // alert("host: ["+host+"]  path: ["+path+"]");
1381     if (url.substring(0,6) == 'http:/' || url.substring(0,7) == 'https:/' || url.substring(0,4) == 'ws:/') {
1382         return (url);
1383     }
1384     else if (url.substring(0,1) == '/') {
1385         return (host+url);
1386     }
1387     else {
1388         return (host+path+url);
1389     }
1390 }