iw.vFix = {

    init : function( selector, minTopPosition ) {

        if (typeof minTopPosition == 'undefined') minTopPosition = 100;
        $( selector ).each(function( i ) {
            var _this = $(this);
            var offset = _this.offset();
            this.__iw_vFix = {
                offsetTop : offset.top,
                top : parseInt(_this.css('top').replace(/px/, '')),
                windowTop : minTopPosition,
                offsetLeft : offset.left,
                left : parseInt(_this.css('left').replace(/px/, ''))
            };
            $(this).addClass('__vFix');
        });

        $(window).bind('scroll', function(e){
            iw.vFix.windowScroll( e );
        });

    },

    windowScroll : function ( e ) {

        $( '.__vFix' ).each(function(i) {
            if ($.browser.msie) {
            } else {
                if (this.style.position == 'fixed') {
                    if ( $(this).offset().top < this.__iw_vFix.offsetTop ) {
                        this.style.position = 'absolute';
                        this.style.top = this.__iw_vFix.top + 'px';
                        this.style.left = this.__iw_vFix.left + 'px';
                    }
                } else {
                    var scrollY = iw.viewport.scrollY();
                    if (this.__iw_vFix.offsetTop - scrollY < this.__iw_vFix.windowTop) {
                        this.style.position = 'fixed';
                        //this.style.top = (scrollY + this.__iw_vFix.windowTop - (this.__iw_vFix.offsetTop - this.__iw_vFix.top)) + 'px';
                        this.style.top = this.__iw_vFix.windowTop + 'px';
                        this.style.left = this.__iw_vFix.offsetLeft + 'px';
                    }
                }
            }
        });

    }

};

