Your IP : 18.219.40.177


Current Path : /usr/local/mgr5/skins/orion/src/
Upload File :
Current File : //usr/local/mgr5/skins/orion/src/scroll.js

/**
 * ScrollHandler
 * @class
 */
var ScrollHandler = (function() {
  'use strict';
  var shiftY = 0,

      shiftX = 0,

      SCROLLBAR_INIT_CLASS = 'scrollbar-init',

      VERTICAL_SCROLL_CLASS = 'vertical-scroll',

      bigObj = {},
      /**
       * Current Scroll object
       */
      curObj = {
        /**
         * Object id
         */
        objId: null,
        /**
         * Wrapper id
         */
        contId: null,
        /**
         * Wrapper id
         */
        obj: null,
        /**
         * HTML Object of Object
         */
        cont: null,
        /**
         * HTML Object of ScrollHandler
         */
        sh: null,
        /**
         * Visible height (wrapper's height)
         */
        vh: null,
        /**
         * Scroll handler height
         */
        sch: null
      },

      moveObj = {}, //temp object moved elems
      down = false, //go down
      /* jslint evil:true */
      isIe = !!window.execScript,
      /* jslint evil:false */
      up = false, // go up
      left = false, //go left
      right = false,  //go right
      intId = null,
      /**
       * Block not needed events when scrolling
       */
      blockEvent = function(e) {
        e = e || window.event;
        if (e.stopPropagation) {
          e.stopPropagation();
        } else { e.cancelBubble = true; }
        if (e.preventDefault) {
          e.preventDefault();
        } else { e.returnValue = false; }
      },
      /**
       * Handler for mouseup
       * unbind mouseup/touchend handlers
       */
      mouseUp = function() {
        down = false;
        up = false;
        left = false;
        right = false;
        document.onmouseup = null;
        document.ontouchend = null;
      },
      /**
       * Set Position for object and scrollhandler
       */
      lastValues = {},

      setPosition = function(newPosition) {
        var sTop, scrollTop,
            middle = false,
            top = false,
            bottom = false;
        if ((newPosition <= moveObj.vh - moveObj.sch) && (newPosition >= 0)) {
          sTop = newPosition;
          middle = true;
        } else if (newPosition > moveObj.vh - moveObj.sch) {
          sTop = moveObj.vh - moveObj.sch;
          bottom = true;
        } else {
          sTop = 0;
          top = true;
        }

        moveObj.sh.style.top = sTop + 'px';
        scrollTop = Math.round(sTop * moveObj.delta);
        if (isIe) {
          moveObj.cont.scrollTop = 0;
          moveObj.obj.style.marginTop = scrollTop * (-1) + 'px';
        } else {
          moveObj.cont.scrollTop = scrollTop;
          moveObj.sw.style.top = scrollTop + 'px';
        }
        if (lastValues[moveObj.contId] !== sTop) {
          var body = document.querySelector('body') || document.body,
              event;
          try {
            event = new CustomEvent('verticalScroll', { 'detail': {
                top: top,
                middle: middle,
                bottom: bottom,
                id: moveObj.contId}});
            body.dispatchEvent(event);
          } catch (e) {}
        }
        lastValues[moveObj.contId] = sTop;
        return false;
      },
      /**
       * Set Position for horizontal object and scrollhandler
       */
      setPositionHor = function(newPosition) {
        var sLeft, scrollLeft;
        if ((newPosition <= moveObj.vw - moveObj.schH) && (newPosition >= 0)) {
          sLeft = newPosition;
        } else if (newPosition > moveObj.vw - moveObj.schH) {
          sLeft = moveObj.vw - moveObj.schH;
        } else {
          sLeft = 0;
        }
        moveObj.hSh.style.left = sLeft + 'px';
        scrollLeft = Math.round(sLeft * moveObj.deltaH);

        if (isIe) {
          moveObj.cont.scrollLeft = 0;
          moveObj.obj.style.marginLeft = scrollLeft * (-1) + 'px';
        } else {
          moveObj.cont.scrollLeft = scrollLeft;
          moveObj.hSw.style.left = scrollLeft + 'px';
        }
        return false;
      },
      /**
       * Mouse wheel handler
       */
      wheel = function(e) {
        e = e || window.event;
        var wheelDelta = 0,
            id = this.getAttribute('id'),
            currentPosition,
            newPosition,
            direction, delta, STEP = 64;
        moveObj = bigObj[id];
        //check for exist scroll
        if (!moveObj) { return; }
        delta = moveObj.delta;
        //detect direction
        if (e.wheelDelta) {
          direction = e.wheelDelta > 0 ? -1 : 1;
        } else if (e.detail) {
          direction = e.detail < 0 ? -1 : 1;
        }
        //check for native scroll
        if (e.target) {
          var target = e.target;
          //check for scroll
          //target.clientHeight > 0 ==> for opera
          if (target.clientHeight < target.scrollHeight &&
              target.clientHeight > 0 &&
              target.nodeName === 'TEXTAREA') {
            //scroll down
            if (
                //(target.clientHeight + 1) ==> for safari
                (direction === 1 && (target.scrollTop <
                    (target.scrollHeight - (target.clientHeight + 1)))) ||
                (direction === -1 && target.scrollTop !== 0)
                ) {
                  return true;
            }
          }
        }

        if (e.wheelDelta) {
          wheelDelta = -e.wheelDelta / 2.5;
        } else if (e.detail) { //for FF
          wheelDelta = e.detail * 16;
        }

        if (wheelDelta) {
          currentPosition = parseFloat(moveObj.sh.style.top);
          newPosition = ((wheelDelta / delta)) + currentPosition;
          setPosition(newPosition);
        }
        blockEvent(e);
      },
      /**
       * Scroll mover by UP/DOWN scroll btn
       */
      scrollMove = function(stopPos) {
        var currentPosition, mDelta, newPosition, magicNumber = 5;
        if (!moveObj) {
           clearInterval(intId);
        }
        currentPosition = parseFloat(moveObj.sh.style.top);
        mDelta = magicNumber / moveObj.delta;
        if (up) {
          newPosition = currentPosition - mDelta;
          setPosition(newPosition);
          if (stopPos && newPosition < stopPos) {
            clearInterval(intId);
          }
        } else if (down) {
          newPosition = mDelta + currentPosition;
          setPosition(newPosition);
          if (stopPos && newPosition > stopPos) {
            clearInterval(intId);
          }
        } else {
          clearInterval(intId);
        }
      },
      /**
       * Scroll mover horizontal by UP/DOWN scroll btn
       */
      scrollMoveHoriz = function(stopPos) {
        var currentPosition, mDelta, newPosition, magicNumber = 5;
        if (!moveObj) {
           clearInterval(intId);
        }
        currentPosition = parseFloat(moveObj.hSh.style.left);
        mDelta = magicNumber / moveObj.deltaH;
        if (left) {
          newPosition = currentPosition - mDelta;
          setPositionHor(newPosition);
          if (stopPos && newPosition < stopPos) {
            clearInterval(intId);
          }
       } else if (right) {
          newPosition = mDelta + currentPosition;
          setPositionHor(newPosition);
          if (stopPos && newPosition > stopPos) {
            clearInterval(intId);
          }
       } else {
          clearInterval(intId);
        }
      },
      /**
       * Handler for button move up
       */
      moveUp = function(id, stopPos) {
        var doc = document,
            timeOut = stopPos !== undefined ? 1 : 10;
        moveObj = bigObj[id];
        up = true;
        //some issues about
        if (!('ontouchstart' in doc.documentElement)) {
          doc.onmouseup = mouseUp;
        }
        //for touchpads
        doc.ontouchend = mouseUp;
        doc.ontouchcancel = mouseUp;
        scrollMove(stopPos);
        intId = setInterval(function() { scrollMove(stopPos); }, timeOut);
      },

      moveUpHandler = function(e) {
        e = e || window.event;
        var id = this.getAttribute('id').replace('-top-button', '');
        moveUp(id);
        blockEvent(e);
        return false;
      },

      moveLeftHandler = function(e) {
        e = e || window.event;
        var id = this.getAttribute('id').replace('-left-button', '');
        moveLeft(id);
        blockEvent(e);
        return false;
      },

      moveLeft = function(id, stopPos) {
        var doc = document,
            timeOut = stopPos !== undefined ? 1 : 10;
        moveObj = bigObj[id];
        left = true;
        //some issues about
        if (!('ontouchstart' in doc.documentElement)) {
          doc.onmouseup = mouseUp;
        }
        //for touchpads
        doc.ontouchend = mouseUp;
        doc.ontouchcancel = mouseUp;
        scrollMoveHoriz(stopPos);
        intId = setInterval(function() { scrollMoveHoriz(stopPos); }, timeOut);
      },
      /**
       * Handler for button move down
       */
      moveDown = function(id, stopPos) {
        var doc = document,
            timeOut = stopPos !== undefined ? 1 : 10;
        moveObj = bigObj[id];
        down = true;
        if (!('ontouchstart' in doc.documentElement)) {
          doc.onmouseup = mouseUp;
        }
        //for touchpads
        doc.ontouchend = mouseUp;
        doc.ontouchcancel = mouseUp;
        scrollMove(stopPos);
        intId = setInterval(function() { scrollMove(stopPos); }, timeOut);
      },

      moveDownHandler = function(e) {
        e = e || window.event;
        var id = this.getAttribute('id').replace('-bottom-button', '');
        moveDown(id);
        blockEvent(e);
        return false;
      },

      moveRightHandler = function(e) {
        e = e || window.event;
        var id = this.getAttribute('id').replace('-right-button', '');
        moveRight(id);
        blockEvent(e);
        return false;
      },

      moveRight = function(id, stopPos) {
        var doc = document,
            timeOut = stopPos !== undefined ? 1 : 10;
        moveObj = bigObj[id];
        right = true;
        if (!('ontouchstart' in doc.documentElement)) {
          doc.onmouseup = mouseUp;
        }
        //for touchpads
        doc.ontouchend = mouseUp;
        doc.ontouchcancel = mouseUp;
        scrollMoveHoriz(stopPos);
        intId = setInterval(function() { scrollMoveHoriz(stopPos); }, timeOut);
      },
      /**
       * Cancel scroll, hide scroll handler
       * @param {curObj} obj Current object
       */
      cancelScroll = function(obj) {
        if (!obj) { return; }
        //need to fix
        obj.sh.style.display = 'none';
        obj.vstatus = true;
        obj.cont.style.overflowY = '';
        //hide horiz scroll
        if (obj.hs) {
          obj.vstatus = false;
          obj.sw.style.display = 'none';
          obj.cont.style.paddingRight = '0px';
          // $(obj.cont).removeClass('vertical-scroll');
        }
        $(obj.cont).removeClass(VERTICAL_SCROLL_CLASS);
        $(obj.cont.parentNode).removeClass('vertical-scroll-child');
        //this._curObj.sh = null;
        obj.cont.onmousewheel = null;
        obj.bb.onmousedown = null;
        obj.tb.onmousedown = null;
        obj.cont.onkeydown = null;
        if (isIe) {
          obj.obj.style.marginTop = 0;
        }
        obj.cont.scrollTop = 0;
        obj.sh.style.top = 0 + 'px';
        obj.sw.style.top = 0 + 'px';
        if (obj.contWheelEvent) {
          obj.cont.removeEventListener('DOMMouseScroll', wheel, false);
          obj.contWheelEvent = false;
        }
      },
      /**
       * Cancel horiz scroll, hide scroll handler
       * @param {curObj} obj Current object
       */
      cancelScrollHoriz = function(obj) {
         if (!obj) { return; }
        //need to fix
        obj.hSh.style.display = 'none';
        obj.cont.style.overflowX = '';
        obj.hstatus = true;
        if (!obj.hss) {
          obj.hstatus = false;
          obj.hSw.style.display = 'none';
          $(obj.cont).removeClass('horizontal-scroll');
          obj.cont.paddingBottom = '0px';
        }
        //this._curObj.sh = null;
        obj.hBb.onmousedown = null;
        obj.hTb.onmousedown = null;
        if (isIe) {
          obj.obj.style.marginLeft = 0;
        }
        obj.cont.scrollLeft = 0 + 'px';
        obj.hSh.style.top = 0 + 'px';
      },
      /**
       * Update scroll method
       */
      updateFunc = function(key) {
        if (bigObj[key] === undefined) { return; }
        var scrollCorrect = 36, swStyle, tmpHeight, scrollTop, curObjUp;
            curObjUp = bigObj[key];
        curObjUp.cont.className += ' ' + SCROLLBAR_INIT_CLASS;
        if (curObjUp.hstatus) {
          scrollCorrect += 18;
        }
        //trackHeight
        var visibleHeight = curObjUp.cont.clientHeight,
            scrollTrackHeight = visibleHeight - scrollCorrect,
            deltaTop = (curObjUp.obj.offsetTop > 0) ?
                curObjUp.obj.offsetTop : 0,
            allHeight = curObjUp.obj.offsetHeight + deltaTop,
            deltaAV = allHeight / visibleHeight,
            scrollHandlerHeight = scrollTrackHeight / deltaAV,
            delta = allHeight / scrollTrackHeight;
        //if hide element exit
        if (visibleHeight === 0) { return; }
        curObjUp.vh = scrollTrackHeight;
        //all height, object height

        //var sch = (visibleHeight) / (allHeight /
        // (visibleHeight + scrollCorrect));
        if (scrollHandlerHeight < 25) {
          scrollHandlerHeight = 25;
          delta = (allHeight - (scrollTrackHeight + scrollCorrect)) /
              (scrollTrackHeight - 25);
        }
        //size of step
        curObjUp.delta = delta;
        curObjUp.sch = scrollHandlerHeight;
        //check for nothing scroll
        tmpHeight = scrollTrackHeight + scrollCorrect;
        if (scrollTrackHeight < scrollCorrect ||
            scrollHandlerHeight > scrollTrackHeight ||
            tmpHeight === allHeight) {
          cancelScroll(curObjUp);
          //scrollHandlerHeight = scrollTrackHeight;
        } else {
          //set scroll handler size
          swStyle = curObjUp.sw.style;
          //keep state
          curObjUp.cont.scrollTop = parseFloat(swStyle.top);
          //swStyle.top = curObjUp.cont.scrollTop;
          curObjUp.sh.style.height = scrollHandlerHeight + 'px';
          curObjUp.sh.style.display = 'block';
          swStyle.display = 'block';
          curObjUp.cont.style.paddingRight = '18px';
          curObjUp.cont.style.overflowY = 'hidden';
          if (curObjUp.cont.className.indexOf(VERTICAL_SCROLL_CLASS) === -1) {
            curObjUp.cont.className += ' ' + VERTICAL_SCROLL_CLASS;
            curObjUp.cont.parentNode.className += ' vertical-scroll-child';
          }
          if (!curObjUp.contWheelEvent) {
            curObjUp.cont.addEventListener('DOMMouseScroll', wheel, false);
            curObjUp.contWheelEvent = true;
          }

          curObjUp.cont.onmousewheel = wheel;

          curObjUp.bb.onmousedown = moveDownHandler;
          curObjUp.tb.onmousedown = moveUpHandler;

          //check real behavior
          if (parseInt(curObjUp.sh.style.top, 10) + curObjUp.sch >
              curObjUp.vh) {
            curObjUp.sh.style.top = curObjUp.vh - curObjUp.sch + 'px';
            scrollTop = (curObjUp.vh - curObjUp.sch) * curObjUp.delta;
            swStyle.top = scrollTop + 'px';
            curObjUp.cont.scrollTop = scrollTop;
          }
        }
        bigObj[key] = curObjUp;
        curObjUp.cont.className = curObjUp.cont.className.replace(SCROLLBAR_INIT_CLASS, ' ');
        curObjUp = null;
      },
      /**
       * Update horiz scroll method
       */
      updateFuncHoriz = function(key) {
        if (bigObj[key] === undefined) { return; }
        var scrollCorrect = 36,
            curObjUp = bigObj[key],
            vw, aw, delta, sch;
        if (curObjUp.vstatus) {
          scrollCorrect += 18;
        }

        vw = curObjUp.cont.offsetWidth - scrollCorrect;
        curObjUp.vw = vw;
        //ll height, object height
        aw = curObjUp.obj.offsetWidth;
        delta = aw / (vw);
        //scroll height
        sch = (vw) / (aw / (vw + scrollCorrect));

        if (sch < 25) {
          //var dp = 25 - sch;
          sch = 25;
          delta = (aw - (vw + scrollCorrect)) / (vw - 25);
        }
        //size of step
        curObjUp.deltaH = delta;
        curObjUp.schH = sch;
        //check for nothing scroll
        if (vw < scrollCorrect || sch > vw || vw + scrollCorrect === aw) {
          cancelScrollHoriz(curObjUp);
          //sch = vw;
        } else {
          //set scroll handler size
          curObjUp.hSh.style.width = sch + 'px';
          curObjUp.hSw.style.display = 'block';
          curObjUp.hSh.style.display = 'block';
          curObjUp.cont.style.overflowX = 'hidden';
          curObjUp.cont.style.paddingBottom = '18px';

          curObjUp.hBb.onmousedown = moveRightHandler;
          curObjUp.hTb.onmousedown = moveLeftHandler;

         //check real behavior
          if (parseInt(curObjUp.hSh.style.top, 10) + curObjUp.schH >
              curObjUp.vw) {
            curObjUp.hSh.style.left = curObjUp.vw - curObjUp.schH + 'px';
            curObjUp.obj.scrollLeft =
                (curObjUp.vw - curObjUp.schH) * curObjUp.deltaH;
          }
        }
        bigObj[key] = curObjUp;
        curObjUp = null;
      },
      /**
       * void method, update sizes
       */
      update = function(id) {
        if (id) {
          updateFunc(id);
          updateFuncHoriz(id);
        } else {
          var key;
          /* jslint forin:true */
          for (key in bigObj) {
            updateFunc(key);
            updateFuncHoriz(key);
          }
        }
      },
      /**
       * get sizes of objects and calculate delta
       */
      getSize = function() {
        //visible height
        var scrollCorrect = 36,
            visibleHeight = curObj.cont.clientHeight,
            scrollTrackHeight = visibleHeight - scrollCorrect,
            deltaTop = (curObj.obj.offsetTop > 0) ? curObj.obj.offsetTop : 0,
            allHeight = curObj.obj.offsetHeight + deltaTop,
            deltaAV = allHeight / visibleHeight,
            scrollHandlerHeight = scrollTrackHeight / deltaAV,
            delta = allHeight / scrollTrackHeight;

        //-18px for top/bottom buttons
        curObj.vh = scrollTrackHeight;
        curObj.delta = delta;
        //scroll height
        curObj.sch = scrollHandlerHeight;

        //check for nothing scroll
        if (scrollTrackHeight < 36 ||
            scrollHandlerHeight > scrollTrackHeight ||
            ((scrollTrackHeight + 36) === allHeight)) {
          cancelScroll(curObj);
        } else {
          curObj.vstatus = true;
          curObj.cont.className += ' ' + VERTICAL_SCROLL_CLASS;
          curObj.cont.parentNode.className += ' vertical-scroll-child';
          if (scrollHandlerHeight < 25) {
            scrollHandlerHeight = 25;
          }
          //set scroll handler size
          curObj.sh.style.height = scrollHandlerHeight + 'px';
          curObj.sh.style.left = 0;
          curObj.cont.scrollTop = 0;
          curObj.cont.style.paddingRight = '18px';
          curObj.cont.style.overflowY = 'hidden';
        }
        curObj.cont.className = curObj.cont.className.replace(SCROLLBAR_INIT_CLASS, ' ');
      },

      getSizeHor = function() {
        //visible height
        var visibleWidth = curObj.cont.offsetWidth - 36,
            //all height, object height
            aw = curObj.obj.offsetWidth,
            //size of step
            delta = aw / (visibleWidth),
            sch;

        //-20px for top/bottom buttons
        curObj.vw = visibleWidth;
        curObj.deltaH = delta;
        //scroll height
        sch = (visibleWidth) / (aw / (visibleWidth + 36));
        curObj.schH = sch;

        //check for nothing scroll
        if (visibleWidth < 36 ||
            sch > visibleWidth ||
            visibleWidth + 36 === aw) {
          cancelScrollHoriz(curObj);
          sch = visibleWidth;
        } else {
          curObj.hstatus = true;
          curObj.cont.className += ' horizontal-scroll';
          if (sch < 25) {
            sch = 25;
          }
          //set scroll handler size
          curObj.hSh.style.width = sch + 'px';
          curObj.hSh.style.left = 0;
          curObj.hSw.style.display = 'block';
          curObj.cont.scrollLeft = 0;
          curObj.cont.style.paddingBottom = '18px';
          curObj.cont.style.overflowX = 'hidden';
        }
        curObj.cont.className = curObj.cont.className.replace(SCROLLBAR_INIT_CLASS, ' ');
      },

      forceMoveSelectItem = function(id, offsetTop, boxHeight, elemHeight) {
        moveObj = bigObj[id];
        if (!moveObj) { return; }
        var boxHeight =  boxHeight || 223,
            elemHeight = elemHeight || 16,
            newPosition = null,
            mTRaw = moveObj.cont.scrollTop,
            mT = 0,
            df;
        if (mTRaw !== '') {
          mT = parseFloat(mTRaw);
        }
        df = offsetTop - mT;
        if (boxHeight < df) {
          //movedown
          if (boxHeight < (df - 17)) {
            newPosition = (offsetTop) / moveObj.delta;
          } else {
            newPosition = (mT + elemHeight) / moveObj.delta;
          }
        } else if (df < 0) {
          //moveup
          newPosition = (mT - elemHeight) / moveObj.delta;
        }
        if (newPosition !== null) {
          setPosition(newPosition);
        }
      },

      TABKEY = 9,
      /**
       * force mov
       */
      forceMove = function(id) {
        if (!id) { return; }
        moveObj = bigObj[id];
        var scrollTop = moveObj.cont.scrollTop,
            newPosition = scrollTop / moveObj.delta;
        setPosition(newPosition);
      },

      checkTabKeyUp = function(e) {
        e = e || window.event;
        var codeKey, contId;
            codeKey = e.which || e.keyCode;
        if (codeKey === TABKEY) {
          contId = $(e.target || e.srcElement)
              .parents('div.' + VERTICAL_SCROLL_CLASS)
              .attr('id');
          forceMove(contId);
        }
      },
      animate = function(opts) {
        var start = new Date(),
            timer = setInterval(function() {
              var progress = (new Date() - start) / opts.duration;
              if (progress > 1) { progress = 1; }
              opts.step(progress);
              if (progress === 1) {
                clearInterval(timer);
              }
            }, opts.delay || 10);
      },

      animateMove = function(to, from) {
        from = from || 0;
        animate({
          duration: 350,
          step: function(progress) {
            //var newPos =  (1 - Math.sin(Math.acos(progress))) * to;
            var newPos = from + (Math.pow(progress, 2)) * to;
            setPosition(newPos);
          }
        });
      },
      /**
       * set scrollTop
       * @param {string} id  scroll contId
       * @param {number} offset Offset to move
       * @param {number} raw Raw value to Move in offset param
       * @param {boolean|undefined} animate Scrolling with animate
       */
      scrollTo = function(id, offset, raw, animate) {
        if (!id) { return; }
        moveObj = bigObj[id];
        if (!moveObj) { return; }
        var newPosition = 0,
            from = parseFloat(moveObj.sh.style.top) || 0;
        if (!raw) {
          newPosition = offset / moveObj.delta;
        } else {
          newPosition = offset;
        }
        if (!animate) {
          setPosition(newPosition);
        } else {
          newPosition -= from;
          animateMove(newPosition, from);
        }
      },
      /**
       * Handler for mouseup
       * unbind mousemove and mouseup
       */
      drop = function() {
        moveObj = null;
        document.onmousemove = null;
        document.onmouseup = null;
      },
      /**
       * Handler for touchend
       * unbind ontouchmove and touchend
       */
      tDrop = function() {
        moveObj = null;
        document.ontouchmove = null;
        document.ontouchend = null;
        document.ontouchcancel = null;
      },
      /**
       * Handler for move
       */
      move = function(e) {
        e = e || window.event;
        setPosition(e.clientY - shiftY);
        blockEvent(e);
        return false;
      },
      /**
       * Handler for move horizontal
       */
      moveHor = function(e) {
        e = e || window.event;
        setPositionHor(e.clientX - shiftX);
        blockEvent(e);
        return false;
      },
      /**
       * Handler for touchmove
       */
      tMove = function(e) {
        e = e || window.event;
        setPosition(e.touches[0].pageY - shiftY);
        blockEvent(e);
        return false;
      },
      /**
       * Handler for touchmove horizontal
       */
      tMoveHor = function(e) {
        e = e || window.event;
        setPositionHor(e.touches[0].pageX - shiftX);
        blockEvent(e);
        return false;
      },
      /**
       * Handler for mousedown for scrollhandler
       * bind handlers for touchmove, touchend
       */
      drag = function(e) {
        e = e || window.event;
        var id, doc, top;
        id = this.getAttribute('id').replace('-scrollbar-handler', '');
        top = this.style.top === '' ? 0 : parseFloat(this.style.top);
        shiftY = e.clientY - top;
        doc = document;
        moveObj = bigObj[id];
        doc.onmousemove = move;
        doc.onmouseup = drop;
        blockEvent(e);
        return false;
      },
      /**
       * Handler for mousedown for scrollhandler horizontal
       * bind handlers for touchmove, touchend
       */
      dragHor = function(e) {
        e = e || window.event;
        var id, doc, left;
        id = this.getAttribute('id').replace('-scrollbar-handler-horiz', '');
        left = this.style.left === '' ? 0 : parseFloat(this.style.left);
        shiftX = e.clientX - left;
        moveObj = bigObj[id];
        doc = document;
        doc.onmousemove = moveHor;
        doc.onmouseup = drop;
        blockEvent(e);
        return false;
      },
      /**
       * Handler for touchstart for scrollhandler
       * bind handlers for touchmove, touchend
       */
      tDrag = function(e) {
        e = e || window.event;
        var id, doc, top;
        id = this.getAttribute('id').replace('-scrollbar-handler', '');
        top = this.style.top === '' ? 0 : parseFloat(this.style.top);
        shiftY = e.touches[0].pageY - top;
        moveObj = bigObj[id];
        doc = document;
        doc.ontouchmove = tMove;
        doc.ontouchend = tDrop;
        doc.ontouchcancel = tDrop;
        blockEvent(e);
        return false;
      },
      /**
       * Handler for touchstart for scrollhandler horizontal
       * bind handlers for touchmove, touchend
       */
      tDragHor = function(e) {
        e = e || window.event;
        var id, doc, left;
        id = this.getAttribute('id').replace('-scrollbar-handler-horiz', '');
        left = this.style.left === '' ? 0 : parseFloat(this.style.left);
        shiftX = e.touches[0].pageX - left;
        moveObj = bigObj[id];
        doc = document;
        doc.ontouchmove = tMoveHor;
        doc.ontouchend = tDrop;
        doc.ontouchcancel = tDrop;
        blockEvent(e);
        return false;
      },
      /**
       * Scroll by scroll track click
       */
      scrollTrackMDHandler = function(e) {
        var id = String(this.getAttribute('id')).replace('-scrollbar-track', ''),
            sbh = document.getElementById(id + '-scrollbar-handler'),
            offsetY, offsetX,
            offsetST,
            horizScroll = false;
        if (!sbh) {
          id = String(this.getAttribute('id')).replace('-scrollbar-track-horiz', '');
          sbh = document.getElementById(id + '-scrollbar-handler-horiz');
          if (!sbh) {
            return;
          }
          horizScroll = true;
        }
        if (!horizScroll) {
          var borderTop = parseInt(sbh.style.top, 10),
              borderBottom = parseInt(sbh.style.height, 10);
          if (e.offsetX && e.offsetY) {
            offsetY = e.offsetY;
          } else {
            offsetST = $(this).offset();
            offsetY = e.clientY - offsetST.top;
          }
          if (offsetY < borderTop) {
            //direction up
            moveUp(id, offsetY);
          } else if (offsetY > borderBottom) {
            //direction down
            moveDown(id, offsetY - borderBottom);
          }
        } else {
          var borderLeft = parseInt(sbh.style.left, 10),
              borderRight = parseInt(sbh.style.width, 10);
          if (e.offsetX && e.offsetY) {
            offsetX = e.offsetX;
          } else {
            offsetST = $(this).offset();
            offsetX = e.clientX - offsetST.left;
          }
          if (offsetX < borderLeft) {
            //direction up
            moveLeft(id, offsetX);
          } else if (offsetX > borderRight) {
            //direction down
            moveRight(id, offsetX - borderRight);
          }
        }
      },
      /**
       * Bind handler for scrollhandler on mousedown and touchstart events
       */
      bindEvent = function() {
        if (curObj.sh) {
          curObj.sh.onmousedown = drag;
          curObj.sh.ontouchstart = tDrag;
          var contElem = curObj.cont;

          contElem.onkeyup = function(e) {
            checkTabKeyUp(e);
          };
          contElem = null;
        }
        if (curObj.hSh) {
          curObj.hSh.onmousedown = dragHor;
          curObj.hSh.ontouchstart = tDragHor;
        }
      },

      /**
       * void method for build scroll
       */
      buildScroll = function() {
        //@TODO might be add class?
        curObj.cont.style.overflowY = 'hidden';
        curObj.cont.style.position = 'relative';
        curObj.cont.className += ' ' + SCROLLBAR_INIT_CLASS;
        var sw, divId, tb, trt, st, sh, ln, lns, bb, trb;

        //create scroll wrapper
        sw = document.createElement('div');
        divId = curObj.contId + '-scrollbar-wrapper';
        sw.setAttribute('id', divId);
        sw.setAttribute('class', 'scrollbar-wrapper scrlbr');

        curObj.cont.appendChild(sw);

        //create scroll button top
        tb = document.createElement('div');
        tb.setAttribute('id', curObj.contId + '-top-button');
        tb.setAttribute('class', 'top-button scrlbr');
        sw.appendChild(tb);

        trt = document.createElement('div');
        trt.setAttribute('class', 'triangl-top scrlbr');
        tb.appendChild(trt);

        //create scroll button scrollbar-track
        st = document.createElement('div');
        st.setAttribute('id', curObj.contId + '-scrollbar-track');
        st.setAttribute('class', 'scrollbar-track scrlbr');
        sw.appendChild(st);
        //create scroll button scrollbar-handler
        sh = document.createElement('div');
        sh.setAttribute('id', curObj.contId + '-scrollbar-handler');
        sh.setAttribute('class', 'scrollbar-handler scrlbr');

        curObj.st = st;
        curObj.sh = sh;

        st.appendChild(sh);

        //create scroll button scrollbar-handler
        ln = document.createElement('div');
        ln.setAttribute('class', 'scrollbar-lines scrlbr');

        lns = document.createElement('div');
        lns.setAttribute('class', 'scrollbar-line scrlbr');

        ln.appendChild(lns);

        sh.appendChild(ln);

        //create scroll button bottom
        bb = document.createElement('div');
        bb.setAttribute('id', curObj.contId + '-bottom-button');
        bb.setAttribute('class', 'bottom-button scrlbr');
        sw.appendChild(bb);

        trb = document.createElement('div');
        trb.setAttribute('class', 'triangl-bot scrlbr');
        bb.appendChild(trb);

        curObj.sw = sw;
        curObj.bb = bb;
        curObj.tb = tb;

        if (curObj.sh !== null) {
          //for mouse wheel
          if (curObj.cont.addEventListener) {
            curObj.cont.addEventListener('DOMMouseScroll', wheel, false);
            curObj.contWheelEvent = true;
            curObj.st.addEventListener('mousedown', scrollTrackMDHandler, false);
          }
          curObj.cont.onmousewheel = wheel;
          //for button up/down scroll!!!
          if (!('ontouchstart' in document.documentElement)) {
            bb.onmousedown = moveDownHandler;
            tb.onmousedown = moveUpHandler;
          }
          //for touchpads
          bb.ontouchstart = moveDownHandler;
          tb.ontouchstart = moveUpHandler;
        }
        getSize();
      },

      buildHorizScroll = function() {
        curObj.cont.style.overflowX = 'hidden';
        curObj.cont.style.position = 'relative';

        //create scroll wrapper
        var sw, divId, tb, trt, st, sh, ln, lns, bb, trb;

        divId = curObj.contId + '-scrollbar-wrapper-horiz';
        sw = document.createElement('div');
        sw.setAttribute('id', divId);
        sw.setAttribute('class', 'scrollbar-wrapper-horiz scrlbr');

        curObj.cont.appendChild(sw);

        //create scroll button top
        tb = document.createElement('div');
        tb.setAttribute('id', curObj.contId + '-left-button');
        tb.setAttribute('class', 'left-button scrlbr');
        sw.appendChild(tb);

        trt = document.createElement('div');
        trt.setAttribute('class', 'triangl-left scrlbr');
        tb.appendChild(trt);

        //create scroll button scrollbar-track
        st = document.createElement('div');
        st.setAttribute('id', curObj.contId + '-scrollbar-track-horiz');
        st.setAttribute('class', 'scrollbar-track-horiz scrlbr');
        sw.appendChild(st);
        curObj.st = st;
        //create scroll button scrollbar-handler
        sh = document.createElement('div');
        sh.setAttribute('id', curObj.contId + '-scrollbar-handler-horiz');
        sh.setAttribute('class', 'scrollbar-handler-horiz scrlbr');

        curObj.hSh = sh;

        st.appendChild(sh);

        //create scroll button scrollbar-handler
        ln = document.createElement('div');
        ln.setAttribute('class', 'scrollbar-lines scrlbr');

        lns = document.createElement('div');
        lns.setAttribute('class', 'scrollbar-line scrlbr');

        ln.appendChild(lns);

        sh.appendChild(ln);

        //create scroll button bottom
        bb = document.createElement('div');
        bb.setAttribute('id', curObj.contId + '-right-button');
        bb.setAttribute('class', 'right-button scrlbr');
        sw.appendChild(bb);

        trb = document.createElement('div');
        trb.setAttribute('class', 'triangl-right scrlbr');
        bb.appendChild(trb);

        curObj.hSw = sw;
        curObj.hBb = bb;
        curObj.hTb = tb;

        if (curObj.hSh !== null) {
          //for button up/down scroll!!!!
          if (!('ontouchstart' in document.documentElement)) {
            bb.onmousedown = moveRightHandler;
            tb.onmousedown = moveLeftHandler;
          }
          //for touchpads
          bb.ontouchstart = moveRightHandler;
          tb.ontouchstart = moveLeftHandler;
        }
        if (curObj.st.addEventListener) {
          curObj.st.addEventListener('mousedown', scrollTrackMDHandler, false);
        }

        getSizeHor();
      },
      /**
       * Attach object for scrolling
       * @param {String} contId Id of wrapper object
       * @param {String} objId Id of object
       * @param {Boolean} hs HideScroll if nothing scrolling
       * @param {Boolean} hss hideHoriz scroll
       */
      attach = function(contId, objId, tabId, hs, hss) {
        var obj = document.getElementById(objId),
            cont = document.getElementById(contId);

        if (!obj || !cont) {
          return false;
        }
        //bind resize
        curObj = {
          'objId' : objId,
          'contId' : contId,
          'obj' : obj,
          'cont' : cont,
          'tabId' : tabId,
          'hs' : hs || false,
          'hhs' : hss || false
        };
        buildScroll();
        buildHorizScroll();
        bigObj[contId] = curObj;
        bindEvent();
        curObj = null;
        obj = null;
        cont = null;
        //return _curObj;
      },

      detach = function(tabId) {
        var keyVar, keyVar1;
        //rbin = document.getElementById('rbin');
        for (keyVar in bigObj) {
          if (bigObj[keyVar].tabId === tabId) {
            if (bigObj[keyVar].cont.removeEventListener) {
              if (bigObj[keyVar].contWheelEvent) {
                bigObj[keyVar].cont
                    .removeEventListener('DOMMouseScroll', wheel, false);
                bigObj[keyVar].contWheelEvent = false;
              }
            }
            for (keyVar1 in bigObj[keyVar]) {
              if (bigObj[keyVar].hasOwnProperty(keyVar1)) {
                bigObj[keyVar][keyVar1] = null;
              }
            }
            delete lastValues[bigObj[keyVar].contId];
            delete bigObj[keyVar];
          }
        }
      };
  return {
    attach: attach,
    update: update,
    bigObj: bigObj,
    scrollMove: scrollMove,
    scrollMoveHoriz: scrollMoveHoriz,
    scrollTo: scrollTo,
    forceMove: forceMove,
    forceMoveSelectItem: forceMoveSelectItem,
    detach: detach
  };
}());