/*
 * $Id: ajaxterm.js  2010-11-26 v1  CenTauriaИ
 */

var hD='0123456789ABCDEF';
function dec2hex(d) {
var h = hD.substr(d&15,1);
while (d>15) {
d>>=4;
h=hD.substr(d&15,1)+h;
}
return h;
}

function DoubleUTF8( string) {
 		out="";
 	  var state=0;	

    for (var n = 0; n < string.length; n++) {
			var c = string.charCodeAt(n);
      
			if (c < 128) {
				 out += String.fromCharCode(c); //ASCII char
			}  else if (c == 0xC3) { n++; if (n< string.length) { //UTF8 is bad encoded (missing char)
         c = string.charCodeAt(n);
              
              if (c == 0xDA) out+="/";
         else if (c == 0xD9) out+="/";    
         else if (c == 0xC0) out+="\\";
         else if (c == 0xC1) out+="+";
         else if (c == 0xC2) out+="+";
         else if (c == 0xC3) out+="|";
         else if (c == 0xC4) out+="-"; 
         else if (c == 0xC5) out+="+"; 
         else                out+="&("+dec2hex(c)+")";
        
      }} else if (c == 0xC2) { n++; if (n< string.length) {
         c = string.charCodeAt(n);
              
              if (c == 0xF3) out+="|";
         else if (c == 0xF4) out+="|"; 
         else if (c == 0xFF) out+="\\";      
         else                out+="#("+dec2hex(c)+")";
         
      }} else if((c > 127) && (c < 2048)) {
         out+="L("+dec2hex(c)+")";
			}  else {
			   out+="H("+dec2hex(c)+")";	
			}
		}
    return out; 
}
 
 
function setHTML(el, t) { if (!el) return; el.innerHTML = t; el.innerHTML = el.innerHTML; } //nastaví hodnotu elementu