iw.scroller = {

    scroller : null,
    wrapper : null,
    content : null,
    scrollLine : null,
    vars : {
        wrapperWidth : 0,
        contentWidth : 0,
        scrollWidth : 0,
        scrollButtonWidth : 0,
        scrollOffsetLeft : 0,
        maxScrollLeft : 0,
        currentContentScroll : 0
    },
    mouseX : 0,
    mouseMoveFunction : null,
    mouseUpFunction : null,
    autoScrollTimer : null,

    init : function( scroller ) {

        this.scroller = $( scroller );
        this.scroller.find('a').bind('focus', function() { this.blur(); });
        if (!this.scroller.length) return;

        this.scroller.find('div.scroller-wrapper').mousedown(function( e ) {
            iw.scroller.mouseDown( this, e );
            return false;
        }).click(function( e ) {
            iw.scroller.mouseClick( this, e );
            return false;
        });
        this.scroller.find('.scroll-left div').mouseover(function( e ) {
            iw.scroller.mouseOver( this, e, 'left' );
        }).mouseout( function( e ) {
            iw.scroller.mouseOut( this, e );
        });
        this.scroller.find('.scroll-right div').mouseover(function( e ) {
            iw.scroller.mouseOver( this, e, 'right' );
        }).mouseout( function( e ) {
            iw.scroller.mouseOut( this, e );
        });
        $(window).resize(function(){
            iw.scroller.updateVars();
            iw.scroller.setScrollPosition();
        });
        this.updateVars();
        this.setScrollPosition(10000);
    },

    setScrollerFromChild : function( _this ) {
        this.scroller = $( _this ).parents('#scroller:first');
        this.updateVars();
    },

    updateVars : function() {
        this.wrapper = this.scroller.find('div.scroll-wrapper');
        this.content = this.scroller.find('div.scroll-content');
        this.scrollLine = this.scroller.find('div.scroller-wrapper');
        this.scrollButton = this.scroller.find('div.scroller-wrapper div.scroller');
        this.vars.wrapperWidth = this.wrapper.width();
        this.vars.contentWidth = this.content.width();
        this.vars.scrollWidth = this.scrollLine.width();
        this.vars.scrollOffsetLeft = this.scrollLine.offset().left;
        this.vars.scrollButtonWidth = this.scrollButton.width();
        this.vars.maxScrollLeft = this.vars.contentWidth - this.vars.wrapperWidth;
    },

    mouseDown : function( _this, e ) {
        this.setScrollerFromChild( _this );
        clearInterval( this.autoScrollTimer );
        this.mouseMoveFunction = function( e ) {
            iw.scroller.mouseMove( e );
        }
        this.mouseUpFunction = function( e ) {
            iw.scroller.mouseUp( e );
        }
        $( document ).bind('mousemove', this.mouseMoveFunction );
        $( document ).bind('mouseup', this.mouseUpFunction );
    },

    mouseClick : function( _this, e ) {
        this.setScrollerFromChild( _this );
        var newX = e.clientX - this.vars.scrollOffsetLeft;
        newX -= Math.round( this.vars.scrollButtonWidth / 2 );
        this.scrollToPosition( newX );
    },

    scrollToPosition : function( newX ) {
        if (this.vars.wrapperWidth >= this.vars.contentWidth) return false;
        if (newX < 0) newX = 0;
        if (newX > this.vars.scrollWidth - this.vars.scrollButtonWidth) newX = this.vars.scrollWidth - this.vars.scrollButtonWidth;
        clearInterval( this.autoScrollTimer );
        this.autoScrollTimer = setInterval(function() {
            var left = iw.scroller.scrollButton.offset().left - iw.scroller.vars.scrollOffsetLeft;
            var diff = Math.ceil((Math.abs(left - newX) / iw.scroller.vars.scrollWidth) * 100);
            if (diff < 1) diff = 1;
            left = (newX > left ? left + diff : left - diff );
            iw.scroller.setScrollPosition( left );
            var dt = new Date();
            //window.status = 'need: ' + newX + ', left: ' + left + ', ' + diff + ', ' + dt.getTime();
            if (left == newX) {
                clearInterval( iw.scroller.autoScrollTimer );
                //window.status = 'cleared';
            }
        }, 15 );
    },

    mouseUp : function( e ) {
        $( document ).unbind('mousemove', this.mouseMoveFunction );
        $( document ).unbind('mouseup', this.mouseUpFunction );
    },

    mouseMove : function( e ) {
        var newX = e.clientX - this.vars.scrollOffsetLeft;
        newX -= Math.round( this.vars.scrollButtonWidth / 2 );
        this.setScrollPosition( newX );
    },

    mouseOver : function( _this, e, d ) {
        this.setScrollerFromChild( _this );
        clearInterval( this.autoScrollTimer );
        this.autoScrollTimer = setInterval(function() {
            var left = iw.scroller.scrollButton.offset().left - iw.scroller.vars.scrollOffsetLeft;
            left = (d == 'left' ? left - 3 : left + 3);
            iw.scroller.setScrollPosition( left );
        }, 15 );
    },

    mouseOut : function( _this, e ) {
        this.setScrollerFromChild( _this );
        clearInterval( this.autoScrollTimer );
    },

    setScrollPosition : function( newX ) {
        //if (this.vars.wrapperWidth >= this.vars.contentWidth) return false;
        if (typeof newX == 'undefined') {
            if (this.scrollButton.offset().left > this.vars.scrollWidth - this.vars.scrollButtonWidth)
                newX = this.vars.scrollWidth - this.vars.scrollButtonWidth;
        } else {
            if (newX < 0 ) newX = 0;
            else if (newX > this.vars.scrollWidth - this.vars.scrollButtonWidth) newX = this.vars.scrollWidth - this.vars.scrollButtonWidth;
        }
        this.scrollButton.css('left', newX);
        //alert( newX / (this.vars.scrollWidth - this.vars.scrollButtonWidth) );
        this.setContentPosition( newX / (this.vars.scrollWidth - this.vars.scrollButtonWidth ) );
    },

    setContentPosition : function( percent ) {
        if (this.vars.wrapperWidth >= this.vars.contentWidth) return false;
        if (this.vars.maxScrollLeft <= 0 ) return;
        var newX = this.vars.maxScrollLeft * percent;
        if (newX < 0) newX = 0;
        if (newX > this.vars.maxScrollLeft) newX = this.vars.maxScrollLeft;
        newX = Math.round( newX );
        //alert( newX );
        this.vars.currentContentScroll = newX;
        this.wrapper.attr( 'scrollLeft', newX );

    },

    undisable : function( parent ) {
        this.setScrollerFromChild( parent );
        this.scroller.find('.disabled').removeClass('disabled');
    },

    getLinkByI : function( i ) {
        var link = this.scroller.find('#object-i-'+i).parent().find('a:first');

        var newOffsetLeft = Math.round(this.vars.wrapperWidth / 2 - link.width() / 2);
        var scrollLeft = link.offset().left + this.vars.currentContentScroll - this.vars.scrollOffsetLeft - newOffsetLeft;
        newX = Math.round(( scrollLeft / this.vars.maxScrollLeft ) * (this.vars.scrollWidth - this.vars.scrollButtonWidth ) );
        this.scrollToPosition( newX );

        return link.length ? link.get(0) : false;
    }

};

