function parseQuery(s)
{
	s=s.substring(s.indexOf('?')+1);
	var q=s.split('&');
	var r={};
	for(var i=0;i<q.length;i++)
	{
		var t=q[i].split('=');
		r[t[0]]=t[1];
	}
	return r;
}

(function($)
{
	var $event=$.event,$special=$event.special,
		
	$listen=$.listen=function(name,listener,selector,handler)
	{
		if(typeof listener!='object')
		{
			handler=selector;selector=listener;listener=document;
		}
		each(name.split(/\s+/),function(ev)
		{
			ev=$listen.fixes[ev]||ev;
			var idxer=indexer(listener,ev)||indexer(listener,ev,new Indexer(ev,listener));
			idxer.append(selector,handler);
			idxer.start();
		});
	},
	
	indexer=function(elem,name,val)
	{
		return $.data(elem,name+'.indexer',val);
	};
			
	$.extend($listen,{regex:/^((?:\w*?|\*))(?:([#.])([\w-]+))?$/,fixes:{focus:'focusin',blur:'focusout'},cache:function(on){this.caching=on;}});
		
	$.fn.listen=function(name,selector,handler)
	{
		return this.each(function()
		{
			$listen(name,this,selector,handler);
		});
	};
	
	function Indexer(name,listener)
	{
		$.extend(this,{ids:{},tags:{},listener:listener,event:name});
		this.id=Indexer.instances.push(this);
	};
	
	Indexer.instances=[];
	
	Indexer.prototype=
	{
		constructor:Indexer,handle:function(e)
		{
			indexer(this,e.type).parse(e);
		},start:function()
		{
			if(!this.on)
			{
				$event.add(this.listener,this.event,this.handle);this.on=true;
			}
		},parse:function(e)
		{
			var node=e.data||e.target,args=arguments,handlers;
			if(!$listen.caching||!(handlers=this.cache(node))){handlers=[];

			each([node.nodeName,'*'],function(tag)
			{
				var klasses=this.tags[tag];
				if(klasses)each((node.className+' *').split(' '),function(klass)
				{
					if(klass&&klasses[klass])push(handlers,klasses[klass]);
				});
			},this);

		}
		if(handlers[0])
		{
			each(handlers,function(handler)
			{
				if(handler.apply(node,args)===false)
				{
					e.preventDefault();
					e.stopPropagation();
				}
			});
		}
		handlers=args=node=null;
	},
	append:function(selector,handler)
	{
		each(selector.split(/\s*,\s*/),function(selector)
		{
			var match=$listen.regex.exec(selector);

			var id=match[2]=='#'&&match[3],tag=match[1].toUpperCase()||'*',klass=match[3]||'*';

			if(tag)
			{
				tag=this.tags[tag]=this.tags[tag]||{};
				(tag[klass]||(tag[klass]=[])).push(handler);
			}
		},this);
	}};
	
	function each(arr,fn,scope)
	{
		for(var i=0,l=arr.length;i<l;i++) fn.call(scope,arr[i],i);
	};
	
	function push(arr,elems)
	{
		arr.push.apply(arr,elems);
		return arr;
	};
	





	$.fn.stars=function()
	{
		function on(){$(this).parent().addClass('b-rating-stars-'+this.className.substring(1));}
		function off(){$(this).parent().removeClass().addClass('b-rating-stars');}
		

		function click()
		{
			$.getJSON("/action/vote/",
				{
					tpl_id: parseQuery(this.href)['tpl_id'],
					rec_id: parseQuery(this.href)['rec_id'],
					vote: parseQuery(this.href)['vote']
				},
			function (data)
				{
					if(data.status=='ok')
					{
						var r=$("div.rating");
						$("div.vote").hide();
						r.find("i").removeClass().addClass('b-rating-stars').addClass('b-rating-stars-'+data.votes);
						r.find("span").text(data.count);r.show();
					}
				}
			);
			
			
			return false;
		}

	return this.each(
		function()
		{
			var $this=$(this);
			$this.listen("mouseover","a",on).listen("mouseout","a",off);
			if($this.hasClass("can-vote")){$this.listen("click","a",click);}
		}
	);
	}
})(jQuery);
