(function($){

	$.fn.jColorChooser = function(o){
		return this.each(function(){
			$(this).data('jColorChooser', new $cc(this, o));
		});
	}
		
	var defaults = {
		scrolling : false,
		marginTop : false,
		onScroll : null,
		onScrollStop : null
	};

	jColorChooser = function(el, o){
		this.options = $.extend({}, defaults, o || {});
		this.element = $(el);
		
		this.shift = 0;
		this.itemHeight = 0;
		this.$prev = $('<a></a>');
		this.$next = $('<a></a>');
		this.$ul = $('<ul></ul>');
		this.$box = $('<div></div>');
		
		this.setup();
	};

	var $cc = jColorChooser;
	
	$cc.fn = jColorChooser.prototype = {
		jColorChooser : 'version 0.1.0'
	};
	
	$cc.fn.extend = $cc.extend = $.extend;
	
	$cc.fn.extend({
		
		setup : function(){
			var self = this, $this = $(this.element), $li = $this.parents('.js-product:first'), 
				$attrs = $li.find('.js-attrs:first'), $label = $li.find('div.label:first')
				$box = $this.find('.js-box:first'), $ul = $this.find('ul:first');
			var z = 0, force = false;
			
			self.$box = $box;
			self.$ul = $ul;
			
			$li.find('.js-exclude-height').each(function(){
				z += $(this).outerHeight(true);
			});
			var $prev = $('<a class="prev" href="#prev"></a>'),
				$next = $('<a class="next" href="#next"></a>'),
				h = $li.height() - z, arrows = $prev.outerHeight(true) + $next.outerHeight(true),
				ih = $ul.find('li:first').outerHeight(true), tail = h % ih;
				
			if (!arrows) arrows = 2 * 15;
			
			if ($ul.find('> li').size() > 3){
				// maximum rows - 3
				h = h >= ih * 3 + arrows ? ih * 3 + arrows : ih * 3;
				tail = 0;
				force = true;
			} else {
				h -= tail;
			}
			$this.height(h);
			$box.height(h);
			
			/*
			$li.find('.quantity-column').append('<p class="log">UL height: '+$ul.height()
				+'<br />Colors height: '+h+'<br />Colors count: '+$ul.find('> li').size()
				+'<br />LI height: '+$li.height()+'<br />PREV height: '+z
				+'<br />Diff: '+( $li.height() - z )+'</p>');
			
			$box.parent().append('<div style="position: absolute; width: 20px; height: '+($li.height() - z)+'px; top: 0; left: 60px; border: 1px solid red"></div>');
			*/

			if ($ul.height() > h || force){
				h += tail;
				$ul.css('position', 'absolute');
				$prev.prependTo($this);
				$next.appendTo($this);
				self.$prev = $prev;
				self.$next = $next;
				h -= arrows;
				h -= h % ih;
				$box.height(h);
				self.init();
			} else if (self.options.marginTop){
				$ul.css('margin-top', '15px');
			}
			
			$this.find('a[href$="#"]').click(function(){
				var $inp = $(this).parents('li:first').find('input[type="checkbox"]');
				$inp.attr('checked', !$inp.attr('checked'));
				return false;
			});
			
			if ($ul.find('> li').size() == 1){
				$ul.find('> li a').click();
			}
		},
		
		prevRefresh : function(top){
			if (!top) top = 0;
			this.$prev.removeClass('disabled');
			if (top + this.$ul.outerHeight(true) <= this.$box.outerHeight(true))
				this.$prev.addClass('disabled');
		},
		
		nextRefresh : function(top){
			if (!top) top = 0;
			this.$next.removeClass('disabled');
			if (top >= 0) this.$next.addClass('disabled');
		},
		
		animate : function(top, now){
			now = now || false;
			var self = this;
			top = self.realTop(top);
			if (now){
				self.$ul.css({'top' : top});
				if (typeof self.options.onScrollStop == 'function') self.options.onScrollStop.call(self);
			} else {
				self.$ul.animate({'top' : top}, function(){
					if (typeof self.options.onScrollStop == 'function') self.options.onScrollStop.call(self);
				});
			}
			self.prevRefresh(top);
			self.nextRefresh(top);
			if (typeof self.options.onScroll == 'function') self.options.onScroll.call(self);
		},
		
		realTop : function(top){
			if (this.$box.outerHeight(true) > this.$ul.outerHeight(true) + top)
				return this.$box.outerHeight(true) - this.$ul.outerHeight(true);
			if (top + this.shift > 0)
				return 0;
			return top;
		},
		
		init : function(){
			var self = this, $el = $(this.element), $box = self.$box, 
				$ul = self.$ul, ih = $ul.find('li:first').outerHeight(true),
				$prev = self.$prev, $next = self.$next;
			
			self.itemHeight = ih;
			self.shift = ih * 2;
			if (self.shift > $box.outerHeight(true)) self.shift = ih;
			
			function getTop(el){ // only of iE8
				var top = $(el).css('top');
				return top == 'auto' ? 0 : parseInt(top);
			}
			
			if (typeof $.fn.mousewheel == 'function' && self.options.scrolling){
				$box.mousewheel(function(event, delta){
					if (delta < 0) $prev.click(); else $next.click();
					return false;
				});
			}
			
			$prev.each(function(){
				self.prevRefresh();
			}).click(function(){
				if ($(this).is('.disabled')) return false;
				self.animate(getTop(self.$ul) - self.shift);
				return false;
			});
			
			$next.each(function(){
				self.nextRefresh();
			}).click(function(){
				if ($(this).is('.disabled')) return false;
				self.animate(getTop(self.$ul) + self.shift);
				return false;
			});
		},
		
		scrollTo : function(el, now){
			now = now || false;
			var self = this, $el = $(el);
			if ($el.get(0).tagName != 'LI') $el = $el.parents('li:first');
			self.animate(-self.itemHeight * $el.index(), now);
		},
		
		foo : function(){
		}
	});


	$.fn.jColorPicker = function(o){
		var defaults = {
			onChange	: null
		};
		var options = $.extend(defaults, o || {});
		
		return this.each(function(){
			var $div = $(this), $ul = $div.find('ul.ui-color-chooser'), 
				$box = $div.find('.js-box:first'), shown = false;
			
			function showPicker(){
				shown = true;
				$div.css({overflow : "visible"});
				$box.addClass('popup').css({"z-index" : 81});
			}
			
			function hidePicker(){
				shown = false;
				$div.css({overflow : "hidden"});
				$box.removeClass('popup').css({"z-index" : 0});
			}
			
			function getBoxPosition(){
				var $checked = $ul.find('> li input:checked'),
					left = parseInt($box.css('padding-left')) + parseInt($box.css('border-left-width')),
					top = 0;
				if ($checked.size() == 1){
					top = $checked.parents('li:first').position().top;
				}
				//top += parseInt($box.css('padding-top')) + parseInt($box.css('border-top-width'));
				return {top : top, left : left};
			}
			
			function initPicker(){
				var ih = $ul.find('> li:first').outerHeight(true), 
					h = ih * $ul.find('> li').size(), pos = getBoxPosition();
				
				$box.css({
					height : h+'px',
					top : '-'+pos.top+'px',
					left : '-'+pos.left+'px'
				});
				$div.find('.loading:first').remove();
			}
			
			$div.find('a[href$="#"]').click(function(){
				var $li = $(this).parents('li:first');
				if (shown){
					var $inp = $li.find('input[type="checkbox"]');
					$ul.find('input:checked').attr('checked', false);
					$inp.attr('checked', true);
					hidePicker();
					var pos = getBoxPosition();
					$box.animate({
						top : '-'+pos.top+'px',
						left : '-'+pos.left+'px'
					});
					if (typeof options.onChange == 'function'){
						options.onChange.call($div.get(0), this, $inp.get(0));
					}
				} else {
					if ($ul.find('> li').size() > 1) showPicker();
				}
				return false;
			});
			
			initPicker();
			
		});
	}

})(jQuery);