iw.objector = {

    objectsFull : {},
    objectsPart : {},

    reverse : false,

    currentObject : null,
    leftObject : null,
    rightObject : null,
    currentObjectID : 0,
    currentObjectI : 0,
    maxObjectI : 0,
    objectURL : '',

    init : function() {

        var ar = null;
        if (ar = window.location.hash.match('object:([0-9]+)')) {
            if (ar[1] > 0) {
                if (window.location.pathname.match('/o:[0-9]+')) {
                    window.location.href = window.location.protocol + '//'+ window.location.host + window.location.pathname.replace(/\/o:[0-9]+/, '/o:'+ar[1]);
                } else {
                    window.location.href = window.location.protocol + '//'+ window.location.host + window.location.pathname.replace(/\/$/, '') + '/o:'+ar[1] + '/';
                }
            }
        }

        this.currentObject = $('#current-object');
        this.leftObject = $('#left-object');
        this.rightObject = $('#right-object');
    },

    getIDByI : function( i ) {
        var ID = $('#object-i-'+i).parents('.object:first').attr('ID');
        if (!ID) return false;
        var reg = /(\d+)$/;
        var res = reg.exec( ID );
        ID = res[0];
        return ID;
    },

    setObjectData : function( ID, html, isFull ) {

        // object caching disabled
        return false;

        if (typeof isFull == 'undefined') isFull = true;
        var stock = (isFull) ? this.objectsFull : this.objectsPart;
        if (typeof stock[ID] == 'undefined') {
            stock[ID] = html;
        }
    },

    loadCurrent : function( i, _parent ) {
        if (typeof (_parent) == 'undefined') {
            _parent = iw.scroller.getLinkByI( i );
        }
        if (!_parent) return false;
        if ($(_parent).hasClass('disabled')) return false;
        //this.setObjectData( this.currentObjectID, this.currentObject.html() );
        var ID = this.getIDByI( i );
        if (!ID) return false;
        if (!this.currentObjectID) { //not inited class objector -> refresh page
            window.location.href =  './o:' + ID + '/';
            return false;
        }
        var self = this.currentObject;
        var setVars = function() {
            iw.scroller.undisable( _parent );
            $(_parent).addClass('disabled').parents('table:first').addClass('disabled');
            iw.objector.currentObjectID = ID;
            iw.objector.currentObjectI = i;
            iw.objector.loadLeft( iw.objector.reverse ? -1 : +1 );
            iw.objector.loadRight( iw.objector.reverse ? +1 : -1 );
            window.location.hash = 'object:'+iw.objector.currentObjectID;
        };
        iw.preloader.show('#current-object');
        if (typeof iw.objector.objectsFull[ID] != 'undefined') {
            self.html( iw.objector.objectsFull[ID] );
            iw.preloader.hide('#current-object');
            self.fadeIn();
            setVars();
        } else {
            $.ajax({
                complete: function() {
                    iw.preloader.hide('#current-object');
                    self.fadeIn();
                },
                url : settings.url + '/object/' + iw.objector.objectURL + '/' + ID + '/',
                type : 'GET',
                dataType : 'text',
                success : function( responseText, statusText ) {
                    var html = iw.functions.getAjaxBody( responseText );
                    iw.objector.setObjectData( ID, html );
                    self.html( html );
                    setVars();
                }
            });
        }
    },

    loadLeft: function( shift ) {
        if (!shift) shift = this.reverse ? -1 : +1 ;
        var i = this.currentObjectI;
        i += shift;
        if (i > this.maxObjectI) i = 1;
        if (i < 1) i = this.maxObjectI;
        if (i == this.currentObjectI) return false;
        var ID = this.getIDByI( i );
        var self = this.leftObject;
        if (!ID) {
            self.fadeOut();
            return false;
        }
        self.fadeOut('fast', function() {
            if (typeof iw.objector.objectsPart[ID] != 'undefined') {
                self.html( iw.objector.objectsPart[ID] );
                self.fadeIn('fast');
            } else {
                $.ajax({
                    complete: function() {
                        self.fadeIn('fast');
                    },
                    url : settings.url + '/object/' + iw.objector.objectURL + '/' + ID + '/?no-comments',
                    type : 'GET',
                    dataType : 'text',
                    success : function( responseText, statusText ) {
                        var html = iw.functions.getAjaxBody( responseText );
                        iw.objector.setObjectData( ID, html, false );
                        self.html( html );
                    }
                });
            }
        });
    },

    loadRight: function( shift ) {
        if (!shift) shift = this.reverse ? +1 : -1;
        var i = this.currentObjectI;
        i += shift;
        if (i > this.maxObjectI) i = 1;
        if (i < 1) i = this.maxObjectI;
        if (i == this.currentObjectI) return false;
        var ID = this.getIDByI( i );
        var self = this.rightObject;
        if (!ID) {
            self.fadeOut();
            return false;
        }
        self.fadeOut('fast', function() {
            if (typeof iw.objector.objectsPart[ID] != 'undefined') {
                self.html( iw.objector.objectsPart[ID] );
                self.fadeIn('fast');
            } else {
                $.ajax({
                    complete: function() {
                        self.fadeIn('fast');
                    },
                    url : settings.url + '/object/' + iw.objector.objectURL + '/' + ID + '/?no-comments',
                    type : 'GET',
                    dataType : 'text',
                    success : function( responseText, statusText ) {
                        var html = iw.functions.getAjaxBody( responseText );
                        iw.objector.setObjectData( ID, html, false );
                        self.html( html );
                    }
                });
            }
        });
    },

    setLeft : function() {
        this.setChange( this.reverse ? -1 : +1 );
        return;
        /*
        var newI = this.currentObjectI + 1;
        if (newI > this.maxObjectI) newI = 1;
        this.loadCurrent( newI );
        */
    },

    setRight : function() {
        this.setChange( this.reverse ? +1 : -1 );
        return;
        /*
        var newI = this.currentObjectI - 1;
        if (newI < 1) newI = this.maxObjectI;
        this.loadCurrent( newI );
        */
    },

    setChange : function( shift ) {
        if (!shift || typeof shift == 'undefined') shift = 0;
        var newI = this.currentObjectI + shift;
        if (newI > this.maxObjectI) newI = 1;
        if (newI < 1) newI = this.maxObjectI;
        this.loadCurrent( newI );
    }

};
