// screen memory
var scr=new Array(25*80);
var curs=0;
var dirty=true;
var buf;
// initialize screen
function clrscr() {
  for(var r=0;r<25;r++) {
   for(var c=0;c<80;c++) {
    scr[r*80+c]=' ';
   }
  }
  buf=scr.concat();
  dirty=true;
}
clrscr();

function screen2string() {
  var str="";
  var tscr=buf.concat(); // copy
  for(var c=0;c<tscr.length;c++) {
    if (tscr[c]==' ' || tscr[c]==undefined) tscr[c]="&nbsp;";
    if (tscr[c]=='<') tscr[c]="&lt;";
    if (tscr[c]=='>') tscr[c]="&gt;";
  }
  var cc=tscr[curs];
  if (cc == undefined) {cc="&nbsp;"}
  tscr[curs]="<span class=\"cursor\">"+cc+"</span>";
  for(var r=0;r<25;r++) {
    str+=tscr.slice(r*80,r*80+80).join('');
    str+="<br>\n";
  }
  return str;
}

function expsp(ch) {
  if (ch == undefined || ch == " " ) { return String.fromCharCode(160); }
  return ch;
}
function screenUp() {
	var bc="";
	var cb="";
	for (var r=0;r<25;r++) {
		for (var c=0;c<80;c++) {
			if ((r*80+c)==curs) {
				io_c.firstChild.replaceData(0,1,expsp(buf[r*80+c]));
				bc=cb;
				cb="";
				continue;
			} else {
				cb+=expsp(buf[r*80+c]);
			}
		}
		cb+="\n";
	}
	io_bc.replaceData(0,io_bc.length,bc);
	io_ac.replaceData(0,io_ac.length,cb);
}

function IOmoveTo(x,y) {
	curs=y*80+x;
}

function stOut(st) {
    for(var i=0;i<st.length;i++) {
        buf[curs++]=st.charAt(i);
		if (curs >= 80*25) {
			buf=buf.slice(80);
			curs-=80;
		}
    }
	dirty=true;
}
function chOut(ch) {
    if (ch==13) {
        curs=curs-(curs%80)+80;
    } else if (ch == 8) {
        curs--;
	} else if (ch == 9) {
		curs++;
    } else {
        buf[curs++]=String.fromCharCode(ch);
    }
	if (curs >= 80*25) {
		buf=buf.slice(80);
		curs-=80;
	} else if (curs <0) {
		curs=0;
	}
	dirty=true;
}

function updated() {
	if (dirty) {
		dirty=false;
		screenUp();
		// var outa=document.getElementById('od');
		// outa.innerHTML = screen2string();
	}
}

function screenCh(ind) {
    if(buf[ind]==" ") {return '&nbsp;';}
    if (buf[ind]==undefined) {/* alert(ind+" "+curs); */  return "";}
    return buf[ind];
}

function updated_alt() {
	if (dirty) {
		dirty=false;
        for (var i=0;i<buf.length;i++) {
            if (buf[i] != scr[i]) {
                document.getElementById('ch'+i).innerHTML=screenCh(i);
                scr[i]=buf[i];
            }
        }
        var cd=document.getElementById('ch'+curs);
        // var cc=cd.innerHTML;
        cd.innerHTML="<span class=\"cursor\">"+screenCh(curs)+"</span>";
        scr[curs]=-1;
	}
}

var uiv;
var sinit=1;
function initscr_old() {
    if(sinit) return;
    sinit=1;
    var outa=document.getElementById('od');
    var str="";
    var A=new Array;
    for(var c=0;c<scr.length;c++) {
        var row=Math.floor(c/80);
        var col=c%80;
        var top=row*16+1;
        var left=col*7+1;
        A.push('<div id="ch'+c+'" class="char" style="top:'+top+'; left:'+left+'; ">'+screenCh(c)+'</div>\n');
    }
    str=A.join("");
    outa.innerHTML=str;
}

var io_bc=null;
var io_ac=null;
var io_c=null;
function initscr() {
    var outa=document.getElementById('od');
	while (outa.hasChildNodes()) {
		outa.removeChild(outa.firstChild);
	}
	io_bc=document.createTextNode("");
	io_ac=document.createTextNode("");
	io_c=document.createElement('span');
	io_c.setAttribute('class','cursor');
	io_c.appendChild(document.createTextNode(" "));
	outa.appendChild(io_bc);
	outa.appendChild(io_c);
	outa.appendChild(io_ac);
}

function ioinit() {
    Kq=new Array;
    initscr();
    clrscr();
    iorun();
}

function iorun() {
    uiv=window.setInterval(updated,100);
	document.onkeypress=doKey;
	// document.onkeydown=doKey;
}

function nop() {}

function iopause() {
    window.clearInterval(uiv);
	document.onkeypress=nop;
	// document.onkeydown=nop;
}

// terminal input
var Kq=new Array;
function Kin(k) {
    Kq.push(k);
    if (Kq.waiting) {
        Kq.waiting=0;
        doNext();
    }
}

function doKey(ev) {
    if (!ev) ev=window.event;
    var k=ev.keyCode;
    var ch=ev.charCode;
    if (k==191) return; // ignore
    if (k==27) {running=-10;}
    if (k==9) {running=100; doNext();}
	trace("key "+k+" "+ch);
    Kin(k?k:ch);
	if (!(ev.ctrlKey || ev.altKey || ev.metaKey)) {
        if (ev.preventDefault) {
            ev.preventDefault();
        } else {
            ev.returnValue=false;
        }
	}
}