ajaxterm={};
ajaxterm.Terminal = function(id, width, height, keylen, sid) {
        if (!width) width=80;
        if (!height) height=25;
        if (!keylen) keylen=16;
	var ie=(window.ActiveXObject) ? 1 : 0;
	var webkit= (navigator.userAgent.indexOf("WebKit") >= 0) ? 1 : 0;
	if (!sid) { /* generate a session ID if not supplied */
	    sid = '';
	    var alphabet = 'abcdefghijklmnopqrstuvwxyz';
	    var l = alphabet.length;
	    for (var i=0; i < keylen; i++)
		sid += alphabet.charAt(Math.round(Math.random()*l));
	}

	/* query0 is the base URL for a query */
	var query0="s="+sid+"&w="+width+"&h="+height;
	var query1=query0+"&c=1&k=";	/* current query */

	var timeout;		/* callback for the update request */
	var error_timeout;	/* the error callback */
	var keybuf='';		/* keys to be transmitted */
	var sending=0;	/* set when we have a pending request */
	var rmax=1;	/* delay between refresh requests */

	/* elements in the top bar */
	var div=document.getElementById(id);
	var dstat=document.createElement('pre');	/* status line */
	var opt_get=document.createElement('a');   //tlačítko get
	var opt_color=document.createElement('a');  //tlačítko barva
	var sdebug=document.createElement('span');  //Debug info
	var dterm=document.createElement('div');
	
	var opt_alt=document.createElement('a');  //tlačítko ALT
	var opt_ctrl=document.createElement('a');  //tlačítko ctrl
	var opt_fn=document.createElement('a');  //tlačítko ctrl
	var opt_font=document.createElement('a');  //tlačítko Zoom
	
	var fnhelp=document.createElement('img');

	function debug(s) {	setHTML(sdebug, s); }

	function error() {
		debug("Connection lost at "+((new Date).getTime()));
	}


	function opt_add(opt,name) {
		opt.className='off'; //hodnota položky off
		setHTML(opt, ' '+name+' '); //přidá element
		dstat.appendChild(opt); //přidá element
		dstat.appendChild(document.createTextNode(' ')); //prázdný text elementu
	}

  //event při stisku tlačítka get
	function do_get(event) { /* toggle get/post */
		opt_get.className=(opt_get.className=='off')?'on':'off';
		debug('GET '+opt_get.className);
	}

  //event při stisku tlačítka color
	function do_color(event) {
		var o=opt_color.className=(opt_color.className=='off')?'on':'off';
		query1 = query0 + (o=='on' ? "&c=1" : "") + "&k=";
		debug('Color '+opt_color.className);
	}
	
	var key_alt=false;
  //event při stisku tlačítka ALT
	function do_alt(event) {
		var o=opt_alt.className=(opt_alt.className=='off')?'on':'off';
		
		if (opt_alt.className=='off') {key_alt=false;} else { key_alt=true;} 
    debug('ALT '+opt_alt.className);
	}
	
	var key_ctrl=false;
  //event při stisku tlačítka ALT
	function do_ctrl(event) {
		var o=opt_ctrl.className=(opt_ctrl.className=='off')?'on':'off';
		
		if (opt_ctrl.className=='off') {key_ctrl=false;} else { key_ctrl=true;} 
    debug('CTRL '+opt_ctrl.className);
	}
	
	var key_fn=false;
  //event při stisku tlačítka FN
	function do_fn(event) {
		var o=opt_fn.className=(opt_fn.className=='off')?'on':'off';
		
		if (opt_fn.className=='off') {key_fn=false; fnhelp.style.display = "none"; } else { key_fn=true; fnhelp.style.display = "block";} 
    debug('FN '+opt_fn.className);
	}
	
	function do_font(event) {
		if (opt_font.className=='1') {
       dterm.style.fontSize="100%";
       opt_font.className='2';  
       opt_font.style.backgroundColor="#555"; 
    } else if (opt_font.className=='2') {
       dterm.style.fontSize="120%";
       opt_font.className='3';   
       opt_font.style.backgroundColor="#888";
    } else if (opt_font.className=='3') {
       dterm.style.fontSize="86%"   //Default zoom
       opt_font.className='1'; 
       opt_font.style.backgroundColor="#333";
    }
	}

	function update() {
		if (sending) return; //zabraň znovuodeslání
		sending=1;
		var r=new XMLHttpRequest();
		var send=keybuf;
		keybuf = '';
		var query=query1+send;
		if (opt_get.className=='on') {
		    r.open("GET","u?"+query,true);
		    if (ie) { // force a refresh
			r.setRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT");
		    }
		} else {
    r.open("POST","u",true);
		}
		r.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
		r.onreadystatechange = function () {
		    if (r.readyState!=4) return;
		    window.clearTimeout(error_timeout);
		    if (r.status!=200) {
			debug("Connection error, status: "+r.status + ' ' + r.statusText);
			return;
		    }
		    if(ie) {
			var responseXMLdoc = new ActiveXObject("Microsoft.XMLDOM");
			responseXMLdoc.loadXML(r.responseText);
			de = responseXMLdoc.documentElement;
		    } else {
			de=r.responseXML.documentElement;
		    }
		    if (de.tagName=="pre" || de.tagName=="p") {
			setHTML(dterm, DoubleUTF8( unescape(r.responseText)));
			rmax=100;
		    } else {
			rmax*=2;
			if(rmax>2000)
			    rmax=2000;
		    }
		    sending=0;
		    timeout=window.setTimeout(update,rmax);
		}
		error_timeout=window.setTimeout(error,5000);
		r.send ( (opt_get.className=='on') ? null : query );
	}

	function queue(s) {   //přidá klávesu do fronty
		keybuf += s;
		if (sending==0) {
		    window.clearTimeout(timeout);
		    timeout=window.setTimeout(update,1);
		}
	}

	function keypress(ev) { //stisk klávesy
		if (!ev) var ev=window.event;
		
	  key_alt = (ev.altKey || key_alt);
		if (key_alt) {opt_alt.className='on';} else {opt_alt.className='off';}
		
		s="KEY:"+ev.keyCode;
		if (ev.which == 0) s= s+" DOWN";
		if (ev.shiftKey) s= s+" SHIFT";
		
		debug(s);
		
		var kc;
		var k="";
		if (ev.keyCode)   kc=ev.keyCode;
		if (ev.which)     kc=ev.which;
		   
		  if (key_alt) {
         if (kc>=65 && kc<=90)
            kc+=32;
         if (kc>=97 && kc<=122) {
            k=String.fromCharCode(27)+String.fromCharCode(kc);
         }
      } else if (key_ctrl) {
		    if (kc>=65 && kc<=90)        k=String.fromCharCode(kc-64); // Ctrl-A..Z
		    else if (kc>=97 && kc<=122)  k=String.fromCharCode(kc-96); // Ctrl-A..Z
		    else if (kc==54)             k=String.fromCharCode(30); // Ctrl-^
		    else if (kc==109)            k=String.fromCharCode(31); // Ctrl-_
		    else if (kc==219)            k=String.fromCharCode(27); // Ctrl-[
		    else if (kc==220)            k=String.fromCharCode(28); // Ctrl-\
		    else if (kc==221)            k=String.fromCharCode(29); // Ctrl-]
		    else if (kc==219)            k=String.fromCharCode(29); // Ctrl-]
		    else if (kc==219)            k=String.fromCharCode(0);  // Ctrl-@
	 } else if (key_fn) {	  
           if (kc==8)  k=String.fromCharCode(27); // DEL -> Escape
      else if (kc==97) k=String.fromCharCode(9); // a -> Tab 
      else if (kc==13) k=String.fromCharCode(13); // Enter -> Enter   
      else {
           if (kc==113) k="[[A";  // q -> F1
			else if (kc==119) k="[[B";  // w -> F2
			else if (kc==101) k="[[C";  // e -> F3
			else if (kc==114) k="[[D";  // r -> F4
			else if (kc==116) k="[[E";  // t -> F5
			else if (kc==121) k="[17~"; // y -> F6
			else if (kc==117) k="[18~"; // u -> F7
			else if (kc==105) k="[19~"; // i -> F8
			else if (kc==111) k="[20~"; // o -> F9
			else if (kc==112) k="[21~"; // p -> F10
			else if (kc==107) k="[23~"; // k -> F11
			else if (kc==108) k="[24~"; // l -> F12
      
      else if (kc==122) k="[D"; // z -> Left
      else if (kc==120) k="[B"; // x -> Down
      else if (kc== 99) k="[C"; // c -> Right
      else if (kc==115) k="[A"; // s -> Up
    
    	else if (kc==106) k="[5~";   // j -> PgUp
			else if (kc==109) k="[6~";   // m -> PgDn
			else if (kc==110) k="[4~";   // n -> End
			else if (kc==104) k="[1~";  // h -> Home
      else if (kc==103) k="[2~";  // g -> Ins
			else if (kc==98) k="[3~";   // b -> Del
    	
      if (k.length) k=String.fromCharCode(27)+k;      
            }
    	
		} else if (ev.which==0) {
     // AA key etc....
		} else {
		    if (kc==8)
			k=String.fromCharCode(127);  // Backspace
		    else
			k=String.fromCharCode(kc); //běžné klávesy
		}
		if (k.length)
		    queue( encodeURIComponent(k) );
		ev.cancelBubble=true;
		if (ev.stopPropagation) ev.stopPropagation();
		if (ev.preventDefault)  ev.preventDefault();
		return false;
	}
	
	//Keys on Kindle 3 --použitelné
	/*

a=97
s=115
d=100
f=102
g=103
h=104
j=106
k=107
l=108
z=112
x=120
c=99
v=118
b=98
n=110
m=109

DEL=8
SPACE=32
SHIFT=16
ENTER=13
PGUP=33
PGDOWN=34
.46

	*/
	
	//stisk klávesy (dolů)
	function keydown(ev) {
		if (!ev) var ev=window.event;
		if (ie || webkit) {

		s="KEY Down:"+ev.keyCode+" W KEY:"+ev.which;
		if (ev.shiftKey) s= s+" SHIFT";
		if (ev.ctrlKey)  s= s+" CTRL";
		if (ev.altKey)   s= s+" ALT";
		    debug(s);
		  
        // >TAB    >
        //     >BACKSPACE    >PgDown   >HOME                         >Delete
        //              >PgUp     >END                          >Insert
        o={9:1,8:1,27:1,33:1,34:1,35:1,36:1,37:1,38:1,39:1,40:1,45:1,46:1,112:1,113:1,114:1,115:1,116:1,117:1,118:1,119:1,120:1,121:1,122:1,123:1};
		    
        if (o[ev.keyCode] || ev.ctrlKey || ev.altKey) {
			        ev.which=0;
			        return keypress(ev);
		    }
		}
	}
	
	//uvolnění klávesy
	function keyup(ev) {
		if (!ev) var ev=window.event;
		
    if (ie || webkit) {
        s="KEY Up:"+ev.keyCode+" W KEY:"+ev.which;
        if (ev.shiftKey) s= s+" SHIFT";
		    if (ev.ctrlKey)  s= s+" CTRL";
		    if (ev.altKey)   s= s+" ALT";
		  		    		    
        if (ev.keyCode == 33) do_fn(true);
        if (ev.keyCode == 34) do_ctrl(true);
        
        //HW ALT key UP pull back
        if (ev.keyCode == 18) {key_alt = false; opt_alt.className='off';}
        
		    return false;
		    }
	}
	
	function init() {
	  //položka barvy
		opt_add(opt_color,'Colors');
		opt_color.className='on';
		opt_color.title='Toggle color or grey';
		
		//Přepínač POST/GET
    opt_add(opt_get,'GET');
		opt_get.title = 'Toggle GET or POST methods';
		
		//tlačítko Zoom
		opt_add(opt_font,'Zoom');
		opt_font.className='1';
		opt_font.title='Set font size';
		opt_font.style.backgroundColor="#333";
		opt_font.style.color="white";
		opt_font.style.cursor="pointer";
		
		
		//tlačítko ALT
		opt_add(opt_alt,'ALT');
		opt_alt.className='off';
		opt_alt.title='Emulate ALT button.';
		
		//tlačítko CRTL
		opt_add(opt_ctrl,'CTRL');
		opt_ctrl.className='off';
		opt_ctrl.title='Emulate CTRL button.';
		
		//tlačítko FN
		opt_add(opt_fn,'FN');
		opt_fn.className='off';
		opt_fn.title='Emulate FN button.';
		
		//stavový řádek
    dstat.appendChild(sdebug); //SPAN
		dstat.className='stat';
		div.appendChild(dstat);
		div.appendChild(dterm); //DIV (tělo terminálu)
		
    dterm.style.fontSize="86%"   //Default zoom
		
		fnhelp.src="Fn.jpg";
		fnhelp.style.display = "none";
		div.appendChild(fnhelp); //Napoveda
		
		//Přiřazení událostí při stisku tlačítka
		if(opt_color.addEventListener) {
		    opt_get.addEventListener('click',do_get,true);
		    opt_color.addEventListener('click',do_color,true);
		    opt_alt.addEventListener('click',do_alt,true);
		    opt_ctrl.addEventListener('click',do_ctrl,true);
		    opt_fn.addEventListener('click',do_fn,true);
		    opt_font.addEventListener('click',do_font,true);
		} else {
		    opt_get.attachEvent("onclick", do_get);
		    opt_color.attachEvent("onclick", do_color);
		    opt_alt.attachEvent("onclick", do_alt);
		    opt_ctrl.attachEvent("onclick", do_ctrl);
		    opt_fn.attachEvent("onclick", do_fn);
		    opt_font.attachEvent("onclick", do_font);
		}
		
		//Přiřazení událostí.
    document.onkeypress=keypress;
		document.onkeydown=keydown;
		document.onkeyup=keyup;
		
		//obnovení okna
    timeout=window.setTimeout(update,100);
	}
	init();
	//ID Session
	debug('Session: ' + sid);
}
