jQuery.fn.nicecontrols = function () {
    $('BODY').append('<div id="niceselect-dropdowns"></div>');
    $(this).each(function () {
        // init
        var rand = Math.round(Math.random() * 10000000);
        var $elem = $(this);
		// store element position and dimensions
		$elem.data('marginTop',$elem.css('margin-top'));
		$elem.data('marginRight',$elem.css('margin-right'));
		$elem.data('marginBottom',$elem.css('margin-bottom'));
		$elem.data('marginLeft',$elem.css('margin-left'));
		$elem.data('float',$elem.css('float'));
		$elem.data('width',$elem.outerWidth());
		$elem.data('height',$elem.outerHeight());
		if($elem.tagName() == 'select'){
			$elem.data('width',$elem.outerWidth()+3);
			$elem.data('setfocus', false).wrap('<span class="niceselect"></span>').after('<img class="replacement" src="img/blank.gif" alt="" /><span class="cont01" id="niceselect_master_' + rand + '" role="button" aria-haspopup="true" aria-owns="niceselect_slave_' + rand + '"><span class="cont02"></span><span class="c c1"></span><span class="c c2"></span><span class="c c3"></span><span class="c c4"></span></span>');
			var $container = $elem.parents('SPAN.niceselect').eq(0);
			var $holder = $container.find('IMG.replacement');
			var $drop = $('<div class="niceselect-drop" id="niceselect_slave_' + rand + '" role="listbox" aria-hidden="true" aria-labelledby="niceselect_master_' + rand + '" aria-activedescendant="niceselect_master_' + rand + '_active"><div class="scroller"><ul></ul></div></div>');
			var $opts = $drop.find('UL');
			var t = ''
			// fill replacement with data and create content
			$elem.find('OPTION, OPTGROUP').each(function (a, b) {
				var $b = $(b);
				if ($b.tagName() == 'optgroup') {
					var $item = $('<li role="presentation"><div class="group"><span>' + $b.attr('label') + '</span></div></li>');
				} else {
					$b.text() == "" ? t = '&nbsp;' : t = $b.text();
					var $item = $('<li role="presentation"><div role="option" aria-selected="false"><span>' + t + '</span></div></li>');
					if ($b.is(':selected')) {
						$item.find('div').eq(0).addClass('selected').attr('aria-selected', 'true').attr('id', 'niceselect_master_' + rand + '_active');
					}
					if ($b.parents('OPTGROUP').length > 0) {
						$item.find('div').eq(0).addClass('grouped');
					}
				}
				$opts.append($item);
			});
			$('#niceselect-dropdowns').append($drop);
			// mimic owner css
			$container.css({
				marginTop: $elem.css('margin-top'),
				marginRight: $elem.css('margin-right'),
				marginBottom: $elem.css('margin-bottom'),
				marginLeft: $elem.css('margin-left'),
				width: $elem.data('width'),
				height: $elem.outerHeight()
			});
			$holder.css({
				width: $elem.data('width') + 'px',
				height: $elem.outerHeight() + 'px'
			});
			$container.find('SPAN.cont02').eq(0).css({
				width: $container.outerWidth() - ($container.find('SPAN.cont01').eq(0).outerWidth() - $container.find('SPAN.cont02').eq(0).outerWidth()) + 'px'
			}).html($elem.find('OPTION:selected').html() == '' ? '&nbsp;' : $elem.find('OPTION:selected').text());
			// die if select is empty
			if ($elem.find('OPTION').length == 0) {
				return;
			}
			// set events
			$container.find('SPAN.cont01').mousedown(function () {
				if ($elem.is(':disabled')) {
					return false;
				}
				if ($container.hasClass('niceselect-open')) {
					$container.removeClass('niceselect-open');
					$('.niceselect-drop-open').removeClass('niceselect-drop-open').attr('aria-hidden', 'true');
				} else {
					$('.niceselect-open, .niceselect-focus').removeClass('niceselect-open').removeClass('niceselect-focus');
					$('.niceselect-drop-open').removeClass('niceselect-drop-open').attr('aria-hidden', 'true');
					$container.addClass('niceselect-open');
					$drop.addClass('niceselect-drop-open').attr('aria-hidden', 'false');
					if ($drop.find('UL').outerHeight() > 200) {
						$drop.find('DIV.scroller').css('height', '200px').scrollTop(0);
						$drop.find('DIV.scroller').scrollTop($drop.find('DIV.selected').position().top - ($drop.find('DIV.scroller').outerHeight() / 2) + ($drop.find('DIV.selected').outerHeight() / 2));
					} else {
						$drop.find('DIV.scroller').css('height', 'auto');
					}
					$drop.css({
						width: $elem.data('width') + 'px',
						left: $container.offset().left + 'px',
						top: $container.offset().top + $container.find('SPAN.cont01').outerHeight() + 'px'
					});
				}
				$elem.data('setfocus', true);
				nicecontrols_setfocus($elem);
				return false;
			});
			$elem.bind("change keyup keydown", function () {
				if ($elem.is(':disabled')) {
					return false;
				}
				$container.find('SPAN.cont02').eq(0).html($elem.find('OPTION:selected').text() == '' ? '&nbsp;' : $elem.find('OPTION:selected').text());
				$drop.find('DIV.selected').removeClass('selected').attr('aria-selected', 'false');
				$('#niceselect_master_' + rand + '_active').attr('id', '');
				$drop.find('DIV DIV:not(.group)').eq($elem.attr('selectedIndex')).addClass('selected').removeClass('hover').attr('aria-selected', 'true').attr('id', 'niceselect_master_' + rand + '_active');
			}).focus(function () {
				if ($elem.is(':disabled')) {
					return false;
				}
				$elem.data('setfocus', false);
				$container.addClass('niceselect-focus');
			}).blur(function (event) {
				if ($elem.is(':disabled')) {
					return false;
				}
				if ($elem.data('setfocus') == true) {
					$elem.data('setfocus', false);
					nicecontrols_setfocus($elem);
				} else {
					$container.removeClass('niceselect-focus').removeClass('niceselect-open');
					$drop.removeClass('niceselect-drop-open').attr('aria-hidden', 'true');
				}
			}).keydown(function (e) {
				if ($elem.is(':disabled')) {
					return false;
				}
				if (e.which == 13 || e.which == 27) { // return or esc
					$container.removeClass('niceselect-open');
					$drop.removeClass('niceselect-drop-open').attr('aria-hidden', 'true');
				}
			});
			$drop.find('DIV DIV:not(.group, .scroller)').each(function (a, b) {
				$(this).mousedown(function () {
					$container.removeClass('niceselect-open');
					$drop.removeClass('niceselect-drop-open');
					$elem.attr('selectedIndex', a).trigger('change').data('setfocus', true);
				}).hover(function () {
					$(this).addClass('hover');
				},
				function () {
					$(this).removeClass('hover');
				});
			});
			$drop.find('DIV.group').mousedown(function (event) {
				$elem.data('setfocus', true);
				event.stopPropagation();
				return false;
			});
			$drop.find('DIV.scroller').mousedown(function (event) {
				$elem.data('setfocus', true);
				event.stopPropagation();
				return false;
			});
		} else if($elem.tagName() == 'input' && $elem.is('[type=text]')){
			$elem.wrap('<span class="niceinput"><span class="cont01"></span></span>');
			var $container = $elem.parents('SPAN.niceinput').eq(0);
			$container.prepend('<img class="replacement" src="img/blank.gif" alt="" />');
			$elem.after('<span class="c c1"></span><span class="c c2"></span><span class="c c3"></span><span class="c c4"></span>');
			var $holder = $container.find('IMG.replacement');
			$holder.css({
				width: $elem.data('width') + 'px',
				height: $elem.data('height') + 'px'
			});
			$container.css({
				marginTop: $elem.data('marginTop'),
				marginRight: $elem.data('marginRight'),
				marginBottom: $elem.data('marginBottom'),
				marginLeft: $elem.data('marginLeft'),
				float: $elem.data('float'),
				width: $elem.data('width')
			}).click(function(){
				$elem.focus();
			});
			$elem.css({
				width: $container.outerWidth() - ($container.find('SPAN.cont01').outerWidth() - $elem.outerWidth()) + 'px'
			}).focus(function(){
				$container.addClass('niceinput-focus');
			}).blur(function(){
				$container.removeClass('niceinput-focus');
			});
		} else if($elem.tagName() == 'input' && ($elem.is('[type=checkbox]') || $elem.is('[type=radio]'))){
			var t = $elem.attr('type');
			$elem.wrap('<span class="nicecontrol nicecontrol-'+t+'" />').after('<img class="replacement" role="'+t+'" aria-checked="false" src="img/blank.gif" alt="" />');

			var $container = $elem.parents('SPAN.nicecontrol').eq(0);
			var $holder = $container.find('IMG.replacement');
			if($elem.is(':checked')){ $holder.attr('aria-checked','true').addClass('replacement-checked'); }
			$container.css({
				marginTop: $elem.data('marginTop'),
				marginRight: $elem.data('marginRight'),
				marginBottom: $elem.data('marginBottom'),
				marginLeft: $elem.data('marginLeft'),
				float: $elem.data('float'),
				width: $elem.data('width')
			});
			$elem
				.bind('updateMe',function(){
					if(t == 'radio'){
						$('INPUT[name="'+$elem.attr('name')+'"]:not(:checked)').each(function(){
							$(this).parents('SPAN.nicecontrol').eq(0).find('IMG.replacement').attr('aria-checked','false').removeClass('replacement-checked');
						});
					}
					if($elem.is(':checked')){
						$holder.attr('aria-checked','true').addClass('replacement-checked');
					} else {
						$holder.attr('aria-checked','false').removeClass('replacement-checked');
					}
				})
				.trigger('updateMe')
				.click(function(){ $(this).trigger('updateMe'); })
				.focus(function(){ $container.addClass('nicecontrol-'+t+'-focus'); })
				.blur(function(){ $container.removeClass('nicecontrol-'+t+'-focus'); })
			;
			$holder.click(function(){
				if($elem.is(':checked') && t=='checkbox'){
					$elem.attr('checked','').trigger('updateMe').focus();
				} else {
					$elem.attr('checked','checked').trigger('updateMe').focus();
				}
				return false;
			}).css({
				width: $elem.data('width') + 'px',
				height: $elem.data('height') + 'px'
			});
		} else if($elem.tagName() == 'textarea'){
			$elem.wrap('<span class="nicetextarea"><span class="cont01"></span></span>');
			var $container = $elem.parents('SPAN.nicetextarea').eq(0);
			$container.prepend('<img class="replacement" src="img/blank.gif" alt="" />');
			$elem.after('<span class="c c1"></span><span class="c c2"></span><span class="c c3"></span><span class="c c4"></span>');
			var $holder = $container.find('IMG.replacement');
			$holder.css({
				width: $elem.data('width') + 'px',
				height: $elem.data('height') + 'px'
			});
			$container.css({
				marginTop: $elem.data('marginTop'),
				marginRight: $elem.data('marginRight'),
				marginBottom: $elem.data('marginBottom'),
				marginLeft: $elem.data('marginLeft'),
				float: $elem.data('float'),
				width: $elem.data('width')
			}).click(function(){
				$elem.focus();
			});
			$elem.css({
				width: $container.outerWidth() - ($container.find('SPAN.cont01').outerWidth() - $elem.outerWidth()) + 'px',
				height: $container.outerHeight() - ($container.find('SPAN.cont01').outerHeight() - $elem.outerHeight()) + 'px'
			}).focus(function(){
				$container.addClass('nicetextarea-focus');
			}).blur(function(){
				$container.removeClass('nicetextarea-focus');
			});
		}
    });
};
// workaround to get firefox focusing working
function nicecontrols_setfocus(r){ setTimeout(function(){ $(r).focus(); },50); }
