<!--
var opened = false, vkb = null, text = null, insertionS = 0, insertionE = 0;

var userstr = navigator.userAgent.toLowerCase();
var safari = (userstr.indexOf('applewebkit') != -1);
var gecko  = (userstr.indexOf('gecko') != -1) && !safari;
var standr = gecko || window.opera || safari;

function backFocus()
{
  if(opened)
  {
    setRange(text, insertionS, insertionE);
    text.focus();
  }
}

function show_keyb(_id) {
	input_id = _id;
	opened = !opened;

	var w_loc = getObjectPosition(input_id) ;
	
	if(opened && !vkb) {
		// Note: all parameters, starting with 3rd, in the following
		// expression are optional; their values are equal to the
		// default parameter values for the VKeyboard object.
		// The only exception is 15th parameter (flash switch),
		// which is false by default.
	       vkb = new VKeyboard("keyboard",    // container's id
				   keyb_callback, // reference to the callback function
				   "16px",        // font size in px
				   "#000",        // font color
				   "#F00",        // font color for the dead keys
				   "#D6D7E7",     // keyboard base background color
				   "#FFF",        // keys' background color
				   "#DDD",        // background color of switched/selected item
				   "#6B699C",     // border color
				   "#CCC",        // border/font color of "inactive" key (key with no value/disabled)
				   "#D6D7E7",     // background color of "inactive" key (key with no value/disabled)
				   "#F77",        // border color of the language selector's cell
				   true,          // show key flash on click? (false by default)
				   "#CC3300",     // font color for flash event
				   "#FF9966",     // key background color for flash event
				   "#CC3300",     // key border color for flash event
				   1);            // index (0-based) of the initial layout
	   } else {
		vkb.Show(opened);
	   }

	var cst = document.getElementById("keyboard");
	cst.style.top = w_loc.y - 1 ;
	cst.style.left = w_loc.x  - (15 * 31);

    text = document.getElementById(input_id);
    text.focus();

    if(document.attachEvent)
      text.attachEvent("onblur", backFocus);
}

