// new browsers filter
if(document.getElementsByTagName)
onload = function(){ // (C) Andrea Giammarchi

	// assing tabindex and accesskey	
	function accesstab(input){
		input.accesskey = input.tabindex = ++accesskey;
		++tabindex;
	};

	// assign generic link properties
	function addLinkProperties(a){
		tab(a);
		a.href = "#";
		a.onclick = function(){
			var	ul = this.parentNode.getElementsByTagName("ul").item(0);
			ul.style.display = !!ul.style.display ? "" : "none";
			return false;
		};
		return a;
	};

	// append one or more elements into another
	// then return the "parent" element
	function append(parent, elements){
		if(elements.constructor !== Array)
			elements = [elements];
		for(var i = 0; i < elements.length; i++)
			parent.appendChild(elements[i]);
		return parent;
	};

	// create a list if there are errors or warnings
	function createList(message, obj){
		for(var	a, span, i = 0, key = "", list = [], tmp = []; i < obj.length; i++) {
			for(key in obj[i]) {
				span = node("span");
				span.innerHTML = obj[i][key];
				tmp.push(append(
					node("li"), [
						append(node("strong"), text(key)),
						span
					]
				));
			};
			a = addLinkProperties(append(node("a"), text(message.concat(i + 1))));
			list.push(append(node("li"),[a, append(node("ul"), tmp)]));
			tmp = [];
		};
		return append(node("ul"), list);
	};

	// perform the request using byteson
	function doRequest(oldtab){

		// just call the server side page
		// sending input string and adding just
		// one listener ( because I'm sure, this application will works "perfectly" :P )
		byteson.request("w3validator.php", inputuri.value, {

			// onload event
			load:function(obj, xhr){
				var	a, key = "";

				// remove the loading text
				resultlist.removeChild(resultlist.firstChild);

				// create a list with every key value ...
				for(key in obj) {

					// but not with Arrays (errors or warnings)
					if(obj[key].constructor !== Array) {
						append(
							resultlist,
							append(
								node("li"), [
									append(node("strong"), text(key)),
									append(node("span"), text(obj[key]))
								]
							)
						);
					};
				};

				// create last list with each error or each warning
				for(key in obj) {
					if(obj[key].constructor === Array && obj[key].length > 0) {
						a = addLinkProperties(append(node("a"), text(key)));
						append(
							resultlist,
							append(
								node("li"), [
									a,
									createList(key.replace(/list/, ' #'), obj[key])
								]
							)
						);
						a.onclick();
					};
				};

				// enable the form
				inputuri.disabled = senduri.disabled = false;

				// set old tabindex for next request
				// (correct tab navigation ready)
				tabindex = oldtab;
			}
		});
	};

	// create and return an element of specified type
	function node(type){return document.createElement(type)}; 

	// add tabindex property using global scpe tabindex integer value
	function tab(node){node.tabindex = ++tabindex};

	// create and return a text node with specified content
	function text(value){return document.createTextNode(value)};

	// internal global scope variables
	var	accesskey = 0,					// accesskey (WCAG ready ?)
		tabindex = 0,					// tabindex (tab navigation ready)
		output = document.getElementById("request"),	// div container
		form = node("form"),				// used form
		inputlabel = node("label"),			// label for input text
		inputuri = node("input"),			// input text
		sendlabel = node("label"),			// label for send button
		senduri = node("input"),			// send button
		resultlist = node("ul");			// result unordered list

	// assign accesskey, tabindex and other parameters for each input (in this case text and btn)
	accesstab(inputuri);
	inputuri.type = "text";
	inputuri.id = inputlabel["for"] = "userinput";
	// keyboard event listener (RETURN to perform the request)
	inputuri.onkeyup = function(evt){
		if(!evt)
			evt = window.event;
		if(!evt.wich)
			evt.wich = evt.keyCode;
		if(evt.wich === 13 && this.value.replace(/^\s*|\s*$/, '').length > 4)
			senduri.onclick();
	};
	
	accesstab(senduri);
	senduri.type = "button";
	senduri.id = sendlabel["for"] = "sendinput";
	senduri.value = "verify";
	// request function
	senduri.onclick = function(){
		var	newresult = node("ul");

		// disable the form
		inputuri.disabled = senduri.disabled = true;

		// blur this button
		senduri.blur();

		// remove precedent unordered list element and replace
		// replace them with a simple "loading response" message
		// inside a new unordered list element
		resultlist.parentNode.replaceChild(newresult, resultlist);

		// assign new ul element to global scope var (to change them on load)
		resultlist = newresult;
		append(resultlist, append(node("li"), text("loading response")));

		// perform the request with byteson
		doRequest(tabindex);
		return false;
	};
	
	// form should be disabled, by default
	// (the form doesn't degrade in this example)
	form.onsubmit = function(){return false};

	// create the output only for the first time
	output.replaceChild(
		append(
			form,									// the form
				append(
					node("fieldset"), [					// top fieldset
						append(
							node("legend"),				// and its legend
							text("W3 Validator")			// with its content
						),
						append(
							inputlabel,				// label for text input
							text("write a valid url address")	// and its content
						),
						inputuri,					// input text
						append(
							sendlabel,				// label for button
							text("verify W3 validator result")	// and its content
						),
						senduri						// send button
					]
				)
	), output.firstChild);

	// create result fieldset to show informations
	// append this fieldset after the precedent output
	append(
		output,
		append(
			node("fieldset"), [							// bottom fieldset
			append(
				node("legend"),							// and its legend
				text("W3 Response")						// with its content
			),
			resultlist								// and its unordered list
			]									// to show the result
		)
	);
};						// that's all
