var messageStack = stdClass.extend({
	//constructor
	constructor: function(el, settings) {
		this.base();
		// initialize settings
		Object.extend(this.s, {
			timer: null,
			waitTime: 10000,
			effectTime: 5000,
			closeSelector: ".close"
			/* put extensions to collections here */
		});
		
		// initialize nodes
		Object.extend(this.n, {
			el: el,
			childEl: [],
			tempContainer: document.createElement('div')
			/* put extensions to nodes here */
		});
		
		// initialize collections
		Object.extend(this.c, {
			messageFunctions: {
				success: this.successMessage.bind(this),
				error: this.errorMessage.bind(this)
			}
			/* put extensions to collections here */
		});
		var eles = this.n.el.getElementsBySelector('ul');
		
		for(var x=0; x<eles.length; x++){
			var childEl = {
				el: eles[x],
				timer: null
			}
			this.startTimer(childEl);
			this._attachEvents(childEl);
		}
	},
	closeClicked: function(childEl){
		this.removeMessage(childEl);
	},
	addMessage: function(message, type){
		if(!this.n.el){
			return;
		}
		if(typeof(this.c.messageFunctions[type]) == "function"){
			var html = this.c.messageFunctions[type](message);
		}else{
			return;
		}
		
		this.n.tempContainer.innerHTML = html;
		var childEl = {
			el:this.n.tempContainer.firstChild,
			timer:null
		}
		this.n.el.appendChild(childEl.el);
		this._attachEvents(childEl);
		Element.show(this.n.el);
		if(window.Effect){
			Effect.BlindDown(childEl.el,{
				duration: (this.s.effectTime/1000),
				afterFinishInternal: function(effect) {
					effect.element.undoClipping();
					effect.element.style.height = '';
				}
			});
		}else{
			Element.show(childEl.el);
		}
		this.startTimer(childEl);
	},
	removeMessage: function(childEl) {
		this.endTimer(childEl);
		if(window.Effect){
			Effect.Fade(childEl.el, {
				duration: (this.s.effectTime/1000)
			});
			/*Effect.BlindUp(childEl.el,{
				duration: (this.s.effectTime/1000),
				afterFinishInternal: function(effect) {
					effect.element.undoClipping();
					effect.element.style.height = '';
					Element.hide(effect.element);
				}
			});*/
		}else{
			Element.hide(this.n.el);
		}
	},
	startTimer: function(childEl) {
		this.endTimer(childEl);
		this.s.timer = setTimeout(this.removeMessage.bind(this, childEl), this.s.waitTime);
	},
	endTimer: function(childEl) {
		if(childEl.timer != null){
			clearTimeout(childEl.timer);
			childEl.timer = null;
		}
	},
	successMessage: function(message){
		var html = '<ul class="success">';
		html += '<li class="title">Success</li>';
		html += '<li>' + message + '</li>';
		html += '</ul>';
		return html;
	},
	errorMessage: function(message){
		var html = '<ul class="error">';
		html += '<li class="title">Error</li>';
		html += '<li>' + message + '</li>';
		html += '<li class="close">Close me</li>';
		html += '</ul>';
		return html;
	},
	_attachEvents: function(childEl) {
		var eles = document.getElementsBySelector(this.s.closeSelector, (childEl.el||this.n.el));
		for(var x=0; x<eles.length; x++){
			this.eObserve(eles[x], 'click', this.closeClicked.bind(this, childEl));
		}
	}
});
Behaviour.register({
	'#messagestack' : function(el){
		new messageStack (el);
	}
});var aStarRatings = stdClass.extend({
	//constructor
	constructor: function(el, settings) {
		this.base();
		// initialize settings
		Object.extend(this.s, {
			//moduleName: null,
			//2007.06.19 13:11:11-AV
			moduleName: 'AddRating',
			json: {
				ver: '0.1',
				meta: {},
				data: {
					requests: []
				}
			},
			ulSelector: 'ul.rateable',
			starSelector: 'a',
			ratingTextSelector: '.rating_text',
			currentRatingSelector: '.current-rating',

			//2007.06.19 13:51:11-AV
			uniqueID: null,
			type: null
			/* put extensions to collections here */
		});
		Object.extend(this.s, settings);
		// initialize nodes
		Object.extend(this.n, {
			container: el,
			ul: null,
			stars: [],
			ratingText: null,
			currentRating: null,
			jsonNode: document.createElement('div')
			/* put extensions to nodes here */
		});

		// initialize collections
		Object.extend(this.c, {
			requests: []
			/* put extensions to collections here */
		});
		this.parseClasses(this.n.container, true);
		/*if(!this.n.container.vars){
			alert('You need to add the class of "vars:{moduleName:theNameOfModule}" to your container!');
			return;
		}*/
		if(this.n.container.vars && this.n.container.vars.moduleName != ""){
			this.s.moduleName = this.n.container.vars.moduleName;
		}

		this._findElements();

	},
	starClicked: function(e, el){
		Event.stop(e);
		this.addRequest("changeRating", {
			newRating: el.vars.stars,
			uniqueID: this.n.ul.vars.uniqueID,
			type: this.n.ul.vars.type
		});
		this.JsonOut();

	},
	parseClasses: function(el, parseChildren){
		var classes = String(el.className).split(" ");
		var keepClasses = [];
		for(var x=0; x<classes.length; x++){
			if(classes[x].indexOf(':') != -1){
				var matches = classes[x].match(/^(\w*):{1,2}\{(.*)\}$/);
				var ob = {};
				var vars = matches[2].split(",");
				for(var y=0; y<vars.length; y++){
					vars[y] = vars[y].split(/::?/);
					if(!vars[y][1]) vars[y][1] = '';
					ob[vars[y][0]] = vars[y][1];
				}
				el[matches[1]] = ob;
			}else{
				keepClasses.push(classes[x]);
			}
		}
		el.className = keepClasses.join(" ");
		if(parseChildren){
			var eles = el.getElementsByTagName('*');
			for(var x=0; x<eles.length; x++){
				this.parseClasses(eles[x]);
			}
		}
	},
	addRequest: function(requestName, dataObject) {
		this.c.requests.push({
			id: this.c.requests.length,
			type: requestName,
			data: dataObject
		});
	},
	//json methods
	JsonOut: function() {
		//construct the post
		this.s.json.data.requests = this.c.requests;
		//this.setMeta('columns', '');
		var data = '__json=' + this.s.moduleName + '&data=' + Object.toJSON(this.s.json);
		this.c.requests = [];
		//send out the request
		if(this.s.moduleName == ''){


			//2007.06.19 13:02:22-AV Commented this out because it is using the old output
			//var returnData = '{"meta":{},"data":{"html":"<div class=\'rating vars:{moduleName:AdminModule__rating}\'><ul class=\'rateable floatleft vars:{uniqueID=51820}\'><li class=\'current-rating\' style=\'width: ' + (this.s.json.data.requests[0].data.newRating*16) + 'px;\'> </li><li><a href=\'javascript:void(0)\' title=\'1 star\' class=\'one-star vars:{stars:1}\'>1</a></li><li><a href=\'javascript:void(0)\' title=\'2 stars\' class=\'two-stars vars:{stars:2}\'>2</a></li><li><a href=\'javascript:void(0)\' title=\'3 stars\' class=\'three-stars vars:{stars:3}\'>3</a></li><li><a href=\'javascript:void(0)\' title=\'4 stars\' class=\'four-stars vars:{stars:4}\'>4</a></li><li><a href=\'javascript:void(0)\' title=\'5 stars\' class=\'five-stars vars:{stars:5}\'>5</a></li></ul><span class=\'rating_text\'>' + this.s.json.data.requests[0].data.newRating + '/5</span></div>"},"responses":[{"id":1,"type":"changeRating","data":{"success":"true"}}]}';

			var returnData = '{"meta":{},"data":{"html":"<div class=\'rating vars:{moduleName:AdminModule__rating}\'><ul class=\'rateable floatleft vars:{uniqueID=51820}\'><li class=\'current-rating\' style=\'width: ' + (this.s.json.data.requests[0].data.newRating*16) + 'px;\'> </li><li><a href=\'javascript:void(0)\' title=\'1 star\' class=\'one-star vars:{stars:1}\'>1</a></li><li><a href=\'javascript:void(0)\' title=\'2 stars\' class=\'two-stars vars:{stars:2}\'>2</a></li><li><a href=\'javascript:void(0)\' title=\'3 stars\' class=\'three-stars vars:{stars:3}\'>3</a></li><li><a href=\'javascript:void(0)\' title=\'4 stars\' class=\'four-stars vars:{stars:4}\'>4</a></li><li><a href=\'javascript:void(0)\' title=\'5 stars\' class=\'five-stars vars:{stars:5}\'>5</a></li></ul><span class=\'rating_text\'>' + this.s.json.data.requests[0].data.newRating + '/5</span></div>"},"responses":[{"id":1,"type":"changeRating","data":{"success":"true"}}]}';


			this.JsonIn({responseText:returnData});
		}else{
			var myAjax = new Ajax.Request(window.location,
			{
				method: 'post',
				parameters: data,
				onSuccess: this.JsonIn.bind(this)
			});
		}
	},

	JsonIn: function(t) {
		//alert(t.responseText);
		var result = t.responseText.evalJSON();
		(result.responses.length).times(function(i) {
			if(result.responses[i].type == 'changeRating'){
				this.n.jsonNode.innerHTML = result.data.html;
				//alert(this.n.jsonNode.innerHTML);
				// 2007.06.13 14:53:44-AV If you need to show ratings text, uncomment this
				//this.n.ratingText.innerHTML = document.getElementsBySelector(this.s.ratingTextSelector, this.n.jsonNode)[0].innerHTML;
				//alert(this.s.currentRatingSelector);
				//alert(document.getElementsBySelector(this.s.currentRatingSelector, this.n.jsonNode)[0].style.width);
				//debugger;
				this.n.currentRating.style.width = document.getElementsBySelector(this.s.currentRatingSelector, this.n.jsonNode)[0].style.width;
				this._startScripts(this.n.container);
				var stars = document.getElementsBySelector(this.s.starSelector, this.n.ul);

				for(var x=0; x<stars.length; x++){
					stars[x].blur();
				}
			}
		}.bind(this));
	},
	_startScripts: function(el) {
		//empty for now...
	},
	_findElements: function(){

		this.n.ul = document.getElementsBySelector(this.s.ulSelector, this.n.container)[0];
		if(!this.n.ul){
			return;
		}
		this.n.currentRating = document.getElementsBySelector(this.s.currentRatingSelector, this.n.container)[0];
		var stars = document.getElementsBySelector(this.s.starSelector, this.n.ul);

		this.n.stars = [];

		for(var x=0; x<stars.length; x++){
			this.eObserve(stars[x], 'click', this.starClicked.bindAsEventListener(this, stars[x]));
			this.n.stars.push(stars[x]);
		}
		this.n.ratingText = document.getElementsBySelector(this.s.ratingTextSelector, this.n.container)[0];
	}
});
EventSelectors.register({
	'.rating': function(el, index) {
		new aStarRatings(el, {
			moduleName: 'AddRating'
		});
	}
}, true);var Favorites = stdClass.extend({
	//constructor
	constructor: function(el, settings) {
		this.base();
		// initialize settings
		Object.extend(this.s, {
			moduleName: 'AddBookmark',
			json: {
				ver: '0.1',
				meta: {},
				data: {
					requests: []
				}
			},
			uniqueID: null,
			type: null
			/* put extensions to collections here */
		});
		
		// initialize nodes
		Object.extend(this.n, {
			el: el,
			link: null,
			links: null,
			linkSpans: null
			/* put extensions to nodes here */
		});
		
		// initialize collections
		Object.extend(this.c, {
			requests: []
			/* put extensions to collections here */
		});
		
		this._addEvents();
		
		// Get query params
		var args = this.n.el.href.substr(this.n.el.href.indexOf('?')+1);
		// Split using the &
		if (args != "#")
		{
			args = args.split("&");
			
			for(var x=0; x<args.length; x++){
				kv = args[x].split("=");
				if (kv[0] == "type")
					this.s.type = kv[1];
				
				if (kv[0] == "id")
					this.s.uniqueID = kv[1]
			}
		}
	},
	
	linkOnClick: function(e){		
		Event.stop(e);
		if(Element.hasClassName(this.n.el, 'bookmark_add')){
			this.addRequest("addFavorites", {
				uniqueID: this.s.uniqueID,
				type: this.s.type
			});
			this.JsonOut();
		}else if(Element.hasClassName(this.n.el, 'bookmark_remove')){
			this.addRequest("removeFavorites", {
				uniqueID: this.s.uniqueID,
				type: this.s.type
			});
			this.JsonOut();
		}
	},
	
	addRequest: function(requestName, dataObject) {
		this.c.requests.push({
			id: this.c.requests.length,
			type: requestName,
			data: dataObject
		});
	},
	
	//json methods
	JsonOut: function() {
		//construct the post
		this.s.json.data.requests = this.c.requests;
		var data = '__json=' + this.s.moduleName + '&data=' + Object.toJSON(this.s.json);
		this.c.requests = [];
		var myAjax = new Ajax.Request(window.location,
		{
			method: 'post',
			parameters: data,
			onSuccess: this.JsonIn.bind(this)
		});
	},
	
	JsonIn: function(t) {
		var result = t.responseText.evalJSON();
		(result.responses.length).times(function(i) {
			if(result.responses[i].type == 'addFavorites'){
				var newLink = result.data.html.toDOMNodes()[0];
				DOM.replace(this.n.el, newLink);
				this.n.el = newLink;
			}else if(result.responses[i].type == 'showMessage'){
				new kDialog2({
					'+zones': {
						heading: result.responses[i].data.headline,
						text: result.responses[i].data.html
					},
					position: {  
						exemplarAnchor: 'bottom right',
						selfAnchor: 'top right',
						exemplar: this.n.el,
						offsetY: 0,
						offsetX: 0
					},
					groupId: 'showMessage',
					groupLimit: 1,
					startHidden: false
				});
			}
		}.bind(this));
	},
	
	_addEvents: function() {
		// Bind the a element to listen for the click event
		this.eObserve(this.n.el, 'click', this.linkOnClick.bindAsEventListener(this));
	}
});

