
(function($){
	$.fn.swapWrapperClass = function(options){
		if(!this) return this;

		var $self = this;

		var nameSpace = "swapWrapperClass";

		options = $.extend({}, $.fn.swapWrapperClass.defaults, options, true);
		var wrapperClasses = [];
		
		$self.each(
			function(index){
				var wrapperClass;
				if($.isFunction(options.wrapperClass)){
					wrapperClass = options.wrapperClass.apply(this);
				}
				else{
					wrapperClass = options.wrapperClass;
				}
				wrapperClasses[index]=wrapperClass;
			}
		);

		return $self.each(
			function(index){
				var $trigger = $(this);
				var $wrapper;
				if($.isFunction(options.wrapper)){
					$wrapper = options.wrapper.apply(this);
				}
				else{
					$wrapper = $(options.wrapper);
				}
				var callbackArg = [$self, $wrapper, wrapperClasses, index];
				
				if(options.addEvent)
				{
					$trigger.bind(
						options.addEvent + "." + nameSpace,
						function(evnt){
							if(options.beforeAdd == undefined || $.isFunction(options.beforeAdd) && options.beforeAdd.apply(this, callbackArg)){
								$wrapper.addClass(wrapperClasses[index]);
								if($.isFunction(options.afterAdd)){
									options.afterAdd.apply(this, callbackArg);
								}
							}
							evnt.preventDefault();
							return false;
						}
					);
				}
				if(options.removeEvent)
				{
					$trigger.bind(
						options.removeEvent + "." + nameSpace,
						function(evnt){
							if(options.beforeRemove == undefined || $.isFunction(options.beforeRemove) && options.beforeRemove.apply(this, callbackArg)){
								$wrapper.removeClass(wrapperClasses.join(" "));
								if($.isFunction(options.afterRemove)){
									options.afterRemove.apply(this, callbackArg);
								}
							}
							evnt.preventDefault();
							return false;
						}
					);
				}
				if(options.swapEvent)
				{
					$trigger.bind(
						options.swapEvent + "." + nameSpace,
						function(evnt){
							if(options.beforeSwap == undefined || $.isFunction(options.beforeSwap) && options.beforeSwap.apply(this, callbackArg)){
								$wrapper.removeClass(wrapperClasses.join(" "));
								$wrapper.addClass(wrapperClasses[index]);
								if($.isFunction(options.afterSwap)){
									options.afterSwap.apply(this, callbackArg);
								}
							}
							evnt.preventDefault();
							return false;
						}
					);
				}
			}
		);
	};

	$.fn.swapWrapperClass.defaults = {
		wrapper: function(){
			var href, wrapper, $this = $(this);
			return ( href = $this.attr("href")) && (wrapper = $(href)) ?
				wrapper:
				undefined;
		},
		wrapperClass: function(){
			var rel, $this = $(this);
			return ( rel = $this.attr("rel")) ?
				rel:
				undefined;
		},

		swapEvent: "click",

		addEvent: undefined,

		removeEvent: undefined,

		beforeSwap: undefined,

		afterSwap: undefined,

		beforeAdd: undefined,

		afterAdd: undefined,

		beforeRemove: undefined,

		afterRemove: undefined
	};


	$(function(){
		$("a.swap_wrapper_class").swapWrapperClass();
	});
})(jQuery);
