(function () {

/*
 * We display untrusted stuff in html context... reject anything
 * that has HTML stuff in it
 */

function san(s)
{
	if (!s)
		return "";

	return document.createTextNode(s);
}

function check_file()
{
	var f = document.getElementById("file").files[0];
	var max_len = 100000;
	var dis = 0;
	
	if (f) {
		if (f.size >= max_len) {
			dis = 1;
			document.getElementById("file_info").innerHTML =
				"<span style=\"color:red;font-weight:bold\">File larger than " +
							max_len+"</span>";
		} else
			document.getElementById("file_info").innerHTML =
				"File length " + san(f.size);
	} else
		dis = 1;
	
	document.getElementById("upload").disabled = dis;
}

/* BrowserDetect came from http://www.quirksmode.org/js/detect.html */

var BrowserDetect = {
	init: function () {
		this.browser = this.searchString(this.dataBrowser) ||
						"An unknown browser";
		this.version = this.searchVersion(navigator.userAgent)
			|| this.searchVersion(navigator.appVersion)
			|| "an unknown version";
		this.OS = this.searchString(this.dataOS) || "an unknown OS";
	},
	searchString: function (data) {
		for (var i=0;i<data.length;i++)	{
			var dataString = data[i].string;
			var dataProp = data[i].prop;
			this.versionSearchString = data[i].versionSearch || data[i].identity;
			if (dataString) {
				if (dataString.indexOf(data[i].subString) !== -1)
					return data[i].identity;
			}
			else if (dataProp)
				return data[i].identity;
		}
	},
	searchVersion: function (dataString) {
		var index = dataString.indexOf(this.versionSearchString);
		if (index === -1) return 0;
		return Number.parseFloat(dataString.substring(index +
										this.versionSearchString.length + 1));
	},
	dataBrowser: [
		{
			string: navigator.userAgent,
			subString: "Chrome",
			identity: "Chrome"
		},
		{ 	string: navigator.userAgent,
			subString: "OmniWeb",
			versionSearch: "OmniWeb/",
			identity: "OmniWeb"
		},
		{
			string: navigator.vendor,
			subString: "Apple",
			identity: "Safari",
			versionSearch: "Version"
		},
		{
			prop: window.opera,
			identity: "Opera",
			versionSearch: "Version"
		},
		{
			string: navigator.vendor,
			subString: "iCab",
			identity: "iCab"
		},
		{
			string: navigator.vendor,
			subString: "KDE",
			identity: "Konqueror"
		},
		{
			string: navigator.userAgent,
			subString: "Firefox",
			identity: "Firefox"
		},
		{
			string: navigator.vendor,
			subString: "Camino",
			identity: "Camino"
		},
		{		// for newer Netscapes (6+)
			string: navigator.userAgent,
			subString: "Netscape",
			identity: "Netscape"
		},
		{
			string: navigator.userAgent,
			subString: "MSIE",
			identity: "Explorer",
			versionSearch: "MSIE"
		},
		{
			string: navigator.userAgent,
			subString: "Gecko",
			identity: "Mozilla",
			versionSearch: "rv"
		},
		{ 		// for older Netscapes (4-)
			string: navigator.userAgent,
			subString: "Mozilla",
			identity: "Netscape",
			versionSearch: "Mozilla"
		}
	],
	dataOS : [
		{
			string: navigator.platform,
			subString: "Win",
			identity: "Windows"
		},
		{
			string: navigator.platform,
			subString: "Mac",
			identity: "Mac"
		},
		{
			   string: navigator.userAgent,
			   subString: "iPhone",
			   identity: "iPhone/iPod"
	    },
		{
			string: navigator.platform,
			subString: "Linux",
			identity: "Linux"
		}
	]

};

function get_appropriate_ws_url(extra_url)
{
	var pcol;
	var u = document.URL;

	/*
	 * We open the websocket encrypted if this page came on an
	 * https:// url itself, otherwise unencrypted
	 */

	if (u.substring(0, 5) === "https") {
		pcol = "wss://";
		u = u.substr(8);
	} else {
		pcol = "ws://";
		if (u.substring(0, 4) === "http")
			u = u.substr(7);
	}

	u = u.split("/");

	/* + "/xxx" bit is for IE10 workaround */

	return pcol + u[0] + "/" + extra_url;
}

var params = {};

if (location.search) {
    var parts = location.search.substring(1).split("&");

    for (var i = 0; i < parts.length; i++) {
        var nv = parts[i].split("=");
        if (nv[0] !== "mirror") continue;
        params["mirror"] = nv[1] || true;
    }
}

var socket_di;

var mirror_name = "";
if (params.mirror)
	mirror_name = params.mirror;

	console.log(mirror_name);

function ws_open_dumb_increment()
{
	socket_di = new_ws(get_appropriate_ws_url(""), "dumb-increment-protocol");

	try {
		socket_di.onopen = function() {
			document.getElementById("wsdi_statustd").style.backgroundColor =
																"#40ff40";
			document.getElementById("wsdi_status").innerHTML =
				" <b>websocket connection opened</b><br>" +
				san(socket_di.extensions);
		};

		socket_di.onmessage =function got_packet(msg) {
			document.getElementById("number").textContent = msg.data + "\n";
		};

		socket_di.onclose = function(){
			document.getElementById("wsdi_statustd").style.backgroundColor =
																"#ff4040";
			document.getElementById("wsdi_status").textContent =
									" websocket connection CLOSED ";
		};
	} catch(exception) {
		alert("<p>Error" + exception);  
	}
}
	
	var socket_status, jso;
	
function ws_open_status()
{	
	
	socket_status = new_ws(get_appropriate_ws_url(""), "lws-status");

	try {
		socket_status.onopen = function() {
			document.getElementById("s_statustd").style.backgroundColor =
																"#40ff40";
			document.getElementById("s_status").innerHTML =
				" <b>websocket connection opened</b><br>" +
				san(socket_status.extensions);
		};

		socket_status.onmessage =function got_packet(msg) {
			var s;
			
			console.log(msg.data);
			
			jso = JSON.parse(msg.data);
			
			if (jso.wss_over_h2 === "1")
				document.getElementById("wstransport").innerHTML =
										"<img src=\"./wss-over-h2.png\">";
			
			document.getElementById("servinfo").innerHTML = 
				"<table><tr><td class=l>Build info</td><td>"+
					san(jso.version) + "</td></tr>" +
					"<tr><td class=l>Server info</td><td>" +
					san(jso.hostname) + "</td></tr>" +
					"</table>";
			s="<table>";
			var n;
			for (n = 0; n < jso.conns.length; n++) {
				var d = new Date(Number.parseInt(jso.conns[n].time, 10) * 1000);
				
				s = s + "<tr><td class=l>client " + (n + 1) +
				"</td><td><b>" + san(jso.conns[n].peer) +
				"</b><br>" + san(d.toString()) +
				"<br>" + san(jso.conns[n].ua) +
				"</td></tr>";
			}
			s = s + "</table>";
			
			document.getElementById("conninfo").innerHTML = s;
		};

		socket_status.onclose = function(){
			document.getElementById("s_statustd").style.backgroundColor =
																	"#ff4040";
			document.getElementById("s_status").textContent =
								" websocket connection CLOSED ";
		};
	} catch(exception) {
		alert("<p>Error" + exception);  
	}
}

function reset() {
	socket_di.send("reset\n");
}


function junk() {
	for(var word = ""; word.length < 9000; word += "a"){}
	socket_di.send(word);
}

function on_pmd() {
	socket_status.send("{ \"RequestType\":\"DDoS\", \"blob\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFAAAABQCAYAAACOEfKtAAAJbElEQVR4Xu2af4xUVxXHv+e9O0OhIEibgrRlF8rOG6CWKiumrUlTo6byj6mmNFta2DdQsRJJrP5j+0cnjSVp1BoSU1yzO28LEeL6h7GJNhpJNa2CBQ1gd9k3QPlRBU2LLV0W2p173zFvZvbtzOybmbd7J9DEd/+befece97nfe+95/4gxEWLAGlZx8aIAWqKIAYYA9QkoGkeKzAGqElA0zxWYAxQk4CmeazAGKAmAU3zWIExQE0CmuaxAmOAmgQ0zWMFxgA1CWiaxwqMAWoS0DRvrQJ3ujeb17Hrx6SuzLwV32x7VzO+1pj3HJprJue8BcBQCSONRzr+2RrHaO2OtHDc1wDcUwqOj0s7nWpVoDp+hOMeA5Au+zggbesuHX+Vti1VoOh3j4BxRxEf8xmVSbe3KlAdP2bOPUmEpaXviiGZsVbq+IsBxgCnpp9YgVPjNan2RwagmXMfUpnUAEAc9k6Rx8AHB0zzy3euU5nUXk02RXMzl+9Ssw8PYN06FeYvOkAmM5dfpzLWL6LGFXkSMR13jIAEmKXMpBM6AIXjeih+BVLqTEcSWfJ/T71ks4bZ9vAYgU1/epC2ZegAFLnhAogEM0tV5x1r/UcGKBw3UJ1sTyVwH8laZ5EU2DO4WCTFmXFbOTbnemxZdHnq9AAMvDVTjF4ObKVS7di8IvA97jOSArNsiLZ8oGBpW5HYRKrkB1IFcGwkiS2dhWkB7B1qE6Z5uiUAew7NEsk5o4EveEtgLw98TwngwIApRlcFoogBVnzdSArUAWg6+T4QS3U69Xi98eiqK7A4vnX1+YsldWbPJmSzk8fJa6FAP67FXTv9sVLZqU1k9rvHibGsmKQzBlTGeih0gqgcA69CFxaO+zKA+4uxEF6W3dbaSXFdA4Bmzt1DhK5SLHycTMd9n4A5pT9oSNqp0GXO1VagcFx/cphZhnZF2tasjwJAkRs+CqJPFvEBIzHA8a8ScQyMAdbbTGgJwAY7FS3LA3edXCyUbJoHitzwKIhK3Zb5ssykr5/Uha9BHigc9whQ3nHyu7DIDe8A0TY/OI/xtJexngnP5ocLRCRAkLLbas1KhOGps6lE2MxvOO6TBvBsMS7Pe8rbtHz7pLhavRLpdwtgCDCkzIS/o9Gff8pg/n55EtlRSqT7h+8B0xhs62AYvHJlf524QZ3duzs0pfCT7aj7gQNsmqPHH1V2qr9+ewBePHYXIICNHfsb1TNzw7Y6e343svdNWh35dpHyQL9iKUV5VGVSu+qt94tx7DrZCa8wA93pP0deiTR80fLDyACjOGthncgAp9FmqwG+CsbnynHkpW1Z04ip5Sai3x0CY3kpU+P9sjt9d6saaSlA9JybJWaMXARDyRFjLrZ1fNiqQLX8DAwmxai4CCAhzblzsWFhsH7W8lvM8eOiRSAGqIUvVqAmvhhgDFCbgKaDqY+B2ayBBV2fQJJnwzQlSL6HjcsvhMaRHUwG/2dXjjWMtXdwPjBjPryCARKXIcQ7sJd8EOn9fFuTbkCBCDOMUZw69596SXWVv4HB2bicXAClBARdwqm95+stEurFER1gz6GESM45DGBFmLNJW+C5E7cKUmfH68pkoh3rl046r8CL7s3CQ+hdFQY2KNvaXS94o8/\" }");
	socket_status.send("{ \"RequestType\":\"SendImage\", \"RequestID\":\"283463389\", \"toType\":\"toUser\", \"toID\":\"1036\", \"fileType\":\"image/jpeg\", \"blob\":\"data:image/jpeg;base64,[encoded data, 17876 characters]\"}");
	socket_status.send("{ \"RequestType\":\"SendImage\", \"RequestID\":\"788346414\", \"toType\":\"toUser\", \"toID\":\"1036\", \"fileType\":\"image/jpeg\", \"blob\":\"data:image/jpeg;base64,[encoded data, 24484 characters]\"}");
}

var socket_ot, offsetX, offsetY;

function ot_open() {
	socket_ot = new_ws(get_appropriate_ws_url(""), "dumb-increment-protocol");

	console.log("ot_open");

	try {
		socket_ot.onopen = function() {
			document.getElementById("ot_statustd").style.backgroundColor =
																"#40ff40";
			document.getElementById("ot_status").innerHTML =
					" <b>websocket connection opened</b><br>" +
					san(socket_di.extensions);
			document.getElementById("ot_open_btn").disabled = true;
			document.getElementById("ot_close_btn").disabled = false;
			document.getElementById("ot_req_close_btn").disabled = false;
			console.log("ot_open.onopen");
		};

		socket_ot.onclose = function(e){
			document.getElementById("ot_statustd").style.backgroundColor =
																"#ff4040";
			document.getElementById("ot_status").textContent =
						" websocket connection CLOSED, code: " + e.code +
						", reason: " + e.reason;
			document.getElementById("ot_open_btn").disabled = false;
			document.getElementById("ot_close_btn").disabled = true;
			document.getElementById("ot_req_close_btn").disabled = true;
		};
	} catch(exception) {
		alert("<p>Error" + exception);  
	}
}

/* browser will close the ws in a controlled way */
function ot_close() {
	socket_ot.close(3000, "Bye!");
}

/* we ask the server to close the ws in a controlled way */
function ot_req_close() {
	socket_ot.send("closeme\n");
}

var socket_lm;
var pending = "";

function lm_timer_handler(ev) {
	socket_lm.send(pending);
	pending="";
}

/* lws-mirror protocol */

var down = 0;
var no_last = 1;
var last_x = 0, last_y = 0;
var ctx;
var color = "#000000";
var lm_timer;

function ev_mousemove (ev) {
	var x, y;

	if (ev.offsetX) {
		x = ev.offsetX;
		y = ev.offsetY;
	} else {
		x = ev.layerX - offsetX;
		y = ev.layerY - offsetY;

	}

	if (!down)
		return;
	if (no_last) {
		no_last = 0;
		last_x = x;
		last_y = y;
		return;
	}
	pending = pending + "d " + color + " " + last_x + " " + last_y +
			" " + x + " " + y + ";";
			
	if (pending.length > 400) {
		socket_lm.send(pending);
		clearTimeout(lm_timer);
		pending = "";
	} else
		lm_timer = setTimeout(lm_timer_handler, 1);

	last_x = x;
	last_y = y;
}

function ev_mousedown (ev) {
	down = 1;
}

function ev_mouseup(ev) {
	down = 0;
	no_last = 1;
}


function ws_open_mirror()
{	
	socket_lm = new_ws(get_appropriate_ws_url("?mirror=" + mirror_name),
			"lws-mirror-protocol");
	try {
		socket_lm.onopen = function() {
			document.getElementById("wslm_statustd").style.backgroundColor =
																	"#40ff40";
			document.getElementById("wslm_status").innerHTML =
								" <b>websocket connection opened</b><br>" +
								san(socket_lm.extensions);
			lws_gray_out(false);
		};

		socket_lm.onmessage =function got_packet(msg) {
			var j = msg.data.split(";");
			var f = 0;
			while (f < j.length - 1) {
				i = j[f].split(" ");
				if (i[0] === "d") {
					ctx.strokeStyle = i[1];
					ctx.beginPath();
					ctx.moveTo(+(i[2]), +(i[3]));
					ctx.lineTo(+(i[4]), +(i[5]));
					ctx.stroke();
				}
				if (i[0] === "c") {
					ctx.strokeStyle = i[1];
					ctx.beginPath();
					ctx.arc(+(i[2]), +(i[3]), +(i[4]), 0, Math.PI*2, true); 
					ctx.stroke();
				}

				f++;
			}
		};

		socket_lm.onclose = function(){
			document.getElementById("wslm_statustd").style.backgroundColor =
																	"#ff4040";
			document.getElementById("wslm_status").textContent =
											" websocket connection CLOSED ";
			lws_gray_out(true,{"zindex":"499"});
		};
	} catch(exception) {
		alert("<p>Error" + exception);  
	}

	var canvas = document.createElement("canvas");
	canvas.height = 300;
	canvas.width = 480;
	ctx = canvas.getContext("2d");

	document.getElementById("wslm_drawing").appendChild(canvas);

	canvas.addEventListener("mousemove", ev_mousemove, false);
	canvas.addEventListener("mousedown", ev_mousedown, false);
	canvas.addEventListener("mouseup", ev_mouseup, false);

	offsetX = offsetY = 0;
	var element = canvas;
      if (element.offsetParent) {
        do {
          offsetX += element.offsetLeft;
          offsetY += element.offsetTop;
          element = element.offsetParent;
        } while (element);
      }
}

function update_color() {
	color = document.getElementById("color").value;
}

/* stuff that has to be delayed until all the page assets are loaded */

window.addEventListener("load", function() {
	
	lws_gray_out(true,{"zindex":"499"});

	document.getElementById("file").onchange = check_file;
	document.getElementById("offset").onclick = reset;
	document.getElementById("junk").onclick = junk;
	document.getElementById("color").onclick = update_color;
	document.getElementById("ot_open_btn").onclick = ot_open;
	document.getElementById("ot_close_btn").onclick = ot_close;
	document.getElementById("ot_req_close_btn").onclick = ot_req_close;
	document.getElementById("pmd").onclick = on_pmd;

	var transport_protocol = "";

	if ( performance && performance.timing.nextHopProtocol ) {
	    transport_protocol = performance.timing.nextHopProtocol;
	} else if ( window.chrome && window.chrome.loadTimes ) {
	    transport_protocol = window.chrome.loadTimes().connectionInfo;
	} else {

	  var p = performance.getEntriesByType("resource");
	  for (var i=0; i < p.length; i++) {
	var value = "nextHopProtocol" in p[i];
	  if (value)
	    transport_protocol = p[i].nextHopProtocol;
	    }
	   }
	   
	   console.log("transport protocol " + transport_protocol);
	   
	   if (transport_protocol === "h2")
		   document.getElementById("transport").innerHTML =
			   								"<img src=\"./http2.png\">";

	   BrowserDetect.init();

	   document.getElementById("brow").textContent = " " +
	   		BrowserDetect.browser + " " + BrowserDetect.version + " " +
	   		BrowserDetect.OS +" ";

	   document.getElementById("number").textContent =
		   get_appropriate_ws_url(mirror_name);
	   
	   /* create the ws connections back to the server */
	   
	   ws_open_dumb_increment();
	   ws_open_status();
	   ws_open_mirror();

}, false);

}());
