/* ******************************************************************************
  *	jQuery Custom Select
  *	Copyright 2009 Gennady Samsonov
  ***************************************************************************** */

(function($) {
	
    $.fn.cselect = function(options) {
		
		settings = $.extend($.fn.cselect.constructor, options);
        
        this.filter('select').each(function() {
			var id = this.id || 'rndm_' + this.name;
			
			$(this).css({ visibility:'hidden' });
				
			settings.init(this, id);
			settings.create(this, id);

			$(document)
				.unbind('click')
				.click(function(e){
					settings.hide();
				});
        });
		
        return this;
    };
	
	$.fn.cselect.constructor = {
		debag : 0,
		
		selects : {},
		
		init : function(_this, id) {
			var len		= _this.options.length;	
			var options	= [];
			
			if (typeof this.selects[id] == 'undefined' || (this.selects[id].custom && this.selects[id].custom == 0)) {
				for (var i = 0; i < len; i++) {
					options[i] = _this.options[i].innerHTML;
				}
				
				this.selects[id] = {
					id: id,
					name: _this.name,
					index: _this.selectedIndex,
					dwidth: 0,
					owidth: 0,
					options: options,
					custom: 0
				}
			} else {
				node = this.selects[id];
				
				if (typeof node.options == 'undefined') {
					for (var i = 0; i < len; i++) {
						options[i] = _this.options[i].innerHTML;
					}
				}
				
				this.selects[id] = {
					id: id,
					name: _this.name,
					index: _this.selectedIndex,
					dwidth: typeof node.dwidth == 'undefined' ? 0 : node.dwidth,
					owidth: typeof node.owidth == 'undefined' ? 0 : node.owidth,
					options: typeof node.options == 'undefined' ? options : node.options,
					custom: 1
				}
			}
			
			$('#' + id + '_slct').remove();
		},
			
		replace : function(a, dw) {
			this.dwidth = isNaN(dw) ? this.dwidth : dw;
			if (typeof a == 'object' && this.options.length == a.length) { 
				for (var i = 0; i < this.options.length; i++) {
					this.options[i] = a[i];
				}
			}
		},
		
		create : function(_this, id) {
			if (!_this) return;
			
			node = this.selects[id];
			
			var self	=	this;
			var len		=	node.options.length;
			var width	=	_this.offsetWidth + node.dwidth;
			var slct	=	$('<div></div>')
								.attr('id', id + '_slct')
								.addClass('select-slct' + (_this.className.indexOf('check') != -1 ? ' select-check' : '') + (_this.disabled ? ' select-disabled' : ''))
								.css({ width: width + 15 + 'px' });
							
			var slctd	=	$('<div></div>')
								.attr('id', id + '_slctd')
								.addClass('select-slctd')
								//.css({ width: width + 'px' })
								.click(function(e){
									if (_this.disabled) return false;
									self.bubbling(e);
									_this.focus();
									self.toggle(_this, id);
								});
								
			var slctdw	=	$('<div></div>')
								.attr('id', id + '_fix')
								.addClass('select-fix')
								.css({ width: width - 14 + 'px', overflow: 'hidden' })
								.html(node.options[_this.selectedIndex]);
							
			var optns	=	$('<div></div>')
								.attr('id', id + '_optns')
								.addClass('select-optns')
								
			slctd.append(slctdw);
			
			for (var i = 0; i < len; i++) {
				var optn	=	$('<div></div>')
									.attr('id', id + '_optn' + i)
									.addClass('select-optn hoverable' + (_this.selectedIndex == i ? ' select-optn-active' : ''))
									.html('<div class="select-optnw">' + (node.options[i] == '' ? '&nbsp;' : node.options[i]) + '</div>')
									.click(function(idx){
										return function() {
											self.change(_this, id, idx);
										}
									}(i));
				optns.append(optn);					
			}
			
			slct.append(slctd).append(optns);
			
			$(_this)
				.before(slct)
				.css({ visibility:'visible' })
				.keyup(function(){
					self.change(_this, id, _this.selectedIndex);
				})
				.focus(function(){
					$('#' + id + '_slct').addClass('select-focus');
				})
				.blur(function(){
					$('#' + id + '_slct').removeClass('select-focus');
					//$('#' + id + '_optns').css({ display:'none' }); not working correctly
				});
				
			if (!this.debug) $(_this).css({ position:'absolute', left:'-10000px' });
		},
		
		change : function(_this, id, idx, toggle) {
			if (_this) {
				node = this.selects[id];
				
				_this.selectedIndex = idx;
				node.index = idx;
				
				$('#' + id + '_fix').html(node.options[idx]);
				$('#' + id + '_optns div.select-optn').removeClass('select-optn-active');
				$('#' + id + '_optn' + idx).addClass('select-optn-active');
			
				if (toggle) this.toggle(_this, id);
				
				_this.focus();
				//if (_this.getAttribute('onchange')) _this.onchange('onchange');
			}
			this.hide();
		},
		
		toggle : function(_this, id) {
			node = this.selects[id];
			
			var slctd	= this.gebi(id + '_slctd');
			var optns	= this.gebi(id + '_optns');
			
			if (optns.style.display == 'block') {
				optns.style.display = 'none';
				$(slctd).removeClass('select-slctd-active');
			} else {
				if (!node.owidth) {
					var len = node.options.length;
					
					optns.style.visibility = 'hidden';
					optns.style.display = 'block';
					
					if (len > 10) {
						if (optns.offsetWidth + 18 < slctd.offsetWidth - 8) node.owidth = slctd.offsetWidth - 8;
							else node.owidth = optns.offsetWidth + 18;
						optns.className += ' select-scrl';
					} else {
						if (optns.offsetWidth < slctd.offsetWidth - 8) node.owidth = slctd.offsetWidth - 8;
							else node.owidth = optns.offsetWidth;
					}
					optns.style.display = 'none';
					optns.style.visibility = 'visible';
				}
				optns.style.width = node.owidth + 'px';
			
				this.hide();
				optns.style.display = 'block';
				$(slctd).addClass('select-slctd-active');
			}
			
			if (node.index) {
				this.gebi(id + '_optns').scrollTop = this.gebi(id + '_optn' + node.index).offsetTop;
			}
		},
			
		hide : function() {
			$('div.select-optns').css({ display:'none' });
			$('div.select-slctd-active').removeClass('select-slctd-active');
		},
			
		gebi: function(n) {
			if(!n) return false;
			if(!document.getElementById(n)) return false;
			return document.getElementById(n)
		},

		bubbling: function(e) {
			e = this.eie(e); 
			if (!e.cancelBubble) e.cancelBubble = true;
			if (e.stopPropagation) e.stopPropagation();
			return false;
		},

		eie: function (e) {
			if (!e) var e = window.event;
			return e;
		}
	};
    
})(jQuery);
