(function($){
	
	$.fn.accordion = function(options) {
		var isMethodCall = (typeof options == "string") || false;
		var args = arguments;
		if (!isMethodCall)
			var options = $.extend({}, options, {});
		
		$(this).each(function(){
			var tab = $(this).data("accordion");
			if (isMethodCall && tab) {
				if (tab[options] && typeof tab[options] == "function"){
					tab[options].apply(tab, $.makeArray(args).slice(1));
				}
				return;
			} else {
				tab = new $.accordion(this, options);
				$(this).data("accordion", tab);
			}
		});
		return this;
	};
	
	$.accordion = function(elem, options) {
		this.elem = elem;
		this.options = $.extend({}, options, $.accordion.defaults);
		this.init();
	};
	
	$.extend($.accordion, {
		defaults: {
			showDuration: 800,
			hideDuration:800,
			selectedClass: "selected",
			show: function(obj) {
				var n,p,h;
				
				if ( $(obj).is("." + this.options.selectedClass) ) {
					this.showNext();
					return;
				} else {
					this.hideCurrent();
				}
				
				self.working = true;
				
				n = $(".accordion_content", obj);
				if (!n.length) {
					self.working = false;
					return;
				}
				
				$(obj).addClass(this.options.selectedClass);
				this.current = obj;
				
				h = $(obj).data("accordion_height");
				$(obj).stop();
				$(obj).animate({height:h+"px"}, {queue:false, duration:this.options.showDuration, easing:"easeOutExpo", complete:function(){
					
				}})
				
				$(".accordion_header", obj).addClass("accordion_header_selected");
				
				self.working = false;
			},
			
			hide: function(obj) {
				var n,p,h;
				n = $(".accordion_content", obj);
				if (!n.length) return;
				var self = this;
				
				self.working = true;
				
				h = $(obj).data("accordion_header_height");
				$(obj).stop();
				$(obj).animate({height:h+"px"}, {queue:false, duration:this.options.hideDuration, easing:"easeOutExpo", complete:function(){
					$(this).css({
						overflow:"hidden",
						height:h+"px"
					});
					
					$(this).removeClass(self.options.selectedClass);
					self.working = false;
				}})
				
				$(".accordion_header", obj).removeClass("accordion_header_selected");
			}
		},
		prototype: {
			init: function() {
				var self = this;
				this.items = $(".accordion_item", this.elem);
				this.itemsCount = this.items.length;
				this.shortCircuit = false;
				this.working = false;
				
				if (!this.itemsCount) {
					this.shortCircuit = true;
					return;
				}
				
				this.current = this.items.filter("." + self.options.selectedClass);
				if (!this.current.length) {
					$(this.items[0]).addClass(self.options.selectedClass);
					this.current = $(this.items[0]);
				} else {
					this.current = $(this.current[0]);
				}
				
				this.items.not(this.current).removeClass(self.options.selectedClass);
				
				this.items.each(function(){
					var item = this;
					var c = $(".accordion_content", this);
					if ( c.length ) {
						c = $(c[0]);
						c.data("accordion_height", c.outerHeight(true));
						
						$(".accordion_header", this).bind("click", function(){
							if (self.working) return false;
							self.options.show.apply(self,[item]);
							return false;
						});
					}
					
					
					var h = 0;
					h = $(".accordion_header", this).outerHeight(true);
					$(item).data("accordion_header_height", h);
					h += $(".accordion_content", this).outerHeight(true);
					$(item).data("accordion_height", h);
					
					if ( !$(this).is("." + self.options.selectedClass)) {
						$(item).css({
							height:$(item).data("accordion_header_height") + "px",
							overflow:"hidden"
						});
					}
					
					$(".accordion_header", this).bind("mouseover", function(){
						$(this).addClass("accordion_header_hover");
					});
					$(".accordion_header", this).bind("mouseout", function(){
						$(this).removeClass("accordion_header_hover");
					});
					
					if ( $(item).is("." + self.options.selectedClass)) {
						$(".accordion_header", item).addClass("accordion_header_selected");
					} else {
						$(".accordion_header", item).removeClass("accordion_header_selected");
					}
				});
			},
			
			showNext: function() {
				var n = $(this.current).next();
				if (!n.length) {
					n = $(this.items[0]);
				}
				
				this.options.show.apply(this,[n]);
			},
			
			hideCurrent: function() {
				if (this.current) {
					this.options.hide.apply(this,[this.current]);
				}
			}
		}
	});
})(jQuery);