/**
 * @author alexander.farkas
 */
(function($){
$.widget('ui.scroller', {
 init: function(){
 var elem = this.element[0],
 o = this.options,
 that = this;
        o.animateOptions.complete = function(){
            that.propagate('end');
        };
        o.direction = (o.direction == 'vertical') ? {
            scroll: 'scrollTop',
            outerD: 'outerHeight',
            dim: 'height'
        } : {
            scroll: 'scrollLeft',
            outerD: 'outerWidth',
            dim: 'width'
        };
        this.pictureUpdate = 0;
       
        this.moveElem = $(o.moveWrapper, elem);
        this.atomElem = $(o.atoms, elem);
        this.hidingWrapper = $(o.hidingWrapper, elem);
       
        this.nextLink = $(o.nextLink, elem);
        this.prevLink = $(o.prevLink, elem);
       
        this.position = 0;
        this.atomPos = 0;
        this.percentage = 0;
        this.oldPosition = 0;
        this.oldAtomPos = 0;
        if (o.hidingHeight || o.hidingWidth) {
            var css = (o.hidingHeight) ? {
                height: o.hidingHeight
            } : {};
            if ((o.hidingWidth)) {
                css = $.extend(css, {
                    width: o.hidingWidth
                });
            }
            this.hidingWrapper.css(css);
        }
        this.dims = [0];
        this.hidingWrapper[0][o.direction.scroll] = 0;
        this.update();
        if (o.diashow) {
            this.startDiashow();
            this.element.bind('moustartDiashowseenter.diashow', function(){
                clearInterval(that.diaTimer);
            }).bind('mouseleave.diashow', function(){
                that.startDiashow.call(that);
            });
        }
        if ($.fn.mousewheel) {
            this.moveElem.mousewheel(function(e, d){
                that.stopDiashow.call(that);
                d = (d < 0) ? '-' : '+';
                var moveStep = (o.moveStep) ? o.moveStep : 'atom';
                that.moveTo(d + 'atom1');
                return false;
            });
        }
 this.mouseAction = false;
 this.element.bind('mousedown.diashow', function(){
                that.mouseAction = true;
            }).bind('mouseup.diashow', function(){
                that.mouseAction = false;
            }).bind('mouseleave.diashow', function(){
                that.mouseAction = false;
            });
        this.nextLink.bind('click.uiscroller', function(){
            that.stopDiashow.call(that);
            that.moveTo('-' + o.moveStep);
            return false;
        });
        this.prevLink.bind('click.uiscroller', function(){
            that.stopDiashow.call(that);
            that.moveTo('+' + o.moveStep);
            return false;
        });
 },
 getAtomNearPos: function(oPos, nPos){
            var i = 2, len = this.dims.length;
            for (; i < len; i++) {
                if (nPos <= this.dims[i]) {
                    return i;
                }
            }
            return false;
        },
        atomfocus: function(){
 var scrollPos = this.hidingWrapper[0][this.options.direction.scroll];
 if(!this.mouseAction && this.mouseAction.position != scrollPos){
 scrollPos = this.getAtomNearPos(this.position, scrollPos);
            if (isFinite(scrollPos)) {
                this.moveTo(this.dims[scrollPos], false);
            }
 }
        },
        startDiashow: function(){
            var that = this;
            this.diaTimer = null;
            clearInterval(this.diaTimer);
            this.diaTimer = setInterval(function(){
                ((that.position === that.maxPos) ? that.moveTo(0, false) : that.moveTo('-' + that.options.moveStep));
            }, this.options.diashow);
        },
        stopDiashow: function(){
            this.element.unbind('.diashow');
            clearInterval(this.diaTimer);
        },
        update: function(hard){
            var that = this, jElm, o = this.options;
            if (hard) {
                this.dims = [0];
            }
            this.dims[1] = this.hidingWrapper.css({
                overflow: 'hidden'
            })[o.direction.dim]();
            var from = this.dims.length - 2;
 for(var i = from, len = this.atomElem.length; i < len; i++){
                jElm = $(this.atomElem[i]);
                that.dims.push(that.dims[0]);
                width = jElm[o.direction.outerD]({
                    margin: true
                });
                that.dims[0] += width;
                jElm.bind('focus.uiscroller', function(){
                    setTimeout(function(){
                        that.stopDiashow.call(that);
                        that.atomfocus.call(that);
                    }, 9);
                });
 }
            this.dims[0] += o.addSubPixel;
            this.maxPos = (this.dims[0] - this.dims[1]);
            var moveCss = (o.direction.dim == 'height') ? {
                height: this.dims[0] + 'px'
            } : {
                width: this.dims[0] + 'px'
            };
            this.moveElem.css(moveCss);
            this.pagination = null;
            if (o.pagination) {
                this.createPagination(hard);
            }
            this.showHideLinks();
        },
        pictureIsLoaded: function(){
            this.pictureUpdate--;
            if (!this.pictureUpdate) {
                this.update();
            }
        },
        append: function(html, waitForImageLoad){
            var that = this;
            var appendedHTML = $(html).appendTo(this.moveElem[0]);
 this.atomElem = this.atomElem.add(appendedHTML);
            if (waitForImageLoad) {
                appendedHTML.find('img').each(function(){
                    if (!this.complete) {
                        $(this).bind('load.uiscroller', function(){
                            that.pictureIsLoaded.call(that);
                        });
                        that.pictureUpdate++;
                    }
                });
                if (!this.pictureUpdate) {
                    this.update();
                }
            }
            else {
                this.update();
            }
           
        },
        createPagination: function(hard){
            var content = '<ul>', that = this, tmpContent, o = this.options;
            this.pagination = $(o.pagination, this.element[0]);
            this.atomElem.each(function(i){
                tmpContent = o.paginationAtoms.replace(/\$number/g, i + 1);
               
                content += (o.paginationTitleFrom) ? tmpContent.replace(/\$title/g, $(o.paginationTitleFrom, this).text()) : tmpContent;
            });
            this.pagination.html(content + '</ul>').find('a').each(function(i){
                $(this).click(function(){
                    that.stopDiashow.call(that);
                    that.moveTo.call(that, 'goTo' + i);
                    return false;
                });
            });
        },
        showHideLinks: function(pos){
 //calculate the curent position
 var o = this.options;
 pos = (isNaN(pos)) ? parseInt(this.hidingWrapper[0][o.direction.scroll], 10) : pos;
            if(pos !== this.position){
 this.percentage = pos / (this.maxPos / 100);
            this.oldPosition = this.position;
            this.oldAtomPos = this.atomPos;
            this.position = pos;
            var num = this.getAtomNearPos(this.oldPosition, this.position);
            num = (num) ? num - 2 : 0;
            this.atomPos = num;
 }
 this.percentage = pos / (this.maxPos / 100);
           
            if (pos <= 0 && this.prevLink.is('.' + o.activeLinkClass)) {
                o.linkFn.call(this.prevLink, 'hide');
                this.prevLink.removeClass(o.activeLinkClass);
            }
            else
                if (pos > 0 && !this.prevLink.is('.' + o.activeLinkClass)) {
                    o.linkFn.call(this.prevLink, 'show');
                    this.prevLink.addClass(o.activeLinkClass);
                }
            if (pos >= this.maxPos && this.nextLink.is('.' + o.activeLinkClass)) {
                o.linkFn.call(this.nextLink, 'hide');
                this.nextLink.removeClass(o.activeLinkClass);
            }
            else
                if (pos < this.maxPos && !this.nextLink.is('.' + o.activeLinkClass)) {
                    o.linkFn.call(this.nextLink, 'show');
                    this.nextLink.addClass(o.activeLinkClass);
                }
            if (this.pagination) {
                var oldActive = this.pagination.find('li').filter('.' + o.activePaginationClass).removeClass(o.activePaginationClass), newActive = oldActive.end().eq(this.atomPos).addClass(o.activePaginationClass);
                if ($.isFunction(o.paginationFn)) {
                    o.paginationFn.call(oldActive, 'inactive');
                    o.paginationFn.call(newActive, 'active');
                }
            }
        },
        calcNewPos: function(ePos){
            var rel = false, num;
            // handle Atom Step & goTo
            if (ePos.indexOf('goTo') === 0) {
                num = parseInt(/(\d+)$/.exec(ePos)[0], 10) + 2;
                ePos = this.dims[num];
            }
            else
                if (ePos == '-atom' || ePos == '-atom1') {
                    num = this.atomPos + 3;
                    ePos = (this.dims[num] || this.dims[num] === 0) ? this.dims[num] : this.dims[this.dims.length - 1];
                }
                else
                    if (ePos == '+atom' || ePos == '+atom1') {
                        ePos = (this.atomPos) ? this.dims[this.atomPos + 1] : 0;
                    }
                    else
                        if (ePos.indexOf('atom') == 1) {
                            num = parseInt(/(\d+)$/.exec(ePos)[0], 10);
                            if (ePos.indexOf('-') === 0) {
                                num += 2;
                                if (this.dims[this.atomPos + num]) {
                                    ePos = this.dims[this.atomPos + num];
                                }
                                else {
                                    ePos = this.dims[this.dims.length - 1];
                                }
                            }
                            else {
                                num -= 2;
                                var aLen = this.atomPos - num;
                                if (aLen > 1 && this.dims[this.atomPos - num]) {
                                    ePos = this.dims[this.atomPos - num];
                                }
                                else {
                                    ePos = 0;
                                }
                            }
                        // handle: +/-Number
                        }
                        else
                            if (ePos.indexOf('+') === 0 || ePos.indexOf('-') === 0) {
                                rel = ePos.slice(0, 1);
                                ePos = parseInt(ePos.slice(1), 10);
                                ePos = (rel == '-') ? this.position + ePos : this.position - ePos;
                            }
                            else {
                                // handle Percentage
                                var per = /(\d+)%$/.exec(ePos);
                                if (per && per[1]) {
                                    ePos = this.maxPos / 100 * parseFloat(ePos);
                                }
                            }
            return ePos;
        },
        moveTo: function(pos, anim, animOp){
 pos = (isNaN(pos)) ? this.calcNewPos(pos) : pos;
            pos = (pos <= 0) ? 0 : (pos >= this.maxPos) ? this.maxPos : pos;
            if (pos === this.position) {
                return false;
            }
            var o = this.options, scroll = o.direction.scroll;
            this.showHideLinks(pos);
            this.propagate('start', this.oldPosition);
           
            anim = (typeof anim == 'undefined') ? o.animate : anim;
            if (anim) {
                //dirty break recursion
                animOp = animOp ||
                {};
                animOp = $.extend({}, o.animateOptions, {
                    slide: this
                }, animOp);
                var animCss = (scroll == 'scrollTop') ? {
                    scrollTop: pos,
                    uiscrollerComplete: pos
                } : {
                    scrollLeft: pos,
                    uiscrollerComplete: pos
                };
                this.hidingWrapper.stop().animate(animCss, animOp);
            }
            else {
                this.hidingWrapper.stop()[0][scroll] = pos;
                this.propagate('end');
            }
        },
        ui: function(){
            return {
                instance: this,
                options: this.options,
                pos: this.position,
                percentPos: this.percentage,
                oldIndex: this.oldAtomPos,
                newIndex: this.atomPos,
                size: this.dims.length - 2
            };
        },
        propagate: function(n, pos){
            var args = (pos || pos === 0) ? [$.extend({}, this.ui(), {
                'pos': pos,
                percentPos: pos / (this.maxPos / 100)
            })] : [this.ui()];
            this.element.triggerHandler("uiscroller" + n, args);
        }
});
$.ui.scroller.defaults = {
 //Wrapper Classes:
        hidingWrapper: 'div.stage',
        moveWrapper: 'div.stage-design',
        //Elements Classes
        atoms: 'div.teaser',
        nextLink: 'a.next',
        prevLink: 'a.prev',
        activeLinkClass: 'show',
        linkFn: function(){
        },
        //animate
        animate: true,
        animateOptions: {
            duration: 800
        },
        hidingWidth: false,
        hidingHeight: false,
        moveStep: 'atom',
        direction: 'horizontal',
        pagination: false,
        paginationAtoms: '<li class="pa-$number"><a href="#">$number</a></li>',
        paginationTitleFrom: false,
        activePaginationClass: 'on',
        paginationFn: false,
        diashow: false,
        addSubPixel: 0
};
    $.extend($.fx.step, {
        uiscrollerComplete: function(fx){
            if (fx.now || fx.now === 0) {
                var scroller = fx.options.slide;
                if (scroller) {
                    scroller.propagate('slide', scroller.hidingWrapper[0][scroller.options.direction.scroll]);
                }
            }
        }
    });
})(jQuery);
