(function($)
{
	$.fn.contextMenu = function(buttons)
	{
		var argButtons = buttons;
		
		return this.each(function (i)
		{
			// give each dropdown unique index
			var index = ($(this).data('index') == undefined ? i + Math.round(Math.random() * 10000).toString() : $(this).data('index'));
			$(this).data('index', index);
			
			// merge buttons given in argument and buttons in anchor element 
			var buttons = ($(this).attr('buttons') == undefined ? [] : $(this).attr('buttons').split(','));
			var tmp = ($(this).attr('id') == undefined ? [] : $(this).attr('id').split(','));
		    var id = tmp[0];
		    var regcode = tmp[1];

			for(var i in argButtons)
			{
				if($.inArray(argButtons[i], buttons) == -1) buttons.push(argButtons[i]);
			}
			
			if(!$.isArray(buttons)) buttons = [];
			
			// variables passed to action item
			var data = {
				anchor: $(this),
				buttons: buttons,
				index: index,
				id: id,
				regcode: regcode
			};

			$(this).click(function ()
			{
				var contextMenu = $('ul#context_plugin_dropdown_' + data.index);
				
				if(contextMenu.length == 0)
				{
					// create the context menu container element
					$('body:first').prepend('<ul id="context_plugin_dropdown_' + data.index + '" class="context_plugin_dropdown"></ul>');
					
					contextMenu = $('ul#context_plugin_dropdown_' + data.index);
					
					// add all action elements
					var actionItems = '';
					
					for(var i in data.buttons) if($.fn.contextMenu.actions[data.buttons[i]])
					{
						actionItems += '<li class="context_plugin_item"><a class="' + $.fn.contextMenu.actions[data.buttons[i]].name + '" href="javascript:void(0);">' + $.fn.contextMenu.actions[data.buttons[i]].title + '</a></li>';
					}
					
					contextMenu.html(actionItems);
					
					// attach data to actions
					contextMenu.children('li.context_plugin_item').children('a').data('objectData', data);
					
					// on mouse out, hide the menu
					contextMenu.hover(function () {}, function ()
					{
						$(this).hide();
					});
				}
				
				// position the context menu on top of the anchor
				contextMenu.css('top', Math.round(data.anchor.offset().top - data.anchor.scrollTop()) + 'px');
				contextMenu.css('left', Math.round(data.anchor.offset().left - data.anchor.scrollLeft()) + 'px');
				
				// if context menu would go behind the bottom edge
				if(data.anchor.offset().top + contextMenu.height() > $(document).height())
				{
					contextMenu.css('top', Math.round(data.anchor.offset().top - contextMenu.height() + data.anchor.height() - data.anchor.scrollTop()) + 'px');
				}
				
				// if context menu would go behind the right edge
				if(data.anchor.offset().left + contextMenu.width() > $(document).width())
				{
					contextMenu.css('left', Math.round(data.anchor.offset().left - contextMenu.width() + data.anchor.width() - data.anchor.scrollLeft()) + 'px');
				}
				
				contextMenu.show();
				
			});
		});
	};
	
	// actions array
	$.fn.contextMenu.actions = [];
	
	// method to add actions
	$.fn.contextMenu.addAction = function (action)
	{
		$.fn.contextMenu.actions[action.name] = action;
		
		// bind menu hiding
		$('a.' + action.name).live('click', function ()
		{
			$('ul.context_plugin_dropdown').hide();
		});
		
		// bind all future clicks
		$('a.' + action.name).live('click', action.bind);
	};
	
	
})(jQuery);
