(function ($) {
    $.widget('ui.slidebar', {
        count: 0,
        dbl: false,
        interval: null,
        interval2: null,
        
        _init: function () {
            var self = this;
            this.position = this.options.position;
            var oImages = [];
            this.element.addClass('ui-widget ui-helper-reset modo-slidebar')
            this.element.wrapInner('<div class="ui-helper-hidden"></div>');
            this.element.append(
                $('<div class="ui-widget-content article" />')
            );
            
            this.element.prepend(
                $('<div class="thumbs-container" />').append(
                    $('<div class="ui-widget-content thumbs" />').hide()
                )
            );
            
            this.thumbs = this.element.find('.thumbs');
            this.article = this.element.find('.article');
            
            // get source information
            $.getJSON(this.options.source, function (response) {
                self._setup(response);
            });
            
            this._setData('oImages', oImages);
            
            // load the loader image
            this.loader = new Image();
            this.loader.src = this.options.path+this.options.loader;
        },
        _setup: function (response) {
            // size containing boxes
            this._setDimensions(response);
            this.thumbs.show();

            // add images
            for(x in response) {
                this._addSlot(response[x]);
                this._putTempImage(response[x]);
                this._getImage(response[x]);
            }
            var placeholder = new Object();
            placeholder.name = 'Placeholder';
            placeholder.src = this.options.placeholderImage;
            if (this.count < 4) {
                while (this.count < 4) {
                    this._addSlot(placeholder);
                    this._putTempImage(placeholder);
                    this._getImage(placeholder);
                }
            }
            else if (this.count == 5) {
                this._addSlot(placeholder);
                this._putTempImage(placeholder);
                this._getImage(placeholder);
            }
            if (this.count > 4) {
                this.element.prepend(
                    $('<a class="controlBar right" />').html('<a><img src="/lib/img/slider_widget/slidebar-right-arrow.png" alt="slidebar-right-arrow" width="35" height="180"/></a>')
                );
                this.element.prepend(
                    $('<a class="controlBar left" />').html('<a><img src="/lib/img/slider_widget/slidebar-left-arrow.png" alt="slidebar-left-arrow" width="35" height="180"/></a>')
                );

                $(".controlBar.left a").click(function () {
                    $(this).parents('.modo-slidebar').slidebar('slide_left');
                    return false;
                });

                $(".controlBar.right a").click(function () {
                    $(this).parents('.modo-slidebar').slidebar('slide_right');
                    return false;
                });
            }
            
            this.select(0);
        },
        _setDimensions: function (response) {
            this.element.children('.thumbs-container').css({
                'width': (5 * this.options.dimensions.width) + 
                        (4 * this.options.dimensions.spacing),
                'height': this.options.dimensions.height
            });

            var length = response.length;
            if (length < 4)
                length = 4;
            else if (length == 5)
                length = 6;
            this.thumbs.css({
                'width': ((length+1) * this.options.dimensions.width) + 
                        length * this.options.dimensions.spacing  + 10, 
                'height': this.options.dimensions.height
            });
        },
        _getImage: function (oImage) {
            var self = this;
            var image = oImage;
            
            // fetch image
            image.element = new Image();
            image.element.onload = function () {
                self._replaceTempImage(image);
            };
            image.element.src = oImage.source;
            
            // check if image already loaded
            if(image.element.complete) {
                image.element.onload = null;
                self._replaceTempImage(image);
            }
            
            var oImages = this._getData('oImages');
            oImages.push(image);
            this._setData('oImages', oImages);
        },
        _putTempImage: function (oImage) {
            $(this.thumbs.children().get(oImage.index)).css({
                'backgroundImage': 'url('+this.loader.src+')',
                'backgroundRepeat': 'no-repeat',
                'backgroundPosition': 'center center'
            });
        },
        _replaceTempImage: function (oImage) {
            var image = oImage.element;
            
            $(image).addClass('content');
            
            // insert image
            $(this.thumbs.children().get(oImage.index)).append(
                $(image).css({
                    'width': image.width,
                    'height': image.height,
                    'marginLeft': -1*(image.width/2)
                })
            );
            
            // add click event
            $(this.thumbs.children().get(oImage.index)).click(function () {
                if($(this).hasClass('selected')|| $(this).hasClass('placeholder')) {
                    return false;
                }
                
                $(this).parents('.modo-slidebar').slidebar('select', oImage.index);
            });
            
            if(!$.browser.msie) {
                this._addShadow(oImage);
            }
            //$(this.thumbs.children().get(oImage.index)).prepend($("<div class='shadow' />").append($("<h1 />").text(oImage.index)));
        },
        _addShadow: function (oImage) {
            var self = this;
            var opacity = this.options.shadow.strength/100;
            if (oImage.opacity) {
                 opacity = oImage.opacity/100;
            }
            
            $(this.thumbs.children().get(oImage.index)).prepend(
                $('<div class="shadow" />').append(
                    $('<img class="left" />').attr('src', this.options.path+this.options.shadow.left)
                ).append(
                    $('<img class="center" />').attr('src', this.options.path+this.options.shadow.center).css({
                        'height': this.options.dimensions.height
                    })
                ).append(
                    $('<img class="right" />').attr('src', this.options.path+this.options.shadow.right)
                ).css({
                    'height': this.options.dimensions.height,
                    'opacity': opacity
                })
            );
        },
        _addSlot: function (oImage) {
            oImage.index = this.count;
            this.count++;
            
            var thumb = new $('<a class="thumb" />');
            if (oImage.name == 'Placeholder')
                thumb.addClass('placeholder');
            
            thumb.css({
                'width': this.options.dimensions.width,
                'height': this.options.dimensions.height,
                'marginRight': this.options.dimensions.spacing
            })
            
            this.thumbs.append(thumb);
        },
        _loadContent: function (index) {
            var self = this;
            var oImages = this._getData('oImages');
            
            // get source information
            $.get(oImages[index].content, function (response) {                
                var article = $(response).appendTo(self.article).hide();
                article.fadeIn(200, function () {
                   $(this).parent().animate({
                       'height': $(this).height() + 25
                   });
                });
                
                self.element.trigger('load.slidebar');

            }, 'html');
        },
        deselect: function () {
            if (this.thumbs.children('.selected'))
                this.select(-1, true);
        },
        select: function (index, dontLoad) {
            if(this.interval || this.interval2) {
                return false;
            }
            
            var self = this;
            
            var newIndex = -1;
            if (index != -1)
                newIndex = (this.count + index - this.position) % this.count;
            if (newIndex == 4)
                self.slide_right();

            if(this.article.children().size() > 0 ) {
                this.article.children().fadeOut(200, function () {
                    self.article.html('');
                });
            }
            
            var animation = {
                'selected' : $(this.thumbs.children().get(newIndex)),
                'previous' : this.thumbs.children('.selected'),
                'steps' : this.options.animation.steps,
                'current_step' : 0
            }

            var easeOutCubic = function (t, b, c, d) {
            	return c*((t=t/d-1)*t*t + 1) + b;
            };
            
            this.interval = setInterval(function () {
                if(animation.current_step <= animation.steps) {            
                    var newWidth = Math.round(
                        easeOutCubic(
                            animation.current_step,
                            self.options.dimensions.width,
                            self.options.dimensions.width+self.options.dimensions.spacing,
                            animation.steps
                        )
                    );
                    
                    if (animation.selected)
                        animation.selected.width( newWidth );
                    
                    if(animation.previous && animation.previous.size() > 0) {
                        animation.previous.width(
                            (self.options.dimensions.width + 
                            (self.options.dimensions.width*2)+self.options.dimensions.spacing)-newWidth
                        );
                    }
            
                    animation.current_step++;
                } else {
                    if (animation.selected)
                        animation.selected.toggleClass('selected');
                    if (animation.previous)
                        animation.previous.removeClass('selected');
                    clearInterval(self.interval);
                    self.interval = null;
                    if (!dontLoad && index != -1)
                        self._loadContent(index);
                }
            }, this.options.animation.interval);
        },
        slide_right: function () {
            if (this.interval2 || this.interval)
                return;
            if (++this.position > this.count-1)
                this.position = 0;

            var selectedIndex = this.thumbs.children().index(this.thumbs.children(".selected"));
            if (selectedIndex == 5)
                if (++this.position > this.count-1)
                    this.position = 0;
            if (selectedIndex == 0 || selectedIndex == 5)
                this.slide(this.thumbs, 2*-(this.options.dimensions.width + this.options.dimensions.spacing));
            else
                this.slide(this.thumbs, -(this.options.dimensions.width + this.options.dimensions.spacing));
        },
        slide_left: function () {
            if (this.interval2 || this.interval)
                return;
            if (--this.position < 0)
                this.position = this.count-1;

            var selectedIndex = this.thumbs.children().index(this.thumbs.children(".selected"));
            if (selectedIndex == 3)
                if (--this.position < 0)
                    this.position = this.count-1;
            var offset = this.options.dimensions.width + this.options.dimensions.spacing;
            if (selectedIndex == this.count-1 || selectedIndex == 3)
                offset *= 2;

            for (i=0; i<Math.abs(offset / (this.options.dimensions.width + this.options.dimensions.spacing)  ); ++i) {
                this.thumbs.children(":last").insertBefore(this.thumbs.children(":first"));
                if (this.thumbs.children(":first").hasClass(".selected"))
                    break;
            }
            this.thumbs.css("margin-left", -offset)
            this.slide(this.thumbs, offset);
        },
        slide: function (thumbs, diff) {
            var self = this;
            var animation2 = null;
            
            if(this.interval2) {
                return;
            }
            else {
                animation2 = {
                    'offset': diff,
                    'margin': parseInt(thumbs.css("margin-left")),
                    'origin': parseInt(thumbs.css("margin-left")),
                    'moving': (diff>0?'right':'left'),
                    'steps' : 60,
                    'current_step' : 0
                }
            }
            
            
            var easeRightCubic = function (t, c, d) {
            	return c*((t=t/d-1)*t*t + 1);
            };
            
            this.interval2 = setInterval(function () {
                if(animation2.current_step <= animation2.steps && (animation2.margin - animation2.offset) != animation2.origin) {
                    animation2.margin = animation2.origin + Math.round(easeRightCubic(animation2.current_step, animation2.offset, animation2.steps));
                    thumbs.css( "margin-left", animation2.margin );
                    animation2.current_step++;
                } else {
                    if (animation2.moving == "left") {
                        for (i=0; i<Math.abs(animation2.offset / (self.options.dimensions.width + self.options.dimensions.spacing)); ++i) {
                            thumbs.children(":first").insertAfter(thumbs.children(":last"));
                            if (thumbs.children(":last").hasClass(".selected"))
                                break;
                        }
                    }
                    animation2.margin = 0;
                    thumbs.children(":first").hide();
                    thumbs.css("margin-left", 0);
                    thumbs.children(":first").show();
                    clearInterval(self.interval2);
                    self.interval2 = null;
                    animation2 = null;
                }
            }, this.options.animation.interval2);
        }
    });
    
    $.extend($.ui.slidebar, {
       getter: '',
       defaults: {
           dimensions: {
               height: 150,
               width: 115,
               spacing: 10
           },
           source: false,
           path: '/lib/img/',
           loader: 'loader.gif',
           shadow: {
               strength: 60,
               left: 'slidebar-shadow-left.png',
               center: 'slidebar-shadow-center.png',
               right: 'slidebar-shadow-right.png'
           },
           animation: {
               interval: 20,
               steps: 30
           },
           position: 0,
           placeholderImage: ''
       } 
    });
})(jQuery);