(function($) {
	$.fn.jcolors = function(options) {
		var opts = $.extend({}, $.jcolorsDefaults, options),
			obj = $(this),
			field = $('<input type="hidden" name="' + opts.name + '" />').insertAfter(obj),
			color_id = opts.color_id,
			palette = null,
			init = function() {
				if (!color_id) {
					 var i;
					 for (i in opts.colors) {
					 	color_id = i;
					 	break;
					 }
				}
				reset_palette(color_id);
				obj.bind(opts.event, show_palette);
			},
			show_palette = function(e) {
				e.stopPropagation();
				if (palette && palette.is(':visible'))
					return reset_palette();
				$(document)
					.trigger(opts.triggerEvent)
					.bind(opts.triggerEvent, reset_palette);
				if (!palette) {
					palette = $('<div></div>')
						.addClass(opts['class'])
						.css({position: 'absolute', width: opts.width?opts.width + 'px':'inherit', zIndex: 100})
						.click(function(e) {
							e.stopPropagation();
						})
						.appendTo('body')
						.html('<div class="tl"></div><div class="t"></div><div class="tr"></div><div class="r"></div><div class="bl"></div><div class="b"></div><div class="br"></div><div class="inner"><div class="tl"></div><div class="t"></div><div class="tr"></div><div class="bl"></div><div class="b"></div><div class="br"></div></div>');
					var colors = $('<div></div>')
							.addClass(opts.colorsClass)
							.appendTo(palette),
						add_color = function(i) {
							if (typeof opts.colors[i] == 'string')
								opts.colors[i] = {color: opts.colors[i]};
							if (opts.colors[i].available == 'undefined')
								opts.colors[i].available = true;
							var id = i,
								bg = opts.colors[i].color,
								name = opts.colors[i].name || '',
								available = opts.colors[i].available,
								cls = opts.colors[i]['class'] || '';
							$('<a href="#"></a>')
          						.css({backgroundColor: bg})
          						.attr('title', name)
          						.addClass(cls)
          						.addClass(id == color_id?opts.activeClass:'')
          						.click(function() {
          							e.stopPropagation();
          							set_color(id);
          							change_color(id);
          							$(this).addClass(opts.activeClass);
          							//reset_palette(id);
            						return false;
            					})
            					.hover(function() {
            						$(this).addClass(opts.overClass);
            						change_color(id);
            					},
            					function() {
            						$(this).removeClass(opts.overClass);
            						change_color(color_id);
            					})
            					.appendTo(colors);
            			}, i;
					for (i in opts.colors) add_color(i);
					colors.append('<div class="clear"></div>');
					$('<input type="image" alt="Ok" src="' + opts.imgPath + 'palette_ok.gif" />')
						.click(function() {
							reset_palette();
						})
						.appendTo(palette);
            	}
			    var offset = obj.offset(),
			    	ow = obj.width(),
			    	oh = obj.height(),
			    	pw = palette.width(),
			    	ph = palette.height();
			    palette.css({
        			'left': (offset.left + pw > $(window).scrollLeft() + $(window).width()?offset.left + ow - pw:offset.left) + 'px',
        			'top': (offset.top + oh + ph > $(window).scrollTop() + $(window).height()?offset.top - ph - opts.offset:offset.top + oh + opts.offset) + 'px'
        		}).show();
        		if (opts.init) {
					opts.init(opts.colors[color_id].color, obj);
				}
    	        return false;
			},
			set_color = function(id) {
				color_id = id;
				$('.' + opts.activeClass, palette).removeClass(opts.activeClass);
				field.val(id);
				if (opts.change) {
          			opts.change(opts.colors[color_id].color, obj);
          		}
			},
			change_color = function(color_id) {
				obj.css({backgroundColor: opts.colors[color_id].color});
				//obj.stop().animate({backgroundColor:opts.colors[color_id].color}, 400);
			},
			reset_palette = function(id) {
				if (id > 0) {
					set_color(id);
				}
				if (opts.reset) {
          			opts.reset(opts.colors[color_id].color, obj);
          		}
				change_color(color_id);
				if (palette) palette.hide();
				$(document).unbind(opts.triggerEvent, reset_palette);
			};
		if (opts.colors) init();
		return obj;
	}
})(jQuery);

$.jcolorsDefaults = {
	'class':		'jcolors',
	colorsClass:	'colors',
	overClass:		'over',
	activeClass:	'active',
	
	offset:			3,
	width:			200,
	imgPath:		'',
	
	name:			'color[]',
	'event':		'click',
	triggerEvent:	'click'
};
