var CheckboxEnhancer = {	
	options: {
		check_all_suffix: "_check_all",
		uncheck_all_suffix: "_uncheck_all",
		check_all_wrapper_class: "check_all_wrapper"
	},
	em: new EventManager(),
	mo_started: false,	
	init: function() {
		if($$('table.index td, div.checkboxes_wrapper ul.checkbox_rows li, div.checkbox').length == 0) return;
		if($$('table.index td, div.checkboxes_wrapper ul.checkbox_rows li').length <= 100) { // if more than 100, don't enhance... too much overhead 		
			$$('table.index td, div.checkboxes_wrapper ul.checkbox_rows li').each(function(el) {
				if(el._overlay == undefined) {
					this._overlay(el);				
				}
				this.em.set(el._overlay, {
					mousedown: this.startMouseOver.bind(this, el._overlay)
				});
				this.em.start(el._overlay, 'mousedown');
			}, this);
			this.em.set(document.body, {
				mouseup: this.stopMouseOver.bind(this),
				mousedown: {action: this.stopSelect.bind(this), dispatch: false}
			});
			this.em.start(document.body);
		}
		$$('div.checkbox').each(function(el){
			if(el._overlay == undefined) {
				this._overlay(el);				
			}
			this.em.set(el._overlay, {
				mouseup: this.toggle.bind(this, el)
			});
			this.em.start(el._overlay, 'mouseup');
		}, this);
		$$('div.checkboxes_wrapper').each(function(wrap) {
			// add check all and uncheck all
			var check_all_id = wrap.identify() + this.options.check_all_suffix;
			var uncheck_all_id = wrap.identify() + this.options.uncheck_all_suffix;
			if($(check_all_id) == undefined) {
				var i = new Element("input", {id: check_all_id, type: "button", value: "Check All"});
				var j = new Element("input", {id: uncheck_all_id, type: "button", value: "Uncheck All"});
				var button_wrap = new Element("div", {"class":this.options.check_all_wrapper_class});
				button_wrap.insert(i);
				button_wrap.insert(j);				
				wrap.insert(button_wrap);
			}
			this.em.set(check_all_id, {click: {action: this.checkAll.bind(this, wrap), dispatch: true}});
			this.em.start(check_all_id);
			this.em.set(uncheck_all_id, {click: {action: this.uncheckAll.bind(this, wrap), dispatch: true}});
			this.em.start(uncheck_all_id);
		}, this)
	},
	toggle: function(row) {
		var func = (row.hasClassName('selected')) ? this.deselectRow : this.selectRow;
		func(row); // run on the current row		
	},
	startMouseOver: function(div) {
		if(this.mo_started) {
			return;
		}
		var row = div.up("tr, li");
		var func = (row.hasClassName('selected')) ? this.deselectRow : this.selectRow;
		func(row); // run on the current row		
		// observe siblings
		var rows = row.siblings();
		rows.each(function(sib_row) {
			var arr;
			if(sib_row.tagName.toLowerCase() == "tr") {
				arr = sib_row.select("td");
			} else {
				arr = [sib_row];
			}
			arr.each(function(el) {
				this.em.set(el._overlay, {
					mouseover: func.bind(this, sib_row)								
				});
				this.em.start(el._overlay, 'mouseover');
			}, this)
		}, this);
		this.mo_started = true;
	},
	stopMouseOver: function() {
		if (!this.mo_started) {
			return;
		}
		$$('td, div.checkboxes_wrapper ul li').each(function(el) {
			this.em.unset(el._overlay, 'mouseover');
		}, this);
		this.mo_started = false;
	},
	stopSelect: function(event) {
		if(Event.element(event).hasClassName('overlay')) {
			event.stop();
		}
	},
	selectRow: function(row) {
		row.down('input[type="checkbox"]').checked = true;
		row.addClassName('selected');
	},
	deselectRow: function(row) {
		row.down('input[type="checkbox"]').checked = false;
		row.removeClassName('selected');		
	},	
	_overlay: function(element) {
		element = $(element);
		var dimensions = element.getDimensions();
		var height = dimensions.height + 2;
		var width = dimensions.width + 1;	
		element._overlay = new Element("div", {"class":"overlay"});
		var outer_wrap = new Element("div");
		var inner_wrap = new Element("div");
		outer_wrap.setStyle({
			position: 'relative'
		});
		inner_wrap.setStyle({
			position: 'relative',
			paddingLeft: element.getStyle('paddingLeft'),
			paddingRight: element.getStyle('paddingRight'),
			paddingTop: element.getStyle('paddingTop'),
			paddingBottom: element.getStyle('paddingBottom')
		});
		element.setStyle({
			padding: '0'
		});								
		inner_wrap.update(element.innerHTML);
		outer_wrap.update(inner_wrap);
		element.update(outer_wrap);
		element._overlay.setStyle({
			position: 'absolute',
			top: '-1px',
			left: '-1px',
			height: height+"px",
			width: width+"px",
			zIndex: '1',
			cursor: 'pointer'
		});
		outer_wrap.insert({top: element._overlay});
		if(element.tagName.toLowerCase() == "td") {
			element.select('a, img.link').each(function(i){
				i.setStyle({
					zIndex: '2',
					position: 'relative'
				});
			});
		}	
	},
	checkAll: function(wrap) {
		wrap.select('li').each(function(el){
			this.selectRow(el);
		}, this)
	},
	uncheckAll: function(wrap) {
		wrap.select('li').each(function(el){
			this.deselectRow(el);
		}, this)		
	},
	reset: function() {
		this.em.unset();
		this.init();
	}	
}
Event.observe(window, "load", function() { CheckboxEnhancer.init(); });

