function CreateXHR() {
	if (window.XMLHttpRequest) {
		return new XMLHttpRequest();
	} else if (window.ActiveXObject) {
		return new ActiveXObject("Microsoft.XMLHTTP");
	} else {
		alert("neither XMLHttpRequest or ActiveXObject found");
	}
}

var xhr = new CreateXHR();
var sign_xhr = new CreateXHR();
var verify_xhr = new CreateXHR();

steps = ["q", "p", "g", "x", "y"];

function handle_start(v) {
	//alert("foo")
	var n = document.createElement("li");
	var txt = document.createTextNode(v);
	n.appendChild(txt);
	var anode = document.createTextNode("0");
	n.appendChild(document.createTextNode(": "));
	n.appendChild(anode);
	n.appendChild(document.createTextNode(" attempts..."));
	document.getElementById("genlist").appendChild(n);
	//document.getElementById("genprog").lastChild.childNodes[2].data = "26"
	//alert(document.getElementById("genprog").lastChild.childNodes[2].data)
}

function handle_dot() {
	var anode = document.getElementById("genlist").lastChild.childNodes[2];
	var count = Number(anode.data);
	count += 1;
	// XXX: should I be changing .length as well?
	anode.data = String(count);
}

function handle_plus() {
	var n = document.getElementById("genlist").lastChild;
	n.appendChild(document.createTextNode(" done"));
}

progress_handlers = {
	".": handle_dot,
	"+": handle_plus
};

function handle_progress(chars) {
	for (i=0; i < chars.length; i++) {
		//document.getElementById("genprog").appendChild(document.createTextNode(i));
		progress_handlers[chars.charAt(i)]();
	}
}

function handle_done(v) {}

handlers = {
	"start": handle_start,
	"progress": handle_progress,
	"done": handle_done
};

function handle(name, value) {
	handlers[name](value);
}

var lineno = 0;
var keydata = null;
var pubkey = null;

function sccb(evt) {
	if (xhr.readyState == 3 || xhr.readyState == 4) {
		var lines = xhr.responseText.split("\n");
		var newlines = lines.slice(lineno, -1);
		lineno = lines.length-1;
		//var pelm = document.createElement("p");
		//pelm.appendChild(document.createTextNode(xhr.readyState))
		//pelm.appendChild(document.createTextNode(newlines.join("\n")))
		//document.getElementById("genprog").appendChild(pelm)
		for (i in newlines) {
			var d = eval("(" + newlines[i] + ")");
			handle(d["event"], d.value);
		}
		if (xhr.readyState == 4) {
			var kul = document.getElementById("keydlist");
			keydata = eval("(" + lines.slice(-1)[0] + ")");
			pubkey = eval("(" + lines.slice(-1)[0] + ")");
			delete pubkey.x;
			//kul.appendChild(document.createTextNode(lines.slice(-1)));
			for (key in keydata) {
				var li = document.createElement("li");
				var keycont = document.createElement("b");
				keycont.appendChild(document.createTextNode(key));
				li.appendChild(keycont);
				li.appendChild(document.createTextNode(": "));
				li.appendChild(document.createTextNode(keydata[key]));
				kul.appendChild(li);
			}
			document.getElementById("keyjson_private").appendChild(document.createTextNode(JSON.stringify(keydata)));
			//document.getElementById("keyjson").appendChild(document.createElement("br"))
			document.getElementById("keyjson_public").appendChild(document.createTextNode(JSON.stringify(pubkey)));
			document.getElementById("sigsubmit").disabled = false;
			document.getElementById("verify_submit").disabled = false;
		}
	}
	//alert(evt)
	//alert(xhr.readyState)
}

var pos = 0;

/*function progcb(ev) {
	//alert(ev.type)
	//alert(ev.namespaceURI)
	var tgt = ev.target;
	var oldpos = pos;
	pos = ev.position;
	//alert(ev.input.stringData)
	//alert("pos: " + pos + ", oldpos: " + oldpos + "rt: " + tgt.responseText);
	document.getElementById("genprog").appendChild(document.createTextNode(this.responseText));
}*/

/*function setup_handlers() {
	alert(document.implementation.hasFeature("Events", "2.0"));
	document.getElementById("signform").addEventListener("submit", sign, false);
}*/

function generate() {
	xhr.onreadystatechange = sccb;
	//xhr.onprogress = progcb
	//xhr.addEventListener("readystatechange", sccb, false)
	//xhr.addEventListener("progress", progcb, false)
	xhr.open("GET", "http://selene.tfkyle.dyndns.org/~kyle/Temp/dsa.php?action=generate");
	xhr.send(null);
}

function sign_rstatechange(ev) {
	if (sign_xhr.readyState == 4) {
		var signature = eval("(" + sign_xhr.responseText + ")");
		var li = document.createElement("li");
		var textcont = document.createElement("b");
		textcont.appendChild(document.createTextNode(signature.text));
		li.appendChild(textcont);
		li.appendChild(document.createTextNode(" : "));
		li.appendChild(document.createTextNode(JSON.stringify(signature.sig)));
		document.getElementById("sigs").appendChild(li);
	}
}

function sign() {
	//evt.preventDefault();
	sign_xhr.onreadystatechange = sign_rstatechange;
	sign_xhr.open("POST", "http://selene.tfkyle.dyndns.org/~kyle/Temp/dsa.php?action=sign");
	// set readystatechange again for IE, see http://en.wikipedia.org/wiki/XHR#Reusing_XMLHttpRequest_Object_in_IE
	sign_xhr.onreadystatechange = sign_rstatechange;
	text = document.getElementById("signtext").value;
	postdata = "text=" + encodeURIComponent(text) + "&keydata=" + encodeURIComponent(JSON.stringify(keydata));
	sign_xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
	sign_xhr.send(postdata);
}

function verify_rstatechange(ev) {
	if (verify_xhr.readyState == 4) {
		var valid = eval("(" + verify_xhr.responseText + ")")[0];
		alert(valid ? "valid" : "invalid");
	}
}

function verify() {
	verify_xhr.onreadystatechange = verify_rstatechange;
	verify_xhr.open("POST", "http://selene.tfkyle.dyndns.org/~kyle/Temp/dsa.php?action=verify");
	// set readystatechange again for IE, see http://en.wikipedia.org/wiki/XHR#Reusing_XMLHttpRequest_Object_in_IE
	verify_xhr.onreadystatechange = verify_rstatechange;
	text = document.getElementById("verify_text").value;
	sig = document.getElementById("verify_sig").value;
	postdata = "text=" + encodeURIComponent(text) + "&keydata=" + encodeURIComponent(JSON.stringify(pubkey)) + "&sig=" + encodeURIComponent(sig);
	verify_xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
	verify_xhr.send(postdata);
}
