/**
 * @author Michael Levanov (leor.thesweetvoice@gmail.com)
 */ 

(function($) {
    var defaults = {
        cw: 0, // ширина контейнера, по умолчанию вычисляется исходя из размеров эллемента
        ch: 0, // высота контейнера, по умолчанию вычисляется исходя из размеров эллемента
        showTitle: false, // показывать информацию об элементе
        titleContainer: null, //  объект для отображения информации
        hideUnfocused: true, // скрывать объекты не в фокусе
        showUnfocusedCount: 1, // показывать это количество объектов влево/вправо от объекта в фокусе
        changeOpacity: true, // нужно ли изменять прозрачность при слайдах (не работает в IE)
        nextArrow: null, // контрол управляющий движением к следующему элементу 
        prevArrow: null // контрол управляющий движением к пердыдущему элементу 
    }
    
    methods = {
        init: function(params) {
            var options = jQuery.extend({}, defaults, params);
            
            var obj = jQuery(this);
            var init = obj.data('jmCarousel');
            if(init) {
                return this
            } else {              
                // инициализация
                obj.data('jmCarousel', true);
                obj.data('jmCarouselOptions', options);
                
                // контейнер для информации
                if(options.showTitle && !options.titleContainer) {
                    var tc = document.createElement('div');
                    tc.setAttribute('class', 'jmagic-carousel-title-container');
                    obj.after(tc);
                    options.titleContainer = $(tc);
                }
                
                // контролы
                if(options.arrowNext) options.arrowNext.click(function() {
                    obj.jmCarousel('moveNext');
                });
                if(options.arrowPrev) options.arrowPrev.click(function() {
                    obj.jmCarousel('movePrev');
                });
                
                var items = obj.children(); // получаем все объекты (элементы списка)
                obj.data('jmCarouselItems', items);
                var current = 0;
                obj.data('jmCarouselCurrent', current);
                
                var to = $(items[0]);
                var dWidth = to.width(); 
                var dHeight = to.height(); // получаем ширину/высоту элемента списка
                var ratio = dWidth/dHeight; // вычисляем отношение ширины к высоте
                
                if(options.showTitle) methods.show_title.apply(this, [to]);
                
                var bodyWidth = (items.length)*dWidth;
                if(!options.cw) options.cw = bodyWidth;
                var bodyHeight = (items.length)*dHeight;
                if(!options.ch) options.ch = bodyHeight; // высота элемента + отступ
                obj.css({width:bodyWidth, height:bodyHeight, position:'relative', left: '50%', marginLeft: -(bodyWidth/2), top: '50%', marginTop: -(bodyHeight/2)}).wrap('<div style="width:'+options.cw+'px;height:'+options.ch+'px;overflow:hidden;position:relative;"/>');
                
                obj.data('jmCarouselSizes', {
                    bodyWidth: bodyWidth, 
                    bodyHeight: bodyHeight, 
                    dWidth: dWidth, 
                    dHeight: dHeight, 
                    ratio: ratio
                });
                
                for(var i = 0;i < items.length;i++) {
                    var o = $(items[i]);
                    css = methods.get_coords.apply(this, [i, o]);
                    css.position = 'absolute';
                    o.css(css);
                    o.addClass('jmagic-carousel-item');
                    
                    var index = methods.get_index.apply(this, [i])
                    
                    if(options.hideUnfocused && Math.abs(index) > options.showUnfocusedCount) o.hide();
                    
                    o.click(function() {
                        obj.jmCarousel('move', [$(this).index()]);
                    });
                }
                
                return $(this);
            }
        },
        
        movePrev: function() {
            var c = parseInt($(this).data('jmCarouselCurrent'));
            var items = $(this).data('jmCarouselItems');
            
            c += 1;
            if(c == items.length) c = 0;
            
            $(this).jmCarousel('move', c);
        },
        
        
        moveNext: function() {
            var c = parseInt($(this).data('jmCarouselCurrent'));
            var items = $(this).data('jmCarouselItems');
            
            c -= 1;
            if(c < 0) c = items.length-1;
            
            $(this).jmCarousel('move', c);
        },
        
        move: function(t) {
            var obj = $(this);
            var current = obj.data('jmCarouselCurrent');
            
            if(current == t) return false;
            current = t;
            
            obj.data('jmCarouselCurrent', t);
            var items = obj.data('jmCarouselItems');
            var options = obj.data('jmCarouselOptions');
            
            for(var i = 0;i < items.length;i++) {
                var o = $(items[i]);
                css = obj.jmCarousel('get_coords', i, o);
                o.css('z-index', css.zIndex);
                delete css.zIndex;
                o.animate(css, 'slow', function() {
                    var ind = items.index(this);
                    var index = obj.jmCarousel('get_index', ind);
                    
                    if(options.hideUnfocused && Math.abs(index) > options.showUnfocusedCount) $(this).hide();
                });                
                
                if(options.showTitle && current == i) {
                    obj.jmCarousel('show_title', o);
                }
            }
        },
        
        get_coords: function(i, o) {
            var obj = $(this);
            var items = obj.data('jmCarouselItems');
            var options = obj.data('jmCarouselOptions');
            var sizes = obj.data('jmCarouselSizes');
            
            if(!o || o === undefined) o = $(items[i]);
            var index = obj.jmCarousel('get_index', i);
            
            /*var h = o.height();
            var w = o.width();*/
            
            var opts = {
                left: sizes.bodyWidth/2 - (index*sizes.dWidth + sizes.dWidth/2)
            }
            opts.width = sizes.dWidth*Math.cos((sizes.bodyWidth/2)-opts.left-sizes.dWidth/2);
            opts.height = opts.width/sizes.ratio;
            
            opts.top = sizes.bodyHeight/2 - opts.height/2;
            if(index > 0) opts.left += sizes.dWidth - opts.width - opts.width/2;
            if(index < 0) opts.left += opts.width/2;
            
            opts.zIndex = (items.length - Math.abs(index))*100;
            
            if(options.changeOpacity && !$.browser.msie) {
                var pc = items.length/100;
                opts.opacity = (((items.length - Math.abs(index))/pc)/100);
                if(index != 0) opts.opacity *= 1/(Math.abs(index)+1);
            }
            
            return opts;
        },
        
        get_index: function(i) {
            var obj = $(this);
            var current = obj.data('jmCarouselCurrent');
            var items = obj.data('jmCarouselItems');
            
            var index =  i - current;
            if(index < 0) index += items.length;
            if(index > items.length/2) index = index - items.length;
            
            return index
        },
        
        show_title: function(o) {
            var obj = $(this);
            var options = obj.data('jmCarouselOptions');
            
            var title = '';
            var tls = o.find('.jmagic-carousel-title');
            if(tls.length > 0) title = $(tls[0]).html();
            
            options.titleContainer.html(title);
        }
    }
    
    $.fn.jmCarousel = function(method) {
        if (methods[method]) {
            return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
        } else if ( typeof method === 'object' || ! method ) {
            return methods.init.apply( this, arguments );
        } else {
            $.error( 'Метод "' +  method + '" не обнаружен в плагине jmCarousel' );
        }
    }
})(jQuery)