EventSelectors.register({
	'.bookmark_add': function(el, index) {
		new Favorites(el);
	}
}, true);
var Share = stdClass.extend({
	//constructor
	constructor: function(el, settings) {
		this.base();
		// initialize settings
		Object.extend(this.s, {
			moduleName: 'Share',
			ceid: null,
			json: {
				ver: '0.1',
				meta: {},
				data: {},
				requests: []
			}
			/* put extensions to collections here */
		});
		
		// initialize nodes
		Object.extend(this.n, {
			el: el,
			form: null,
			vars: [],
			submitButton: null,
			dialog: null
			/* put extensions to nodes here */
		});
		
		// initialize collections
		Object.extend(this.c, {
			requests: []
			/* put extensions to collections here */
		});
		this._attachEvents();

	},
	
	elOnClick: function(e) {
		Event.stop(e);
		
		//Get variables from URL
		urlsplit = this.n.el.href.split('?');
		var vars = urlsplit[1].split("&");
	  	for (var i=0;i<vars.length;i++) {
	   		var pair = vars[i].split("=");
	    	if (pair[0] == 'ceID') {
				ceIDvalue = pair[1];
			}
	    	if (pair[0] == 'url') {
				urlvalue = pair[1];
			}
	    	if (pair[0] == 'title') {
				titlevalue = pair[1];
			}						
	    } 
		
		
		var shareFormDialog = new FormDialog({
			'+zones': {
				heading: 'Loading...',
				text: 'Loading...'
			},
			position: {  
				exemplarAnchor: 'bottom right',
				selfAnchor: 'top right',
				exemplar: this.n.el,
				offsetY: -200,
				offsetX: -100
			},
			groupId: 'InviteDialogs',
			groupLimit: 1,
			startHidden: true,
			moduleName: this.s.moduleName,
			parentThis: this,
			ceID: this.s.ceid,
			params: {
				url: urlvalue,
				ceID: ceIDvalue,
				title: titlevalue
			}
		});
	},
	_attachEvents: function() {
		this.eObserve(this.n.el, 'click', this.elOnClick.bind(this));
	}
	
});

