//load!
window.async = (function(){
	var jsonActions = {}, ret;
	ret = {
		setJSONAction: function(action, callback){
			jsonActions[action]=callback;
			return ret
		},
		request: function(options, events) {
			// figure out the options
			
			if ($type(options)=="element" && options.get("tag")=="form") {
				var o = {
					url: options.getProperty("action"),
					method: options.getProperty("method"),
					data: options
				};
				options = o
			}
			else if	($type(options)=="string") {
				options = {url:options};
			}
			options = options || {};
			if (!options.url) { throw "no url given. must specify a url parameter in the options"; }
			options.method = options.method || "post";
			
			var request = new Request(options);
			
			events = events || {};
			events.defaultComplete = function(body) {
				if (request.status>=400) {
					body = request.xhr.responseText;
					
					request.fireEvent("error", [body, request.status]);
				}
				var content_type = request.getHeader("content-type");
				if (content_type=='application/x-jsonaction')
					request.fireEvent("jsonAction", [body]);
				else if (content_type && content_type.test("^(text|application)/json$")) {
					try{ var j = JSON.decode(body,true); }
					catch(e){ return; /*invalid JSON string.*/ }
					request.fireEvent("json", [j, request.status]);
				}
				else if (content_type=="text/plain") {
					request.fireEvent("plain", [body, request.status]);
				}
				else
					request.fireEvent("html", [body, request.status]);
			};
			events.complete = events.complete || function(body) {
				request.fireEvent("defaultComplete", [body]);
			};
			
			events.defaultJsonAction = function(resp) {
				try{ var jsonObj = JSON.decode(resp,true); }
				catch(e){ alert(resp); return; }
				if(jsonObj && jsonObj.actions)
				{
					jsonObj.actions.each(function(action)
					{
						var methodName = action.method;
						if(jsonActions[methodName]) {
							jsonActions[methodName].run(action.params);
						}
						else {
							throw("no jsonaction <" + methodName + ">.");
						}
					});
				}
			};
			events.jsonAction = events.jsonAction || function(resp) {
				request.fireEvent("defaultJsonAction", [resp]);
			}
			
			request.addEvents(events);
			return request.send();
		}
	};
	return ret
})();

//login thingy
var handle_login, handle_logout;
handle_login = function() {
	var div=document.getElement(".header div.user");
	var form = div.getElement("form[name=login]");
	var err = form.getElement("div.error");
	var disappear;
	
	
	var idle = function(input) {
		var labeltext = form.getElement('label[for=' + input.get('id') + ']').get('text');
		input.addEvents({
			focus:function(ev) {
				if (this.idling) {
					this.set('value', '').removeClass('idle');
					try { this.set('type', this.idling); } catch(e) {}
				}
				this.idling=false
			}, 
			blur:function(ev) {
				if (this.get('value').length==0) {
					this.idling=this.get('type');
					try { // ie doesn't allow changing from password to other types
						this.set('type', 'text');
					} catch(e) {}
					this.set('value', labeltext).addClass('idle');
				}
			}
		});
		if (input.get('value')==labeltext) { //in case form contents carry over on reload
			input.set('value', '');
		}
		input.fireEvent('blur');
	};
	
	var userinput = form.getElement('input[name=username]');
	var passinput = form.getElement('input[name=password]');
	idle(userinput);
	idle(passinput);
	
	
	form.addEvent("submit", function(ev) {
		ev.stop();
		form.getElement("div.error").set("text", "").addClass("hidden");
		div.addClass("userloading");
		function fail(body, status) {
			err.removeClass('hidden');
			if(disappear) {
				clearTimeout(disappear);
			}
			div.removeClass("userloading").highlight("#CFA9AA");
			if(status==403) {
				err.set('text', body);
			}
			else {
				err.set('text', "" + status + " Error");
			}
			disappear = setTimeout(function() {
				if (Browser.Engine.trident && Browser.Engine.version<=4) { //ie6
					err.addClass('hidden').empty();
				}
				else{
					new Fx.Tween(err, {duration:1500, property:'opacity'}).addEvent('complete', function() {
						err.removeProperty('style').addClass('hidden').empty();
					}).start(0);
				}
			}, 5000);
		}
		var username = userinput.idling ? "" : userinput.get('value');
		/* To the particularly curious users of this site: I'm fully aware that this does nothing to stop replay attacks
		 * I'd gladly redirect logins to happen over TLS, but that would be a violation of the same-origin policy for
		 * asynchronous requests, which I'm not willing to give up. So if you're actually concerned, just browse the site
		 * over a secure connection. That's what https:// is for.
		 */
		async.request({
				url:'/user/'+escape(username)+'/salt',
				method:'get'
			},
			{
				success: function(body){
					async.request({
						url:form.get('action'),
						method:form.get('method'),
						data:{
							username: username,
							hpassword: passinput.idling ? "" : (body + passinput.get('value')).sha1()
						}
					}, {
						success: function(body) {
							div.removeClass("userloading").empty().set("html", body).highlight("#ABCFA9");
							setTimeout(handle_logout, 0)
						},
						error: fail
					});
				},				
				error: fail
			}
		);
	});
};

handle_logout = function() {
	var div=document.getElement(".header div.user");
	var form = div.getElement("form[name=logout]");
	form.addEvent("submit", function(ev) {
		ev.stop();
		div.addClass("userloading");
		async.request(form, {
			success:function(body) {
				div.removeClass("userloading").empty().set("html", body).highlight("#ABCFA9");
				setTimeout(handle_login, 0);
			},
			error:function(body, status) {
				div.removeClass("userloading").highlight("#CFA9AA");
				//TODO: unable to log out for some reason
			}
		});
	});
};

refreshLogin = function() {
	var div=document.getElement(".header div.user");
	async.request("/userbox", {
		'success':function(body){
			div.empty().set("html", body).highlight("#ABCFA9");
			handle_logout();
		},
		'error':function(body, status){
			if (status==403) {
				div.empty().set("html", body).highlight("#CFA9AA");
				handle_login();
			}
		}
	});
};

window.addEvent('domready', function(){
	var div=document.getElement(".header div.user");
	var login = div.getElement("form[name=login]");
	var logout = div.getElement("form[name=logout]");
	if (login)
		handle_login();
	if (logout)
		handle_logout();
});