window.addEvent('domready', function() {
	error_console.init();
	global_nav.init();
});

Dialog = new Class({
	Implements: [Options, Events],
	
	options: {
		/*
		onShow: $empty,
		onHide: $empty,
		*/
		button: null
	},
	
	initialize: function(element, options) {
		this.setOptions(options);
		
		this.element = $(element);
		this.button = null;
		
		if(this.options.button) {
			this.button = $(this.options.button);
			this.button.addEvent('click', this.buttonClick.bindWithEvent(this));
		}
		
		if(this.options.close) {
			this.close_button = $(this.options.close);
			this.close_button.addEvent('click', this.hide.bind(this));
		}
		
		this.bound = {
			'mousedown': this.mouseDown.bindWithEvent(this),
			'keydown': this.keyDown.bindWithEvent(this)
		};
	},
	
	buttonClick: function(e) {
		if($(e.target) === this.button) {
			if(this.element.hasClass('hidden')) {
				this.show();
			} else {
				this.hide();
			}
		}
	},
	
	show: function() {
		document.addEvent('mousedown', this.bound.mousedown);
		document.addEvent('keydown', this.bound.keydown);
		
		this.element.removeClass('hidden');
		
		this.fireEvent('show');
	},
	
	hide: function() {
		document.removeEvent('mousedown', this.bound.mousedown);
		document.removeEvent('keydown', this.bound.keydown);
		
		this.element.addClass('hidden');
		
		this.fireEvent('hide');
	},
	
	mouseDown: function(e) {
		if(!e.rightClick && !this.cameThroughElement(e.target)) {
			this.hide();
		}
	},
	
	keyDown: function(e) {
		if(e.key === 'esc') {
			this.hide();
		}
	},
	
	cameThroughElement: function(target) {
		var t = $(target);
		
		do {
			if(t === this.element || t === this.button || t.className.search(/\btip-bubble\b/) > -1) {
				return true;
			}
			
			t = t.parentNode;
		} while(t !== null && t !== document);
		
		return false;
	}
})

ModalDialog = new Class({
	Extends: Dialog,
	
	initialize: function(options) {
		this.parent('modal-dialog', options);
	},
	
	show: function() {
		$('modal-pane').removeClass('hidden');
		$('modal-dialog').setStyle('visibility', 'hidden');
		
		this.parent();
		
		var width = $('modal-dialog').offsetWidth;
		var height = $('modal-dialog').offsetHeight;
		
		$('modal-dialog').setStyles({'margin-left': -width / 2, 'margin-top': -height / 2, visibility: 'visible'});
	},
	
	hide: function() {
		$('modal-pane').addClass('hidden');
		
		this.parent();
		
		$('modal-dialog').empty();
	}
});

Confirm = new Class({
	Extends: Dialog,
	
	options: {
		/*
		onOk: $empty,
		onCancel: $empty
		*/
	},
	
	initialize: function(container, message, ok_label, cancel_label, options) {
		var form_html = '<fieldset><h3>' + message + '</h3><input type="button" class="confirm-button" name="ok" value="' + ok_label + '"><input type="button" class="cancel-button" name="cancel" value="' + cancel_label + '"></fieldset>';
		
		this.form = new Element('form', {'class': 'confirm-form dialog'}).set('html', form_html);
		
		$(this.form.elements['ok']).addEvent('click', this.ok.bind(this));
		$(this.form.elements['cancel']).addEvent('click', this.cancel.bind(this));
		
		this.form.inject(container);
		
		this.parent(this.form, options);
		
		this.show();
	},
	
	ok: function() {
		this.hide();
		this.fireEvent('ok');
	},
	
	cancel: function() {
		this.hide();
		this.fireEvent('cancel');
	},
	
	hide: function() {
		this.parent();
		
		this.form.dispose();
	}
})

var error_console = {
	init: function() {
		this.dialog = new ModalDialog({onHide: this.hide.bind(this)});
	},
	
	add: function(summary, message, is_html) {
		var errors = $('modal-errors');
		
		html = is_html === true ? 'html' : 'text';
		
		if(errors === null) {
			var errors = new Element('ul', {id: 'modal-errors'}).inject('modal-dialog');
		}
		
		var msg = $defined(message) ? message : summary
		
		var message_box = new Element('li', {'class': 'error-message'}).inject(errors);
		var body = new Element('div', {'class': 'body ' + html}).set(html, msg).inject(message_box);
		
		if($defined(message)) {
			new Element('h3').set('text', summary).inject(message_box, 'top');
		}
		
		$('modal-dialog').addClass('errors');
		
		this.dialog.show();
	},
	
	hide: function() {
		$('modal-dialog').removeClass('errors');
	}
};

