var rSelectClass = Class.create();
rSelectClass.prototype = {
	//Properties
				
	//Constructor
	initialize: function(el, s) {
		this.items = [];				// array of list items
		this.el = null;					// <select class="rSelect">
		this.label = null;				// the label of our dropdown
		this.container = null;			// the container element
		this.ul = null;					// Generated UL mirroring the <select> box
		this.imask= null;				// iframe fix for IE
		this.s = {
			fixedWidth: true,					// set the width to the size of the original <select> box
			className: 'rSelectBox',			// Class name to apply to the <div> tag
			selectedClass: 'selected',			// Class name for the seleted item in the select box
			hoverClass: 'hover',				// Class name for the hover of the items in the list
			isMultiSelect: false,				// whether or not this is a multiple select box. It will look for the attribute multiple="multiple" on the select box
			defaultLabel: 'No Values Selected',	// Default value for when no options are selected in a multi-select box
			pxPerChar: 8						// Number of pixels to allow for each character in the label
		};
		for (var key in s) {
			this.s[key] = s[key];
		}
		
		this.el = el;
		Element.hide(this.el);
		if(this.el.attributes['multiple'] && (this.el.attributes['multiple'].value.toLowerCase() == "multiple" || this.el.attributes['multiple'].value.toLowerCase() == "true")){
			this.s.isMultiSelect = true;
		}
		this.container = document.createElement('div');
		Element.addClassName(this.container, this.s.className);
		if(this.el.className != ''){
			Element.addClassName(this.container, this.el.className);
		}
		
		this.ul = document.createElement('ul');
		
		this.label = document.createElement('div');
		var icon = document.createElement('span');
		Element.addClassName(icon, 'icon');
		this.label.appendChild(icon);
		
		Event.observe(this.ul, 'click', this.onClick.bind(this));
		Event.observe(this.ul, 'mouseover', this.onMouseOver.bind(this));
		Event.observe(this.label, 'click', this.clickLabel.bind(this));
		
		this.createElements();
		this.initializeOnBlur();
	},
	//Methods
	createElements: function() {
		
		var opts = this.el.getElementsByTagName('option');
		Element.addClassName(this.label, 'label');
		for (var i=0; i<opts.length; i++) {
			var itemvar = {};
			itemvar.value = opts[i].value;
			itemvar.el = opts[i];
			itemvar.selected = opts[i].selected;
			itemvar.text = opts[i].text;
			itemvar.li = document.createElement('li');
			if(itemvar.el.className != ''){
				Element.addClassName(itemvar.li, itemvar.el.className);
			}
			itemvar.a = document.createElement('a');
			itemvar.a.href = 'javascript:void(0);';
			itemvar.text = opts[i].text;
			if(this.s.isMultiSelect){
				itemvar.a.innerHTML = '<input type="checkbox" name="bleh" ' + ((itemvar.selected)? ' checked="checked"' : '' ) + '> ' + opts[i].text;
			}else{
				itemvar.a.innerHTML = opts[i].text;
			}
			itemvar.li.appendChild(itemvar.a);
			this.ul.appendChild(itemvar.li);
			this.items.push(itemvar);
			if (opts[i].selected) { // create our label element
				this.setLabel(opts[i].text);
			}
		}
		
		this.container.appendChild(this.label);
		this.container.appendChild(this.ul);
		DOM.insertAfter(this.container, this.el);
		
		var dims = Element.getDimensions(this.el);
		
		if (this.s.fixedWidth == true) {
			this.container.style.width = dims.width + 'px'; // set the width of the container
		}
		this.ul.style.width = dims.width + 'px'; // set the width of the UL to the width of the original <select>
		this.ul.style.width = dims.width + (dims.width-this.ul.offsetWidth) + 'px'; // reset the width of the UL, calculating border / padding
		
		var left = String(Position.cumulativeOffset(this.ul));
		left = Number(left.substring(0, left.indexOf(',')));
		left += Element.getDimensions(this.ul).width;
		if(Element.getDimensions(document.getElementsByTagName('body')[0]).width < left){
			this.ul.style.right = "0px";
		}
				
		var uldims = Element.getDimensions(this.ul);
		
		if (document.all) { 
			/* create an iFrame to fix IE bug */
			this.imask = document.createElement('iframe');
			this.imask.scrolling = 'no';
			this.imask.frameborder = '0';
			this.imask.style.display = 'none';
			this.imask.style.position = 'absolute';
			this.imask.style.marginTop = '-1';
			this.imask.style.width = uldims.width + 'px';
			this.imask.style.height = uldims.height + 'px';
			this.container.appendChild(this.imask);
			this.imask.style.top = this.ul.style.top;
			if(Element.getDimensions(document.getElementsByTagName('body')[0]).width < left){
				this.imask.style.right = "0px";
			}
		}	
		if(this.s.isMultiSelect){
			this.updateLabel();
		}
		this.hide();
	},
	
	clickLabel: function(e) {
		this.toggle();
		for (var i=0; i<this.items.length; i++) {
			Element.removeClassName(this.items[i].li, this.s.hoverClass);
			if (this.items[i].selected == true) {
				Element.addClassName(this.items[i].li, this.s.hoverClass);
				Element.addClassName(this.items[i].li, this.s.selectedClass);
			}
		}
		if (typeof(this.el.onclick) == 'function') {
			this.el.onclick();
		}
		if(!Element.visible(this.ul)){
			this.hide();
			if (typeof(this.el.onclose) == 'function') {
				this.el.onclose();
			}
			if (typeof(Event.fire) == 'function') {
				Event.fire(this.el, "close");
			}
		}
	},
	toggle: function() {
		if(Element.visible(this.ul)){
			this.hide();
		}else{
			this.show();
		}
	},
	hide: function() {
		Element.hide(this.ul);
		if (document.all) { 
			Element.hide(this.imask);
		}
	},
	show: function() {
		Element.show(this.ul);
		if (document.all) { 
			Element.show(this.imask);
		}
		var left = String(Position.cumulativeOffset(this.ul));
		left = Number(left.substring(0, left.indexOf(',')));
		left += Element.getDimensions(this.ul).width;
		if(Element.getDimensions(document.getElementsByTagName('body')[0]).width < left){
			this.ul.style.right = "0px";
		}
	},
	onClick: function(e) {
		var ele = Event.element(e);
		while(ele && ele != this.container){
			if(ele.tagName.toLowerCase() == 'a'){
				break;
			}
			ele = ele.parentNode;
		}
		if(ele.tagName.toLowerCase() != 'a'){
			return;
		}
		if(this.s.isMultiSelect){
			for (var i=0; i<this.items.length; i++) {
				if (this.items[i].a == ele) {
					if(this.items[i].selected == true){
						this.items[i].selected = false;
						this.items[i].el.selected = false;
						this.items[i].li.getElementsByTagName('input')[0].checked = false;
						Element.removeClassName(this.items[i].li, this.s.selectedClass);
					}else{
						Element.addClassName(this.items[i].li, this.s.selectedClass);
						this.items[i].el.selected = true;
						this.items[i].selected = true;
						this.items[i].li.getElementsByTagName('input')[0].checked = true;
					}
					this.updateLabel();
					break;
				}
			}
		}else{
			for (var i=0; i<this.items.length; i++) {
				if (this.items[i].a == ele) {
					//this.label.innerHTML = this.items[i].text; // set the label text
					this.setLabel(this.items[i].text);
					Element.addClassName(this.items[i].li, this.s.hoverClass);
					Element.addClassName(this.items[i].li, this.s.selectedClass);
					this.items[i].selected = true;
					//alert (this.el+' '+i);
					this.el.selectedIndex = i; // update the selectedIndex on our original <select> box
				}
				else {
					this.items[i].selected = false;
					Element.removeClassName(this.items[i].li, this.s.hoverClass);
					Element.removeClassName(this.items[i].li, this.s.selectedClass);
				}
			}
			this.hide();
		}
		if (typeof(this.el.onclick) == 'function') {
			this.el.onclick();
		}
		if (typeof(this.el.onchange) == 'function') {
			this.el.onchange();
		}
		if (typeof(Event.fire) == 'function') {
			Event.fire(this.el, "change");
		}
	},
	onMouseOver: function (e) {
		var ele = Event.element(e);
		if(ele.tagName.toLowerCase() != 'a' && ele.tagName.toLowerCase() != 'li'){
			return;
		}
		for (var i=0; i<this.items.length; i++) {
			Element.removeClassName(this.items[i].li, this.s.hoverClass);
			if (this.items[i].a == ele) {
				Element.addClassName(this.items[i].li, this.s.hoverClass);
			}
		}
	},
	initializeOnBlur: function() {
		Event.observe(document.body, 'click', this.onBlur.bind(this), false);
		Event.observe(window, 'blur', this.onBlur.bind(this), false);
	},
	onBlur: function (e) {
		var el = Event.element(e);
		var found = false;
		do {
			if (el == null || el == window || el == document.body) break;
			if(el == this.container){
				found = true;
				break;
			}
		} while(el = el.parentNode);
		if(!found && Element.visible(this.ul)){
			this.hide();
			if (typeof(this.el.onclose) == 'function') {
				this.el.onclose();
			}
			if (typeof(Event.fire) == 'function') {
				Event.fire(this.el, "close");
			}
		}
	},
	updateLabel: function() {
		var selectedItems = [];
		for(var x=0; x<this.items.length; x++){
			if(this.items[x].selected){
				selectedItems.push(this.items[x].text);
			}
		}
		text = selectedItems.join(', ');
		if(text == ''){
			text = this.s.defaultLabel;
		}
		var dims = Element.getDimensions(this.label);
		short = text.substring(0, Math.round(dims.width/this.s.pxPerChar));
		if(short != text){
			text = short + '&hellip;';
		}
		this.setLabel(text);
	},
	setLabel: function(text) {
		if (this.label.firstChild.nodeType == 1) { // element node
			this.label.innerHTML = text + this.label.innerHTML;
		}
		else { // text node
			this.label.innerHTML = text + this.label.innerHTML.substring(this.label.innerHTML.indexOf('<'));
		}
	}
}


//instantiate and use the object
EventSelectors.register({
	'select.rSelect' : function(el) {
		new rSelectClass (el, {
		});
	},
	'select.rSelectSmall' : function(el) {
		new rSelectClass (el, {
			fixedWidth: false,
			className: 'rSelectBoxSmall'
		});
	}
}, true);

