var CD3 = {};

CD3.Behaviors = (function(){
	function observe(element, event, observer){
		if (!Object.isFunction(observer)){
			observer = delegate(observer);
		}
		
		$(element).observe(event, observer);
	}
	
	function delegate(rules){
		return function(e){
			var element;
			for (var selector in rules){
				if (element = e.findElement(selector)){
					return rules[selector].call(this, e, element);
				}
			}
		}
	}
	
	return {
		assign: function(rules){
			for (var selector in rules) {
				var observer = rules[selector];
				selector.split(',').each(function(sel) {
					var parts	= sel.split(/:(?=[a-z]+$)/), 
						css 	= parts[0], 
						event	= parts[1];

					$$(css).each(function(element) {
						if (event) {
							observe(element, event, observer);
						} else if (Object.isFunction(observer)){
							observer.prototype.initialize ? new observer(element) : observer(element);
						} else {
							for(var e in observer){
								observe(element, e, observer[e]);
							}
						}	
					});
				});
			}
		}
	};
})();

CD3.Radio = Class.create({
	initialize: function(radio){
		this.radio	= $(radio).hide();
		this.name 	= this.radio.getAttribute('name') || this.radio.identify();
		this.button = new Element('a', {href:'javascript:;'}).update(' ');
		this.button.addClassName('radio');
		
		this.radio.insert({before: this.button});
		
		if (this.radio.className){
			this.button.addClassName(radio.className);
		}
		
		this.button.observe('click', this.toggle.bind(this));
		this.refresh();
		
		if (!CD3.Radio._elements[this.name]){
			CD3.Radio._elements[this.name] = [];
		}
		CD3.Radio._elements[this.name].push(this);
	},
	toggle: function(){
		this.radio.checked = !this.radio.checked;
		CD3.Radio._elements[this.name].invoke('refresh');
	},
	refresh: function(){
		this.button[this.radio.checked ? 'addClassName' : 'removeClassName']('selected');
	}
});

CD3.Radio._elements = {};

CD3.Dropdown = Class.create({
	initialize: function (container) {
		this.container	= $(container);
		this.link		= this.container.down('a.drop')
		this.div		= this.container.down('div').hide();
		this.ul			= this.container.down('ul');
		this.bindEvents();
	},
	bindEvents: function(){
		this.link.observe('click', this.toggle.bind(this)); 
		this.clickObserver = this.close.bind(this);
	},
	toggle: function(){
		this[this.div.visible() ? 'hide' : 'show']();
	},
	show: function(){ 
		Effect.BlindDown(this.div, {duration: 0.2});
		document.observe('click', this.clickObserver);
	},
	hide: function(){
		Effect.BlindUp(this.div, {duration: 0.1});
		document.stopObserving('click', this.clickObserver);
	},
	close: function(){
		if (this.div.visible()) this.hide();
	}
});

CD3.Select = Class.create(CD3.Dropdown, {
	initialize: function(select, options){ 
		select = $(select);
				
		this.container	= new Element('span');
		this.link 		= new Element('a', {href: 'javascript:;'})
		this.linkspan	= new Element('span').update(select.selectedIndex > -1 ? select.options[select.selectedIndex || 0].text : '');
		this.hidden		= new Element('input', {type: 'hidden', name: select.name, value: select.getValue()});
		this.div		= new Element('div').hide();
		this.ul			= new Element('ul');
		
		this.link.addClassName("drop")
		this.container.addClassName(select.className ? select.className + " dropper" : "dropper");
		
		select.insert({
			before: this.container
				.insert(this.link.insert(this.linkspan))
				.insert(this.hidden)
				.insert(this.div.insert(this.ul))
		});
		
		var options = Object.extend({
			onChange: 	null,
			topBottom:	false,
			scrollOn:	6
		}, options || {});
		
		if (options.topBottom){
			this.ul.insert({
				before: new Element('span', {'class': 'top'}).insert(new Element('span')),
				after: new Element('span', {'class': 'bottom'}).insert(new Element('span'))
			});
		}
		
		this.onChange = options.onChange;
		
		if ($A(select.options).each(this.addOption.bind(this)).length > options.scrollOn){
			this.div.addClassName('scrolled');
		}
		
		Element.remove(select);
		this.bindEvents();
	},
	addOption: function (option){
		this.ul.insert(new Element('li').insert(
			new Element('a', {href: 'javascript:;'}).update(option.text).observe('click', this.select.bind(this, option))
		));
	},
	removeOptions: function(){
		this.ul.select('li').each(function(li){
			li.down('a').stopObserving('click');
			li.remove();
		});
	},
	select: function(option){
		this.linkspan.innerHTML = option.text;
		this.hidden.value		= option.value != null ? option.value : option.text;
		this.hide();
		
		if (this.onChange){
			this.onChange.call(this, option.value);
		}
	}
});

CD3.Checkbox = Class.create({
	initialize: function(checkbox){
		this.checkbox = $(checkbox).hide();
		this.button = new Element('a', {href:'javascript:;'}).update(' ');
		this.button.addClassName('checkbox');
		this.checkbox.className && this.button.addClassName(checkbox.className);
		this.checkbox.insert({before: this.button});
		this.button.observe('click', this.click.bind(this));
		this.mark();
	},
	click: function(){
		this.checkbox.checked = !this.checkbox.checked;
		this.checkbox.fire('checkbox:click');
		this.mark();
	},
	mark: function(){
		this.button[this.checkbox.checked ? 'addClassName' : 'removeClassName']('selected');
	}
});