EventSelectors.register({
	'a.share': function(el, index) {
		new Share(el);
	}
}, true);
/**
 * rSelect
 * @version 1.6
 * @requires prototype.js
 * @requires prototype_ss.js
 * @requires DOM.js
 * @requires EventSelectors.js
 **/

var rSelectClass = Class.create();
rSelectClass.prototype = {

	//Constructor
	initialize: function(el, s) {
		this.items = [];									// array of list items
		this.el = el;										// <select class="rSelect">
		this.label = document.createElement('div');			// the label of our dropdown
		this.labelText = document.createElement('span');	// the text node inside our label
		this.container = document.createElement('div');		// the container element
		this.ulcontainer = document.createElement('div');	// Generated UL mirroring the <select> box
		this.imask = document.createElement('iframe');		// iframe fix for IE
		this.actualCols = 0;								// Actual number of columns that get created
		this.ulInit = false;								// Keeps track of if ul is initialized
		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
			toggleClass: 'toggle',				// Class name for the toggle all 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: 'Select from your PeopleMarks',	// Default value for when no options are selected in a multi-select box
			pxPerChar: 7,						// Number of pixels to allow for each character in the label
			maxHeight: 300,						// Maximum height of the dropdown for multi selects
			maxCols: 1,							// Maximum number of columns - will be fewer colums if fewer fit in maxHeight
			pxPerRow: 22,						// Number of pixels to allow for each row
			processed: 'rSelectReplaced',        // Flag to tell whether a select has been processed yet
			width: null
		};
		for (var key in s) {
			this.s[key] = s[key];
		}
		if(this.s.fixedWidth){
			this.s.width = this.el.style.width? parseInt(this.el.style.width) : Element.getDimensions(this.el).width
		}
		
		if(this.el.hasClassName(this.s.processed)) {
			return 0;
		}
		Element.addClassName(this.el, this.s.processed);
		
		var multi = (this.el.attributes['multiple']) ? this.el.attributes['multiple'].value : this.el.getAttribute('multiple');
		if (multi && (multi.toLowerCase() == "multiple" || multi.toLowerCase() == "true")){
			this.s.isMultiSelect = true;
		}
		
		Element.addClassName(this.container, this.s.className);
		if(this.el.className != ''){
			Element.addClassName(this.container, this.el.className);
		}
		
		/* Event observers */
		Event.observe(this.label, 'click', this.clickLabel.bind(this));
		
		this.createContainer();
		Element.hide(this.el);
	},
	//Methods
	findElements: function() {
		var alleles = this.el.childNodes;
		var eles = new Array();
		var totalEles = 0;
		var makeSelected = false;
		var currentRow = 0;
		var ul = document.createElement('ul');
		
		// add top level <option> and <optgroups> to eles, and count all rows (totalEles) that will get outputted
		for (var i=0; i<alleles.length; i++) {
			switch (String(alleles[i].tagName).toLowerCase()) {
				case 'optgroup':
					eles.push(alleles[i]);
					var opts = alleles[i].getElementsByTagName('option');
					if (alleles[i].label) {
						totalEles++;
					}
					totalEles = totalEles + opts.length;
				case 'option':
					if (alleles[i].childNodes.length == 1) {
						eles.push(alleles[i]);
						totalEles++;
					}
			}
		}
		
		// Check how many rows we are expecting
		var expectedCols = (Math.ceil(totalEles * this.s.pxPerRow / this.s.maxHeight) > this.s.maxCols ? this.s.maxCols : Math.ceil(totalEles * this.s.pxPerRow / this.s.maxHeight));
		
		for (var i=0; i<eles.length; i++) {
			
			// Close our current UL and start a new one
			if (currentRow > Math.ceil(totalEles / expectedCols) - 1) {
				Element.addClassName(ul, 'col');
				this.ulcontainer.appendChild(ul);
				ul = document.createElement('ul');
				currentRow = 0;
				this.actualCols++;
			}
						
			// Fix disabled options in IE
			if(eles[i].selected && eles[i].disabled){
				makeSelected = true;
			}
			if(makeSelected && !eles[i].disabled && String(eles[i].tagName).toLowerCase() == "option"){
				makeSelected = false;
				eles[i].selected = true;
			}
			
			switch (String(eles[i].tagName).toLowerCase()) {
				case 'optgroup':
					var li = document.createElement('li');
					var optgroupUl = document.createElement('ul');
					
					if (eles[i].label) {
						Element.addClassName(li, 'optlabel');
						if (eles[i].disabled) {
							Element.addClassName(li, 'disabled');
							Element.addClassName(optgroupUl, 'disabled');
						}
						li.innerHTML = eles[i].label;
						ul.appendChild(li);
						currentRow++;
					}
					
					var opts = eles[i].getElementsByTagName('option');
					currentRow = currentRow + opts.length;

					for (var j=0; j<opts.length; j++) {
						// Fix disabled options in IE
						if(opts[j].selected && (eles[i].disabled || opts[j].disabled)){
							makeSelected = true;
						}
						if(makeSelected && !eles[i].disabled && !opts[j].disabled){
							makeSelected = false;
							opts[j].selected = true;
						}
						
						this.createElement(opts[j], eles[i].disabled, optgroupUl);
					}
					ul.appendChild(optgroupUl);
					break;
				case 'option':
					if (eles[i].childNodes.length == 1) {
						this.createElement(eles[i], eles[i].disabled, ul);
						currentRow++;
					}
					break;
			}
		}
		this.actualCols++;
		if (this.actualCols > 1) {
			Element.addClassName(ul, 'col');
		}
		this.ulcontainer.appendChild(ul);
		
	},
	createElement: function(el, state, parent) {
		// Fix disabled options in IE
		var elSelected = (el.selected && (!el.disabled && (!el.parentNode || !el.parentNode.disabled))) ? true : false;
		
		var itemvar = {};
		itemvar.value = el.value;
		itemvar.el = el;
		itemvar.selected = elSelected;
		
		itemvar.disabled = (el.disabled || el.parentNode.disabled) ? true : false;
		itemvar.text = el.text;
		itemvar.li = document.createElement('li');
		if(itemvar.el.className != ''){
			Element.addClassName(itemvar.li, itemvar.el.className);
		}
		if (state == true) {
			itemvar.li.innerHTML = el.text;
			Element.addClassName(itemvar.li, 'disabled');
		}
		else {
			itemvar.a = document.createElement('a');
			itemvar.a.href = 'javascript:void(0);';
			itemvar.text = el.text;
			if(this.s.isMultiSelect){
				itemvar.a.innerHTML = '<input type="checkbox" ' + ((itemvar.selected)? ' checked="checked"' : '' ) + '> ' + el.text;
			}else{
				itemvar.a.innerHTML = el.text;
			}
			itemvar.li.appendChild(itemvar.a);
		}
		parent.appendChild(itemvar.li);
		this.items.push(itemvar);
		if (elSelected) { // create our label element
			this.setLabel(el.text);
		}
	},
		
	createContainer: function(){
		Element.addClassName(this.label, 'label');
		
		var icon = document.createElement('div');
		Element.addClassName(icon, 'icon');
		icon.appendChild(this.labelText);
		this.label.appendChild(icon);
		this.container.appendChild(this.label);
		
		//var dims = this.s.elDims;//Element.getDimensions(this.el);
		//var origDims = dims.width;
		
		// container width
		if (this.s.fixedWidth == true && this.s.width) {
			this.container.style.width = this.s.width + 'px'; // set the width of the original <select>
		}
		/*else if (this.s.fixedWidth == true) {
			this.container.style.width = dims.width + ((this.s.isMultiSelect == true) ? 30 : 0) + ((!isNaN(this.s.maxHeight) && uldims.height > this.s.maxHeight) ? 17 : 0) + 'px'; // set the width of the container
		}*/
		
		DOM.insertAfter(this.container, this.el);
		
		var text = [];
		var opts = this.el.getElementsByTagName('option');
		for(var i=0, final=opts.length; i<final; i++)
			if(opts[i].selected)
				text.push(opts[i].text);
		text = text.join(', ');
		if(text == '')
			text = this.s.defaultLabel;
		this.setLabel(text);

	},
	
	createUL: function() {
		
		Element.addClassName(this.ulcontainer, 'ulcontainer');
		this.container.appendChild(this.ulcontainer);
		this.ulcontainer.show();
		
		var width = this.container.offsetWidth;
		var uldims = Element.getDimensions(this.ulcontainer);
		
		var uls = this.ulcontainer.childNodes;
		var ulswidth = 0;
		for (i=0; i<uls.length; i++) {
			if (uls[i].tagName.toLowerCase() == 'ul') {
				ulswidth += uls[i].offsetWidth;
			}
		}
		
		// dropdown width
		if (ulswidth > width) {
			// options longer than select
			this.ulcontainer.style.width = ulswidth + ((!isNaN(this.s.maxHeight) && uldims.height > this.s.maxHeight) ? 17 : 0) + 'px';
			//alert ('2');
		}
		else if (this.s.fixedWidth == true) {
			// set the width of the original <select>
			this.ulcontainer.style.width = width + 'px';
			this.ulcontainer.style.width = width + (width - this.ulcontainer.offsetWidth) + 'px';
			//alert ('3');
		}
		
		if (!isNaN(this.s.maxHeight) && uldims.height > this.s.maxHeight) {
			this.ulcontainer.style.height = this.s.maxHeight + 'px';
			this.ulcontainer.style.overflow = 'auto';
		}
		
		var left = String(Position.cumulativeOffset(this.ulcontainer));
		left = Number(left.substring(0, left.indexOf(',')));
		left += Element.getDimensions(this.ulcontainer).width;
		if(Element.getDimensions(document.getElementsByTagName('body')[0]).width < left){
			this.ulcontainer.style.right = "0px";
		}
				
		var uldims = Element.getDimensions(this.ulcontainer);
		
		if (document.all) { 
			/* create an iFrame to fix IE bug */
			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.zIndex = 10;
			this.ulcontainer.style.zIndex = 11;
			this.imask.style.width = uldims.width + 'px';
			this.imask.style.height = uldims.height + 'px';
			this.container.appendChild(this.imask);
			this.imask.style.top = this.ulcontainer.style.top;
			if(Element.getDimensions(document.getElementsByTagName('body')[0]).width < left){
				this.imask.style.right = "0px";
			}
		}
		
		this.ulInit = true;
	},	
	clickLabel: function(e) {
		if(!this.ulInit){	//ul not initialized?
			this.findElements();
			this.createUL();
			this.initializeULEvents();
			this.show();
		}
		else
		this.toggle();
		for (var i=0; i<this.items.length; i++) {
			Element.removeClassName(this.items[i].li, this.s.hoverClass);
			Element.removeClassName(this.items[i].li, this.s.selectedClass);
			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.ulcontainer)){
			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.ulcontainer)){
			this.hide();
		}else{
			this.show();
		}
	},
	hide: function() {
		Element.hide(this.ulcontainer);
		if (document.all) { 
			Element.hide(this.imask);
		}
	},
	show: function() {
		Element.show(this.ulcontainer);
		if (document.all) { 
			Element.show(this.imask);
		}
		var left = String(Position.cumulativeOffset(this.ulcontainer));
		left = Number(left.substring(0, left.indexOf(',')));
		left += Element.getDimensions(this.ulcontainer).width;
		if(Element.getDimensions(document.getElementsByTagName('body')[0]).width < left){
			this.ulcontainer.style.right = "0px";
		}
	},
	checkItem: function(itemvar, index){
		itemvar.selected = true;
		itemvar.el.selected = true;
		if(itemvar.li.getElementsByTagName('input')[0]){
			itemvar.li.getElementsByTagName('input')[0].checked = true;
		}
		Element.addClassName(itemvar.li, this.s.selectedClass);
		if(index){
			this.el.selectedIndex = index;
		}
	},
	uncheckItem: function(itemvar){
		itemvar.selected = false;
		itemvar.el.selected = false;
		if(itemvar.li.getElementsByTagName('input')[0]){
			itemvar.li.getElementsByTagName('input')[0].checked = false;
		}
		Element.removeClassName(itemvar.li, this.s.selectedClass);
	},
	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.uncheckItem(this.items[i]);
					}else{
						this.checkItem(this.items[i]);
					}
					break;
				}
			}
		}else{
			for (var i=0; i<this.items.length; i++) {
				if (this.items[i].a == ele) {
					this.checkItem(this.items[i], i);
				} else {
					this.uncheckItem(this.items[i]);
				}
			}
			this.hide();
		}
		var allchecked = true;
		for(var x=0; x<this.items.length; x++){
			if(this.items[x].a == ele){
				var itemvar = this.items[x];
			}
			if(this.items[x].selected == false && !Element.hasClassName(this.items[x].li, this.s.toggleClass) && !this.items[x].disabled){
				allchecked = false;
			}
		}
		if(Element.hasClassName(itemvar.li, this.s.toggleClass)){
			for(var x=0; x<this.items.length; x++){
				if(allchecked){
					//uncheck all
					this.uncheckItem(this.items[x]);
				}else{
					//check all
					if (!this.items[x].disabled) {
						this.checkItem(this.items[x]);
					}
				}
			}
		}else if(allchecked){
			for(var x=0; x<this.items.length; x++){
				if(Element.hasClassName(this.items[x].li, this.s.toggleClass)){
					this.checkItem(this.items[x]);
				}
			}
		}else{
			for(var x=0; x<this.items.length; x++){
				if(Element.hasClassName(this.items[x].li, this.s.toggleClass)){
					this.uncheckItem(this.items[x]);
				}
			}
		}
		this.updateLabel();
		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);
			}
		}
	},
	initializeULEvents: function() {
		Event.observe(this.ulcontainer, 'click', this.onClick.bind(this));
		Event.observe(this.ulcontainer, 'mouseover', this.onMouseOver.bind(this));
		Event.observe(document, '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.ulcontainer)){
			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 && !Element.hasClassName(this.items[x].li, this.s.toggleClass)){
				selectedItems.push(this.items[x].text);
			}
		}
		text = selectedItems.join(', ');
		if(text == ''){
			text = this.s.defaultLabel;
		}
		this.setLabel(text);
	},
	setLabel: function(text) {
		//shorten text if necessary
		//var dims = this.s.elDims;
		var shorttext = text.substring(0, Math.round(this.s.width/this.s.pxPerChar));
		if(shorttext != text)
			text = shorttext.substring(0, shorttext.length-2) + '\u2026'; // truncate text and replace last character with ellipsis
			
		//this.labelText.innerHTML = text; // This brakes in IE
		var text = document.createTextNode(text);
		this.labelText.innerHTML = '';
		this.labelText.insertBefore(text, this.labelText.firstChild);
	}
}

//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'
		});
	},
	'select.rSelectNetwork' : function(el) {
		new rSelectClass (el, {
			defaultLabel: 'My Network'
		});
	}
}, true);
