(function( window, $, undefined ) {
	
	/*
	* smartresize: событие измения размера отскоком для jQuery
	*
	* Последняя версия доступна на Github:
	* https://github.com/louisremi/jquery.smartresize.js
	*
	* Copyright 2011 @louis_remi
	* Licensed under the MIT license.
	*
	* Перевод: команда сайта RUSELLER.COM
	*/

	var $event = $.event, resizeTimeout;

	$event.special.smartresize 	= {
		setup: function() {
			$(this).bind( "resize", $event.special.smartresize.handler );
		},
		teardown: function() {
			$(this).unbind( "resize", $event.special.smartresize.handler );
		},
		handler: function( event, execAsap ) {
			// Сохраняем контекст
			var context = this,
				args 	= arguments;

			// Устанавливаем корректный тип события
			event.type = "smartresize";

			if ( resizeTimeout ) { clearTimeout( resizeTimeout ); }
			resizeTimeout = setTimeout(function() {
				jQuery.event.handle.apply( context, args );
			}, execAsap === "execAsap"? 0 : 100 );
		}
	};

	$.fn.smartresize 			= function( fn ) {
		return fn ? this.bind( "smartresize", fn ) : this.trigger( "smartresize", ["execAsap"] );
	};
	
	$.Accordion 				= function( options, element ) {
	
		this.$el			= $( element );
		// Пункты списка
		this.$items			= this.$el.children('ul').children('li');
		// Общее количество пунков
		this.itemsCount		= this.$items.length;
		
		// Инициализация аккордеона
		this._init( options );
		
	};
	
	$.Accordion.defaults 		= {
		// Индекс открытого пункта. -1 означает, что все пункты закрыты по умолчанию.
		open			: -1,
		// Если данная опция имеет значение true, то только один пункт может быть открыт. При открытии пункта другой открытый пункт закрывается.
		oneOpenedItem	: false,
		// Скорость анимации открытия/закрытия
		speed			: 600,
		// Эффект анимации открытия/закрытия
		easing			: 'easeInOutExpo',
		// Скорость прокрутки анимации действия
		scrollSpeed		: 900,
		// Эффект прокрутки анимации действия
		scrollEasing	: 'easeInOutExpo'
    };
	
	$.Accordion.prototype 		= {
		_init 				: function( options ) {
			
			this.options 		= $.extend( true, {}, $.Accordion.defaults, options );
			
			// Проверка опций
			this._validate();
			
			// current - индекс открытого пункта
			this.current		= this.options.open;
			
			// Скрываем содержание, чтобы вывести его потом
			this.$items.find('div.st-content').hide();
			
			// Сохраняем оригинальную высоту и координату по вертикали для каждого пункта
			this._saveDimValues();
			
			// Если нужно по умолчанию открыть пункт
			if( this.current != -1 )
				this._toggleItem( this.$items.eq( this.current ) );
			
			// Инициализируем события
			this._initEvents();
			
		},
		_saveDimValues		: function() {
		
			this.$items.each( function() {
				
				var $item		= $(this);
				
				$item.data({
					originalHeight 	: $item.find('a:first').height(),
					offsetTop		: $item.offset().top
				});
				
			});
			
		},
		// Проверка опций
		_validate			: function() {
		
			// Индекс открытого пункта должен иметь значение между -1 и общим количеством пунктов, иначе установим его в значение -1
			if( this.options.open < -1 || this.options.open > this.itemsCount - 1 )
				this.options.open = -1;
	 	
		},
		_initEvents			: function() {
			
			var instance	= this;
			
			// Открыть / закрыть пункт
			this.$items.find('a:first').bind('click.accordion', function( event ) {
				
				var $item			= $(this).parent();
				
				// Закрыть любой открытый пункт если опция oneOpenedItem имеет значнеие true
				if( instance.options.oneOpenedItem && instance._isOpened() && instance.current!== $item.index() ) {
					
					instance._toggleItem( instance.$items.eq( instance.current ) );
				
				}
				
				// Открыть / закрыть пункт
				instance._toggleItem( $item );
				
				return false;
			
			});
			
			$(window).bind('smartresize.accordion', function( event ) {
				
				// Сброс оригинальных занчений пункта
				instance._saveDimValues();
			
				// Сброс высоты содержания любого пункта, который открыт
				instance.$el.find('li.st-open').each( function() {
					
					var $this	= $(this);
					$this.css( 'height', $this.data( 'originalHeight' ) + $this.find('div.st-content').outerHeight( true ) );
				
				});
				
				// Прокрутка до текущего пункта
				if( instance._isOpened() )
				instance._scroll();
				
			});
			
		},
		// Проверка наличия открытых пунктов
		_isOpened			: function() {
		
			return ( this.$el.find('li.st-open').length > 0 );
		
		},
		// Открыть / закрыть пункт
		_toggleItem			: function( $item ) {
			
			var $content = $item.find('div.st-content');
			
			( $item.hasClass( 'st-open' ) ) 
					
				? ( this.current = -1, $content.stop(true, true).fadeOut( this.options.speed ), $item.removeClass( 'st-open' ).stop().animate({
					height	: $item.data( 'originalHeight' )
				}, this.options.speed, this.options.easing ) )
				
				: ( this.current = $item.index(), $content.stop(true, true).fadeIn( this.options.speed ), $item.addClass( 'st-open' ).stop().animate({
					height	: $item.data( 'originalHeight' ) + $content.outerHeight( true )
				}, this.options.speed, this.options.easing ), this._scroll( this ) )
		
		},
		// Прокрутка до текущего или последнего открытого пункта
		_scroll				: function( instance ) {
			
			var instance	= instance || this, current;
			
			( instance.current !== -1 ) ? current = instance.current : current = instance.$el.find('li.st-open:last').index();
			
			$('html, body').stop().animate({
				scrollTop	: ( instance.options.oneOpenedItem ) ? instance.$items.eq( current ).data( 'offsetTop' ) : instance.$items.eq( current ).offset().top
			}, instance.options.scrollSpeed, instance.options.scrollEasing );
		
		}
	};
	
	var logError 				= function( message ) {
		
		if ( this.console ) {
			
			console.error( message );
			
		}
		
	};
	
	$.fn.accordion 				= function( options ) {
	
		if ( typeof options === 'string' ) {
		
			var args = Array.prototype.slice.call( arguments, 1 );

			this.each(function() {
			
				var instance = $.data( this, 'accordion' );
				
				if ( !instance ) {
					logError( "Нельзя вызвать метод до инициализации; " +
					"попытка вызвать метод '" + options + "'" );
					return;
				}
				
				if ( !$.isFunction( instance[options] ) || options.charAt(0) === "_" ) {
					logError( "Нет такого метода в аккордеоне :'" + options );
					return;
				}
				
				instance[ options ].apply( instance, args );
			
			});
		
		} 
		else {
		
			this.each(function() {
				var instance = $.data( this, 'accordion' );
				if ( !instance ) {
					$.data( this, 'accordion', new $.Accordion( options, this ) );
				}
			});
		
		}
		
		return this;
		
	};
	
})( window, jQuery );
