Backbone.Template.engine = 'handlebars';

/* UI Widgets */

var Menu = Backbone.View.extend({
	widget: true,
	
	templates: {
		list: {
			el: 'menu',
			item: 'menu-item'
		},
		
		groups: ['item'],
		$: ['el', 'button']
	},
	
	properties: ['label', 'action', 'align'],
	
	initialize: function(options) {
		this.values = [];
		var children = (options.el) ? this.el.children || $_(this.el).children.get() : [];
		
		// get the action function from the menu
		if (typeof options.action == 'string') {
			this.action = _.bind(options.parent[options.action], options.parent);
		}
		
		this.action = this.action || options.action;
		this.align = options.align || 'bottomright';
		this.width = options.width;
		this.label = options.label;
		//this.disabled = options.disabled !== undefined;
		
		this.className = this.el && this.el.className;
		
		this.template('el');
		$_(this.el).addClass(this.className);
		
		// get the menu items from the children of the original element
		for (var i = 0, child; (child = children[i]); i++) {
			this.addItem({
				value: child.getAttribute('value'),
				name: child.innerHTML,
				image: child.getAttribute('image')
			});
		}
		
		if (this.el.parentNode.nodeName == 'GROUP') {
			var group = $(this.el.parentNode),
				type = group.attr('type') || 'horizontal',
				children = group.children();
			
			if (this.el == children[0]) {
				$(this.el).addClass('ui-' + type + '-first');
			} else if (this.el == _.last(children)) {
				group.before(children).remove();
				$(this.el).addClass('ui-' + type + '-last');
			} else {
				$(this.el).addClass('ui-' + type + '-middle');
			}
		}
		
		_.bindAll(this, 'pageClick', 'handleClick');
		
		$(this.menu).delegate('.ui-menu-item', 'click', this.handleClick);
	},
	
	addHeader: function(name) {
		this.template('header');
	},
	
	addItem: function(options) {
		if (typeof options.name != 'string') {
			options.name = options.name.innerHTML;
		}
		
		this.values.push(options.value);
		this.template('item', {name: options.name, image: options.image});
	},
	
	display: function() {
		if (this.$button.hasClass('disabled')) {
			return;
		}
		
		this.$button.addClass('active');
		// display the menu at the corrent position
		document.body.appendChild(this.menu);
		var offset = this.$button.offset();
		//this.menu.style.top = this.button.offsetHeight - parseInt(this.button.style.top) + 'px';
		this.menu.style.top = offset.top + 'px';
		this.menu.style.left = offset.left + 'px';
		this.menu.style.display = 'block';
		
		if (this.align == 'bottomleft') {
			this.menu.style.left = (-this.menu.offsetWidth + this.button.offsetWidth) + 'px';
		}
		
		if (this.align == 'bottomright') {
			this.menu.style.top = offset.top + this.button.offsetHeight + 'px';
		}
		
		$_(document).mousedown(this.pageClick);
		
		this.active = true;
	},
	
	hide: function() {
		this.$button.removeClass('active');
		this.menu.style.display = 'none';
		
		$_(document).unbind('mousedown', this.pageClick);
		
		this.active = false;
	},
	
	toggle: function() {
		return (this.active) ? this.hide() : this.display();
	},
	
	disable: function() {
		this.$button.addClass('disabled');
		this.disabled = true;
	},
	
	reset: function() {
		this.values = [];
		this.item = [];
		this.menu.innerHTML = '';
	},
	
	pageClick: function(e) {
		if (e.target == this.button) {
			return;
		}
		
		var $target = $_(e.target), $parents = $target.parents();
		
		if ($parents.index(this.button) != -1) {
			return;
		}
		
		if ($parents.index(this.menu) == -1) {
			this.hide();
		}
	},
	
	events: {
		'mousedown .ui-menu-button, .ui-menu': function(e) {
			e.preventDefault();
		},
		'click .ui-menu-button': 'toggle'
	},
	
	handleClick: function(e) {
		var item = $_(e.target).closest('.ui-menu-item')[0],
			i = _.indexOf(this.item, item);
		
		this.action(this.values[i], e.target, i);
		
		this.hide();
	}
});

Backbone.Template.auto('.ui-menu-widget', Menu);


var Button = Backbone.View.extend({
	isDown: false,
	
	initialize: function() {
		this.$el = $(this.el);
		if (this.el.hasAttribute('disabled')) {
			this.disable();
		}
		
		_.bindAll(this, 'up');
	},
	
	disable: function() {
		$_(this.el).addClass('disabled');
		this.disabled = true;
	},
	
	events: {
		'mousedown': 'down',
		'mouseleave': 'leave',
		'mouseenter': 'enter'
	},
	
	down: function(e) {
		e.preventDefault();
		if (this.disabled) {
			return;
		}
		
		this.isDown = true;
		this.$el.addClass('active');
		
		$(window).bind('mouseup.button', this.up);
	},
	
	up: function() {
		this.isDown = false;
		this.$el.removeClass('active');
		$(window).unbind('mouseup.button');
	},
	
	enter: function() {
		if (this.isDown) {
			this.$el.addClass('active');
		}
	},
	
	leave: function() {
		if (this.isDown) {
			$(this.el).removeClass('active');
		}
	}
});

Backbone.Template.auto( '.ui-button', Button );