// Advanced callback function:
//
   // Advanced callback function:
   //
   function keyb_callback(ch)
   {
     var val = text.value;

     switch(ch)
     {
       case "BackSpace":
         if(val.length)
         {
           var span = null;

           if(document.selection)
             span = document.selection.createRange().duplicate();

           if(span && span.text.length > 0)
           {
             span.text = "";
             getCaretPositions(text);
           }
           else
             deleteAtCaret(text);
         }

         break;

       case "<":
         if(insertionS > 0)
           setRange(text, insertionS - 1, insertionE - 1);

         break;

       case ">":
         if(insertionE < val.length)
           setRange(text, insertionS + 1, insertionE + 1);

         break;

       case "/\\":
         if(!standr) break;

         var prev  = val.lastIndexOf("\n", insertionS) + 1;
         var pprev = val.lastIndexOf("\n", prev - 2);
         var next  = val.indexOf("\n", insertionS);

         if(next == -1) next = val.length;
         var nnext = next - insertionS;

         if(prev > next)
         {
           prev  = val.lastIndexOf("\n", insertionS - 1) + 1;
           pprev = val.lastIndexOf("\n", prev - 2);
         }

         // number of chars in current line to the left of the caret:
         var left = insertionS - prev;

         // length of the prev. line:
         var plen = prev - pprev - 1;

         // number of chars in the prev. line to the right of the caret:
         var right = (plen <= left) ? 1 : (plen - left);

         var change = left + right;
         setRange(text, insertionS - change, insertionE - change);

         break;

       case "\\/":
         if(!standr) break;

         var prev  = val.lastIndexOf("\n", insertionS) + 1;
         var next  = val.indexOf("\n", insertionS);
         var pnext = val.indexOf("\n", next + 1);

         if( next == -1)  next = val.length;
         if(pnext == -1) pnext = val.length;

         if(pnext < next) pnext = next;

         if(prev > next)
            prev  = val.lastIndexOf("\n", insertionS - 1) + 1;

         // number of chars in current line to the left of the caret:
         var left = insertionS - prev;

         // length of the next line:
         var nlen = pnext - next;

         // number of chars in the next line to the left of the caret:
         var right = (nlen <= left) ? 0 : (nlen - left - 1);

         var change = (next - insertionS) + nlen - right;
         setRange(text, insertionS + change, insertionE + change);

         break;

       default:
         insertAtCaret(text, (ch == "Enter" ? (window.opera ? '\r\n' : '\n') : ch));
     }
   }

   // This function retrieves the position (in chars, relative to
   // the start of the text) of the edit cursor (caret), or, if
   // text is selected in the TEXTAREA, the start and end positions
   // of the selection.
   //
   function getCaretPositions(ctrl)
   {
     var CaretPosS = -1, CaretPosE = 0;

     // Mozilla way:
     if(ctrl.selectionStart || (ctrl.selectionStart == '0'))
     {
       CaretPosS = ctrl.selectionStart;
       CaretPosE = ctrl.selectionEnd;

       insertionS = CaretPosS == -1 ? CaretPosE : CaretPosS;
       insertionE = CaretPosE;
     }
     // IE way:
     else if(document.selection && ctrl.createTextRange)
     {
       var start = end = 0;
       try
       {
         start = Math.abs(document.selection.createRange().moveStart("character", -10000000)); // start

         if (start > 0)
         {
           try
           {
             var endReal = Math.abs(ctrl.createTextRange().moveEnd("character", -10000000));

             var r = document.body.createTextRange();
             r.moveToElementText(ctrl);
             var sTest = Math.abs(r.moveStart("character", -10000000));
             var eTest = Math.abs(r.moveEnd("character", -10000000));

             if ((ctrl.tagName.toLowerCase() != 'input') && (eTest - endReal == sTest))
               start -= sTest;
           }
           catch(err) {}
         }
       }
       catch (e) {}

       try
       {
         end = Math.abs(document.selection.createRange().moveEnd("character", -10000000)); // end
         if(end > 0)
         {
           try
           {
             var endReal = Math.abs(ctrl.createTextRange().moveEnd("character", -10000000));

             var r = document.body.createTextRange();
             r.moveToElementText(ctrl);
             var sTest = Math.abs(r.moveStart("character", -10000000));
             var eTest = Math.abs(r.moveEnd("character", -10000000));

             if ((ctrl.tagName.toLowerCase() != 'input') && (eTest - endReal == sTest))
              end -= sTest;
           }
           catch(err) {}
         }
       }
       catch (e) {}

       insertionS = start;
       insertionE = end
     }
   }

   function setRange(ctrl, start, end)
   {
     if(ctrl.setSelectionRange) // Standard way (Mozilla, Opera, Safari ...)
     {
       ctrl.setSelectionRange(start, end);
     }
     else // MS IE
     {
       var range;

       try
       {
         range = ctrl.createTextRange();
       }
       catch(e)
       {
         try
         {
           range = document.body.createTextRange();
           range.moveToElementText(ctrl);
         }
         catch(e)
         {
           range = null;
         }
       }

       if(!range) return;

       range.collapse(true);
       range.moveStart("character", start);
       range.moveEnd("character", end - start);
       range.select();
     }

     insertionS = start;
     insertionE = end;
   }

   function deleteSelection(ctrl)
   {
     if(insertionS == insertionE) return;

     var tmp = (document.selection && !window.opera) ? ctrl.value.replace(/\r/g,"") : ctrl.value;
     ctrl.value = tmp.substring(0, insertionS) + tmp.substring(insertionE, tmp.length);

     setRange(ctrl, insertionS, insertionS);
   }

   function deleteAtCaret(ctrl)
   {
     // if(insertionE < insertionS) insertionE = insertionS;
     if(insertionS != insertionE)
     {
       deleteSelection(ctrl);
       return;
     }

     if(insertionS == insertionE)
       insertionS = insertionS - 1;

     var tmp = (document.selection && !window.opera) ? ctrl.value.replace(/\r/g,"") : ctrl.value;
     ctrl.value = tmp.substring(0, insertionS) + tmp.substring(insertionE, tmp.length);

     setRange(ctrl, insertionS, insertionS);
   }

   // This function inserts text at the caret position:
   //
   function insertAtCaret(ctrl, val)
   {
     if(insertionS != insertionE) deleteSelection(ctrl);

     if(gecko && document.createEvent && !window.opera)
     {
       var e = document.createEvent("KeyboardEvent");

       if(e.initKeyEvent && ctrl.dispatchEvent)
       {
         e.initKeyEvent("keypress",        // in DOMString typeArg,
                        false,             // in boolean canBubbleArg,
                        true,              // in boolean cancelableArg,
                        null,              // in nsIDOMAbstractView viewArg, specifies UIEvent.view. This value may be null;
                        false,             // in boolean ctrlKeyArg,
                        false,             // in boolean altKeyArg,
                        false,             // in boolean shiftKeyArg,
                        false,             // in boolean metaKeyArg,
                        null,              // key code;
                        val.charCodeAt(0));// char code.

         ctrl.dispatchEvent(e);
       }
     }
     else
     {
       var tmp = (document.selection && !window.opera) ? ctrl.value.replace(/\r/g,"") : ctrl.value;
       ctrl.value = tmp.substring(0, insertionS) + val + tmp.substring(insertionS, tmp.length);
     }

     setRange(ctrl, insertionS + val.length, insertionS + val.length);
   }

   // Translator function:

   var pressedC = false;

   function translate(event)
   {
     if(!vkb || !opened) return true;

	 var name = "";
	 for(var i = 0; i < vkb.avail_langs.length; i++) {
		if(vkb.mod[7].innerHTML == vkb.avail_langs[i][1]) {
			name = vkb.avail_langs[i][0];
			break;
		   }
	   }

	 var arr_type = vkb.AltGr ? (vkb.Shift ? "alt_gr_shift" : "alt_gr") : (vkb.Shift ? "shift" : (vkb.Caps ? "caps" : "normal"));
	 var lang_array = vkb[name + "_" + arr_type];

     if(!lang_array) return true;

     if(!event) event = window.event;
     var key = event.which ? event.which : event.keyCode;

     switch(event.type)
     {
       case "keydown":

         switch(key)
         {
           case 20: // Caps

             if(!pressedC)
             {
               vkb.Caps = !vkb.Caps;
               vkb._refresh_layout();

               pressedC = true;
               return true;
             }
             break;

           case 18: // Alt(Gr)

             vkb.AltGr = true;
             vkb._refresh_layout();

             return true;
             break;

           case 16: // Shift

             vkb.Shift = true;
             vkb._refresh_layout();

             return true;
             break;

           default:
             if(event.initKeyEvent)
             {
               var code = String.fromCharCode(key).toUpperCase().charCodeAt(0);

               if((code < 48) || (code > 222)) return true;

               var keymap = [192,49,50,51,52,53,54,55,56,57,48,189,187, // ~ to =
                             81,87,69,82,84,89,85,73,79,80,219,221,220, // q to \
                             65,83,68,70,71,72,74,75,76,186,222,,       // a to '
                             90,88,67,86,66,78,77,188,190,191];         // z to /

               if(navigator.product && (navigator.product.toLowerCase() == 'gecko'))
               {
                 keymap[11] = 109;
                 keymap[12] = 61;
                 keymap[36] = 59;
               }

               for(i = 0; i < keymap.length; i++)
               {
                 if(keymap[i] == code)
                   break;
               }

               if((i > keymap.length) || !lang_array[i])
               {
                 event.returnValue = false;
                 if(event.preventDefault) event.preventDefault();

                 return false;
               }

               code = parseInt(String(lang_array[i]).substr(3, 4), 16);

               var e = document.createEvent("KeyboardEvent");

               e.initKeyEvent("keypress",       //  in DOMString typeArg,                                                           
                              false,            //  in boolean canBubbleArg,                                                        
                              true,             //  in boolean cancelableArg,                                                       
                              null,             //  in nsIDOMAbstractView viewArg,  Specifies UIEvent.view. This value may be null.     
                              false,            //  in boolean ctrlKeyArg,                                                               
                              false,            //  in boolean altKeyArg,                                                        
                              false,            //  in boolean shiftKeyArg,                                                      
                              false,            //  in boolean metaKeyArg,                                                       
                              code, null);      //  key code.

               text.dispatchEvent(e);

               event.returnValue = false;
               if(event.preventDefault) event.preventDefault();

               insertAtCaret(text, String.fromCharCode(code));
             }

             return true;
         }

         break;

       case "keyup":

         switch(key)
         {
           case 13: // Enter

           case 9: // Tab

             break;

           case 20: // Caps

             pressedC = false;
             break;

           case 18: // Alt(Gr)

             vkb.AltGr = false;
             vkb._refresh_layout();

             return true;
             break;

           case 16: // Shift

             vkb.Shift = false;
             vkb._refresh_layout();

             return true;
             break;
         }

         break;

       case "keypress":

         switch(key)
         {
           case 13: // Enter

           case 32: // Space

             break;

           default: // all other keys

             if((key < 33) || (key > 222) || !(document.all || window.opera || safari)) return true;

             var code = String.fromCharCode(key).toUpperCase().charCodeAt(0);

             var keymap = [96,49,50,51,52,53,54,55,56,57,48,45,61, // ` to =
                           81,87,69,82,84,89,85,73,79,80,91,93,92, // q to \
                           65,83,68,70,71,72,74,75,76,59,39,,      // a to '
                           90,88,67,86,66,78,77,44,46,47];         // z to /

             var keymap_sh = [126,33,64,35,36,37,94,38,42,40,41,95,43,   // ~ to +
                              81,87,69,82,84,89,85,73,79,80,123,125,124, // q to |
                              65,83,68,70,71,72,74,75,76,58,34,,         // a to "
                              90,88,67,86,66,78,77,60,62,63];            // z to ?

             var map = vkb.Shift ? keymap_sh : keymap;

             for(i = 0; i < map.length; i++)
               if(map[i] == code)
                 break;

             if((i > map.length) || !lang_array[i]) { event.returnValue = false; return false; }

             code = parseInt(String(lang_array[i]).substr(3, 4), 16)

             if(!window.opera) event.keyCode = code;

             // cancel default behaviour:
             event.returnValue = false;

             insertAtCaret(text, String.fromCharCode(code));
         }

       return false;
     }

     return true;
   }
//-->