/////////////////////////////////////////////////////
//  HTML5 JavaScript Client for ice/net/HDisplay  //
/////////////////////////////////////////////////////

// global state variables
var cnv,ctx,imgd,wurl,ws;
var mouse = { x:0, y:0, b:0 };

// instantiator
function hdisplay(host,port,x,y,w,h,name) {
  cnv = document.getElementById('canvas');
  ctx = cnv.getContext('2d');
  imgd = ctx.createImageData(16,16)
  wurl = "ws://"+host+":"+port+"/Display/ws/"+name;
  ws = new WebSocket(wurl,"vnc-client");
  initHandlers();
}

// event handler callbacks
function initHandlers() { 
  cnv.oncontextmenu = function ()      { return false; }
  cnv.onmousedown   = function (event) { mouseClickHandler(event); };
  cnv.onmouseup     = function (event) { mouseClickHandler(event); };
  cnv.onmousemove   = function (event) { mouseMoveHandler(event); };
  window.onkeydown  = function (event) { keyPressHandler(event); };
  window.onkeyup    = function (event) { keyPressHandler(event); };
  ws.onopen         = function ()      { console.log("Opened WebSocket "+wurl); ws.binaryType = "arraybuffer"; rfbRequest(); }
  ws.onclose        = function ()      { console.log("Closed WebSocket "+wurl); }
  ws.onmessage      = function (event) { rfbHandler(event); }
}

// input handlers
function mouseMoveHandler(event) {
  mouse.x = event.pageX - cnv.offsetLeft;
  mouse.y = event.pageY - cnv.offsetTop;
  ws.send("MM:x="+mouse.x+",y="+mouse.y);
}
function mouseClickHandler(event) {
  mouse.b = event.which;
  if (event.type == 'mouseup') mouse.b = -mouse.b;
  ws.send("MB:x="+mouse.x+",y="+mouse.y+",b="+mouse.b);
}
function keyPressHandler(event) {
  var keysym = event.which;
  if (event.type == 'keyup') keysym = -keysym;
  ws.send("KP:x="+mouse.x+",y="+mouse.y+",k="+keysym);
}

// update handlers
function rfbHandler(event) {
  var ival = new Uint16Array(event.data); 
  var x=ival[0], y=ival[1], w=ival[2], h=ival[3];
  if (w==0) { setTimeout(rfbRequest,50); return; }
  var bval = new Uint8ClampedArray(event.data,8,1024);
  imgd.data.set(bval);
  ctx.putImageData(imgd,x,y);
}
function rfbRequest() {
  ws.send("RU:");
}