global_nav = {
	loggin_in: false,
	
	init: function() {
		if($('login-form')) {
			$('login-button').addEvent('click', this.showLoginForm.bind(this));
			$('try-again').addEvent('click', this.resetForm.bindWithEvent(this));
		}
		
		if($('language-flip')) {
			$('language-flip').addEvent('click', this.setLanguage.bindWithEvent(this, $('language-flip').getProperty('lang')));
		}
	},
	
	setLanguage: function(e, lang) {
		e.preventDefault();
		
		Cookie.write('django_language', lang, {path: '/'});
		location.reload();
	},
	
	resetForm: function(e) {
		e.preventDefault();
		
		$('login-form').removeClass('hidden');
		$('login-error').addClass('hidden');
		
		$('login-form')['name'].value = '';
		$('login-form')['pass'].value = '';
	},
	
	showLoginForm: function() {
		$('login-form').addEvent('submit', this.login.bindWithEvent(this));
		$('openid-button').addEvent('click', this.showOpenId.bind(this));
		
		$('login-button').addClass('hidden');
		$('signup-button').addClass('hidden');
		$('login-form').removeClass('hidden');
		
		$('or').addClass('hidden');
	},
	
	showOpenId: function() {
		$('login-regular').addClass('hidden');
		$('login-openid').removeClass('hidden');
	},
	
	login: function(e) {
		e.preventDefault();
		
		if(!$('login-openid').hasClass('hidden')) {
			// example: admin.users.playtheweb.org
			var openid = $('login-form')['openid'].value;
			
			if(openid.length > 0) {
				new Request.JAMM({url: '/login', 'onSuccess': this.openIdLogin.bind(this), 'onFailure': this.loginFailed.bind(this)}).POST({action: 'openid', openid: openid});
			}
		} else {
			var name = $('login-form')['name'].value;
			var pass = $('login-form')['pass'].value;
			
			if(name == '' || pass == '') {
				$('login-blank-message').removeClass('hidden');
				$('login-form').addClass('hidden');
				$('login-error').removeClass('hidden');
			} else {
				$('login-blank-message').addClass('hidden');
				
				var on_jamm_id = null;
				
				try {
					on_jamm_id = jamm.id;
				} catch(e) {}
				
				if(!this.loggin_in) {
					this.loggin_in = true;
					new Request.JAMM({url: '/login', 'onSuccess': this.loggedIn.bind(this), 'onFailure': this.loginFailed.bind(this)}).POST({name: name, pass: pass, on_jamm_id: on_jamm_id});
				}
			}
		}
	},
	
	loggedIn: function(data) {
		if(data.url !== null) {
			location = data.url;
		} else {
			location.reload();
		}
	},
	
	loginFailed: function(data) {
		this.loggin_in = false;
		$('login-error-message').set('html', data.message);
		$('login-form').addClass('hidden');
		$('login-error').removeClass('hidden');
	},
	
	openIdLogin: function(data) {
		location = data.url;
	}
}

Tip_Bubble = new Class({
	Implements: Options,
	
	options: {
		open_element: null,
		open_event: 'click',
		
		close_element: null,
		close_event: 'click',
		
		event: 'click',
		
		fade: true,
		
		custom_event: null
	},
	
	initialize: function(el, options) {
		this.setOptions(options);
		
		this.element = $(el);
		
		if(this.element === null) {
			return null;
		}
		
		this.bound = {
			'show': this.show.bind(this),
			'close': this.close.bind(this)
		}
		
		if(this.options.open_element) {
			this.open_el = $(this.options.open_element);
			this.open_el.addEvent(this.options.open_event, this.bound.show);
		}
		if(this.options.close_element) {
			this.close_el = $(this.options.close_element);
			this.close_el.addEvent(this.options.close_event, this.bound.close);
		}
		
		this.custom_event = this.options.custom_event;
		
		new Element('span', {'class': 'pointer'}).inject(this.element);
		
		var close = new Element('span', {'class': 'close'}).inject(this.element);
		close.addEvent('click', this.close.bind(this));
		
		if(this.options.fade) {
			this.element.fade('hide');
			this.element.removeClass('hidden');
		}
		
		return this;
	},
	
	show: function() {
		if(this.open_el) {
			this.open_el.removeEvent(this.options.open_event, this.bound.show);
		}
		
		this.element.fade('in');
	},
	
	close: function() {
		if(this.close_el) {
			this.close_el.removeEvent(this.options.close_event, this.bound.close);
		}
		
		this.element.dispose();
	}
});

Request.JAMM = new Class({
	Extends: Request.JSON,
	
	success: function(text) {
		this.response.json = JSON.decode(text, this.options.secure);
		this.onSuccess(this.response.json);
	},
	
	failure: function() {
		var response = JSON.decode(this.xhr.responseText, true);
		
		if(response && response.exception) {
			error_console.add(response.summary, response.message);
		} else {
			//if(this.status === 0)
			//	error_console.add('Fatal Error\n. Try again in 5 min.');
		}
		
		this.fireEvent('complete').fireEvent('failure', response);
	},
	
	onException: function(key, value) {
		error_console.add('Fatal Error\nUnable to set header: "' + key + ': ' + value + '".');
		this.onFailure();
	}
});
