////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////

if ( typeof( IPG ) == 'undefined' ) IPG = {};
IPG.Slider = function ( sliderElement , eventTargetElement ){
    this.version = "0.1";
    
    // スライダーオブジェクトエレメント
    this.frameElement = IPG.Utility.getElement( sliderElement );
    if( !this.frameElement ) return undefined;
    
    // イベント設定エレメント
    this.controllerElement = IPG.Utility.getElement( eventTargetElement );
    if( !this.controllerElement ) return undefined;
    this.document = this.controllerElement.ownerDocument || this.controllerElement.document;
    this.controllerElement.unselectable = "on";
    // イベントハンドラ
    this.eventHandler = {
        /** マウスポインタ書きかえ **/
        //pointer_manager : this.onSliderPointerManagert.bind( this ),
        selectstart : this.onSliderSelectStart.bind( this ),
        mousedown : this.onSliderMouseDown.bind( this ),
        mousemove : this.onSliderMouseMove.bind( this ),
        mouseup : this.onSliderMouseUp.bind( this ),
        mousewheel : this.onSliderMouseWheel.bind( this )
    };
    
    // X軸方向スクロール対象エレメント
    this.scrollXAxisElements;
    // Y軸方向スクロール対象エレメント
    this.scrollYAxisElements;
    
    // スクロールコンテンツの初期描画位置 (intValue)
    this.currentPos = { 'x':0 , 'y':0 };
    // 描画範囲上限 (intValue)
    this.drawLimit = { 'left':0 , 'Top':0 , 'Right':0, 'Bottom':0 };
    
    // ポインタの直前位置 (intValue)
    this.startPos = { 'x':undefined , 'y':undefined };
    this.lastPos = { 'x':undefined , 'y':undefined };
    // ポインタの直前移動方向 (true/false)
    //this.lastDirection = { 'toLeft':undefined , 'toTop':undefined };
    
    // X軸方向スクロールと同期するスクロールバーエレメント
    this.scrollXAxisScrollBar;
    // Y軸方向スクロールと同期するスクロールバーエレメント
    this.scrollYAxisScrollBar;
    
    // ステータスフラグ
    this.active = false;
    this.dragging = false;
    
    // マウスポインタ画像情報
    this.pointer_path;
    
    return this;
};

/////////////////////////////////////////////////////////
// EVENT
/////////////////////////////////////////////////////////
IPG.Slider.prototype.bindEvents = function(){
    if( !this.controllerElement ) return;
    
    /** マウスポインタ書きかえ **/
    //Event.observe( this.controllerElement , "mousemove" , this.eventHandler.pointer_manager );
    Event.observe( this.controllerElement , "mousedown" , this.eventHandler.mousedown );
    Event.observe( this.controllerElement , "selectstart" , this.eventHandler.selectstart );
    Event.observe( this.controllerElement , "DOMMouseScroll" , this.eventHandler.mousewheel );
    Event.observe( this.controllerElement , "mousewheel" , this.eventHandler.mousewheel );
};

IPG.Slider.prototype.rebindEvents = function(){
    if( !this.controllerElement ) return;
    
    /** マウスポインタ書きかえ **/
    //Event.stopObserving( this.controllerElement , "mousemove" , this.eventHandler.pointer_manager );
    Event.stopObserving( this.controllerElement , "mousedown" , this.eventHandler.mousedown );
    Event.stopObserving( this.controllerElement , "selectstart" , this.eventHandler.selectstart );
    Event.stopObserving( this.controllerElement , "DOMMouseScroll" , this.eventHandler.mousewheel );
    Event.stopObserving( this.controllerElement , "mousewheel" , this.eventHandler.mousewheel );
};


/** マウスポインタ書きかえ **/
/**
IPG.Slider.prototype.onSliderPointerManagert = function( evt ){
    evt = IPG.Utility.fixEvent( evt , this );
    
    //if( this.dragging || !this.pointer_path ){
    if( this.dragging ){
        evt.preventDefault();
        return false;
    }
    
    if( !this.pointer_manager ){
        this.pointer_manager = {};
        this.pointer_manager.offset_min_x = 0;
        this.pointer_manager.offset_min_y = 0;
        var tmp_node = $( "epg_container" );
        if( tmp_node ){
            this.pointer_manager.offset_min_y += tmp_node.offsetTop;
            this.pointer_manager.offset_min_x += tmp_node.offsetLeft;
        }
        tmp_node = $( "container_frame" );
        if( tmp_node ){
            this.pointer_manager.offset_min_y += tmp_node.offsetTop;
            this.pointer_manager.offset_min_x += tmp_node.offsetLeft;
        }
        tmp_node = $( "epg_frame" );
        if( tmp_node ){
            this.pointer_manager.offset_min_y += tmp_node.offsetTop;
        }
        tmp_node = $( "epg_body_frame" );
        if( tmp_node ){
            this.pointer_manager.offset_min_y += tmp_node.offsetTop;
        }
        this.pointer_manager.offset_max_x = this.pointer_manager.offset_min_x + tmp_node.offsetWidth;
        this.pointer_manager.offset_max_y = this.pointer_manager.offset_min_y + tmp_node.offsetHeight;
        
        //if( Prototype.Browser.IE ){
            //this.pointer_manager.open_cursor = "url("+this.pointer_path.open+")";
            //this.pointer_manager.close_cursor = "url("+this.pointer_path.close+")";
            //this.pointer_manager.open_cursor = "cursor:url("+this.pointer_path.open+")";
            //this.pointer_manager.close_cursor = "cursor:url("+this.pointer_path.close+")";
        //}else{
            //this.pointer_manager.open_cursor = "url("+this.pointer_path.open+"),auto";
            //this.pointer_manager.close_cursor = "url("+this.pointer_path.close+"),auto";
            //this.pointer_manager.open_cursor = "cursor:url("+this.pointer_path.open+"),auto";
            //this.pointer_manager.close_cursor = "cursor:url("+this.pointer_path.close+"),auto";
        //}
        
    }
    
    var now_x = evt.pageX;
    var now_y = evt.pageY;
    
    if(
        this.pointer_manager.offset_min_x <= now_x && now_x <= this.pointer_manager.offset_max_x &&
        this.pointer_manager.offset_min_y <= now_y && now_y <= this.pointer_manager.offset_max_y
    ){
        //this.controllerElement.style.cursor = this.pointer_manager.open_cursor;
        //Element.setStyle( this.controllerElement , "cursor: url( "+this.pointer_manager.open_cursor+" );" );
        Element.setStyle( this.controllerElement , "cursor: pointer;" );
    }else{
        //this.controllerElement.style.cursor = "auto";
        Element.setStyle( this.controllerElement , "cursor: auto;" );
    }
    
    evt.preventDefault();
    return false;
};
**/

IPG.Slider.prototype.onSliderMouseDown = function( evt ){

    evt = IPG.Utility.fixEvent( evt , this );
    
    this.moveRemainder = { X:0 , Y:0 };
    
    // 左クリック以外は処理しない。
    if( evt.which != 1 ) return;
    
    // 既にアクティブ化してる場合も処理しない。
    if( this.active ) return;
    
    // バルーン表示されてたら消す。
    var balloon = $( "pg_balloon" );
    var balloon_style = balloon.style;
    var orgColor = balloon.getAttribute("target_org_color");
    var target_id = balloon.getAttribute( "target_id" );
    if( orgColor && target_id ) $( target_id ).firstChild.style.color = orgColor;
    balloon.removeAttribute( "target_id" );
    balloon.removeAttribute( "target_org_color" );
    if( balloon_style.display == "block" ) balloon_style.display = "none";
    
    IPG.Utility.clearTextRange();
    
    if( !this.active ) this.active = true;
    
    this.startPos.x = evt.pageX;
    this.startPos.y = evt.pageY;
    this.lastPos.x = evt.pageX;
    this.lastPos.y = evt.pageY;
    
    Event.observe( this.document , "mousemove" , this.eventHandler.mousemove );
    Event.observe( this.document , "mouseup" , this.eventHandler.mouseup );
    Event.observe( this.document , "onlosecapture" , this.eventHandler.mouseup );
    if( Prototype.Browser.IE ) this.controllerElement.setCapture();
    
    evt.preventDefault();
    return false;
};
IPG.Slider.prototype.onSliderMouseMove = function( evt ){
    evt = IPG.Utility.fixEvent( evt , this );
    
    if( !this.active ) return;
    this.dragging = true;
    
    /** マウスポインタ書きかえ **/
    //this.controllerElement.style.cursor = this.pointer_manager.close_cursor;
    //Element.setStyle( this.controllerElement , "cursor: url( "+this.pointer_manager.close_cursor+" );" );
    //Element.setStyle( this.controllerElement , "cursor: move;" );
    
    // ポインタの移動距離。
    var epgMoveX = 0;
    var epgMoveY = 0;
    if( this.scrollXAxisElements ) epgMoveX = ( evt.pageX - this.lastPos.x );
    if( this.scrollYAxisElements ) epgMoveY = ( evt.pageY - this.lastPos.y );
    
    var xAxisSb = this.scrollXAxisScrollBar;
    if( xAxisSb ){
        // 比率計算したEPGの移動距離。
        var tmpMoveX = epgMoveX*this.scrollXAxisScrollBar.sliderPos.rate;
        // 移動距離が正か負か。NN=negative number 0は真として扱う。
        var isNN_X = ( tmpMoveX < 0 ) ? true : false;
        // EPG移動距離の整数部分。
        var integerMoveX = ( !isNN_X ) ? Math.floor( tmpMoveX ) : Math.ceil( tmpMoveX );
        // あまりはイベント発生の都度、加算していく。
        var remainderX = tmpMoveX - integerMoveX;
        this.moveRemainder.X += remainderX;
        if( this.moveRemainder.X >= 1 ){          // あまりの合計値が[1]以上の場合、合計値から[1]減算し、絶対値に[1]加算する。
            --this.moveRemainder.X;
            ++integerMoveX;
        }else if( this.moveRemainder.X <= -1 ){  // あまりの合計値が[1]以上の場合、合計値から[1]減算し、絶対値に[1]加算する。
            ++this.moveRemainder.X;
            --integerMoveX;
        }
        xAxisSb.drawScrollBar( integerMoveX );
    }
    
    var yAxisSb = this.scrollYAxisScrollBar;
    if( yAxisSb ){
        // 比率計算したEPGの移動距離。
        var tmpMoveY = epgMoveY*this.scrollYAxisScrollBar.sliderPos.rate;
        // 移動距離が正か負か。NN=negative number 0は真として扱う。
        var isNN_Y = ( tmpMoveY < 0 ) ? true : false;
        // EPG移動距離の整数部分。
        var integerMoveY = ( !isNN_Y ) ? Math.floor( tmpMoveY ) : Math.ceil( tmpMoveY );
        // あまりはイベント発生の都度、加算していく。
        var remainderY = tmpMoveY - integerMoveY;
        this.moveRemainder.Y += remainderY;
        if( this.moveRemainder.Y >= 1 ){         // あまりの合計値が[1]以上の場合、合計値から[1]減算し、絶対値に[1]加算する。
            --this.moveRemainder.Y;
            ++integerMoveY;
        }else if( this.moveRemainder.Y <= -1 ){  // あまりの合計値が[1]以上の場合、合計値から[1]減算し、絶対値に[1]加算する。
            ++this.moveRemainder.Y;
            --integerMoveY;
        }
        yAxisSb.drawScrollBar( integerMoveY );
    }
    this.drawSlider( -epgMoveX , -epgMoveY );
    
    this.lastPos.x = evt.pageX;
    this.lastPos.y = evt.pageY;
    
    Event.stop( evt );
    return false;
};

IPG.Slider.prototype.onSliderMouseUp = function( evt ){
    evt = IPG.Utility.fixEvent( evt , this );
    
    // 左クリック以外は処理しない。
    if( evt.which != 1 ) return;
    
    if( !this.active ) return;
    this.active = false;
    this.dragging = false;
    
    Event.stopObserving( this.document , "mousemove" , this.eventHandler.mousemove );
    Event.stopObserving( this.document , "mouseup" , this.eventHandler.mouseup );
    Event.stopObserving( this.document , "onlosecapture" , this.eventHandler.mouseup );
    if( Prototype.Browser.IE ) this.controllerElement.releaseCapture();
    
    /** マウスポインタ書きかえ **/
    //this.controllerElement.style.cursor = this.pointer_manager.open_cursor;
    //Element.setStyle( this.controllerElement , "cursor: url( "+this.pointer_manager.open_cursor+" );" );
    //Element.setStyle( this.controllerElement , "cursor: pointer;" );
    
    evt.preventDefault();
    return false;
};
IPG.Slider.prototype.onSliderMouseWheel = function( evt ){
    evt = IPG.Utility.fixEvent( evt , this );
    
    var delta = 0;
    if( evt.wheelDelta )  delta = evt.wheelDelta/120;
    else if( evt.detail )   delta = -evt.detail/3;
    
    // ホイール移動距離の数値が、ブラウザ＋OSで異なるので、実際の移動距離ベースでのスクロールはしない。
    // 方向だけ求めて、移動距離は別途。暫定５０。
    if( delta > 0 ){
        this.drawSlider( 0 , -50 );
        if( this.scrollYAxisScrollBar ) this.scrollYAxisScrollBar.drawScrollBar( Math.round( 50*this.scrollYAxisScrollBar.sliderPos.rate ) );
    }else if( delta < 0 ){
        this.drawSlider( 0 , 50 );
        if( this.scrollYAxisScrollBar ) this.scrollYAxisScrollBar.drawScrollBar( Math.round( -50*this.scrollYAxisScrollBar.sliderPos.rate ) );
    }
    
    Event.stop( evt );
    return false;
};
IPG.Slider.prototype.onSliderSelectStart = function( evt ){
    Event.stop( evt );
    return false;
};

/////////////////////////////////////////////////////////
// 描画
// IE7でのズーム機能を動かないようにしたいね
/////////////////////////////////////////////////////////

// BS用特殊対応。１局分ずらして表示。
IPG.Slider.prototype.bsdDefaultMove = function(){
    
    // ポインタの移動距離。
    var epgMoveX = -120;
    
    var xAxisSb = this.scrollXAxisScrollBar;
    if( xAxisSb ){
        // 比率計算したEPGの移動距離。
        var tmpMoveX = epgMoveX*this.scrollXAxisScrollBar.sliderPos.rate;
        // 移動距離が正か負か。NN=negative number 0は真として扱う。
        var isNN_X = ( tmpMoveX < 0 ) ? true : false;
        // EPG移動距離の整数部分。
        var integerMoveX = ( !isNN_X ) ? Math.floor( tmpMoveX ) : Math.ceil( tmpMoveX );
        xAxisSb.drawScrollBar( integerMoveX );
    }
    this.drawSlider( -epgMoveX , -0 );
};

IPG.Slider.prototype.drawSlider = function( moveX , moveY ){
    //if( !this.scrollXAxisElements || !this.scrollYAxisElements ) return;
    if( moveX === undefined && moveY === undefined ){ moveX = 0; moveY = 0; }
    if( typeof(moveX) !== "number" || typeof(moveY) !== "number" ) return;
    
    var newLeft = this.currentPos.x + moveX;
    var newTop = this.currentPos.y + moveY;
    
    var currentX = 0;
    var currentY = 0;
    if( this.scrollXAxisElements ){
        for( var i = 0 , len = this.scrollXAxisElements.length; i < len; i++ ){
            var target = this.scrollXAxisElements[i];
            target.scrollLeft = newLeft;
        }
        currentX = target.scrollLeft;
    }
    if( this.scrollYAxisElements ){
        for( var i = 0 , len = this.scrollYAxisElements.length; i < len; i++ ){
            var target = this.scrollYAxisElements[i];
            target.scrollTop = newTop;
        }
        currentY = target.scrollTop;
    }
    this.setCurrentPosition( currentX , currentY );
};

/////////////////////////////////////////////////////////
// 座標
/////////////////////////////////////////////////////////

IPG.Slider.prototype.setCurrentPosition = function( x , y ){
    if( typeof(x) !== "number" || typeof(y) !== "number" ) return;
    this.currentPos.x = x;
    this.currentPos.y = y;
};

IPG.Slider.prototype.setMaxLeft = function( val ){
    if( typeof( val ) !== "number" ) return;
    this.drawLimit.left = val;
};
IPG.Slider.prototype.setMaxTop = function( val ){
    if( typeof( val ) !== "number" ) return;
    this.drawLimit.top = val;
};
IPG.Slider.prototype.setMaxRight = function( val ){
    if( typeof( val ) !== "number" ) return;
    this.drawLimit.right = val;
};
IPG.Slider.prototype.setMaxBottom = function( val ){
    if( typeof( val ) !== "number" ) return;
    this.drawLimit.bottom = val;
};

/**
 * スクロール対象コンテンツのサイズから、画面上の表示フレームサイズを減算し、
 * スクロール可能な範囲を求める。
 */
IPG.Slider.prototype.setScrollSize = function( content_w , content_h ){
    if( !this.frameElement || !content_w == undefined || !content_h == undefined ) return;
    
    var frame_width = IPG.Utility.trimUnit( this.frameElement.style.width );
    var frame_height = IPG.Utility.trimUnit( this.frameElement.style.height );
    
    var max_left = ( frame_width < content_w ) ? ( content_w - frame_width ) : 0;
    var max_top = ( frame_height < content_h ) ? ( content_h - frame_height ) : 0;
    
    this.setMaxLeft( max_left );
    this.setMaxTop( max_top );
    this.setMaxRight( 0 );
    this.setMaxBottom( 0 );
};

///////////////////////////////////////////////////////////
// スクロールバーサイズ取得
///////////////////////////////////////////////////////////

IPG.Slider.prototype.getSliderWidth = function( content_w ){
    if( !this.frameElement.style.width || !content_w ) return;
    var frame_width = IPG.Utility.trimUnit( this.frameElement.style.width );
    try{ return Math.round((frame_width/content_w)*frame_width); }catch(e){}
    return 0;
};
IPG.Slider.prototype.getSliderHeight = function( content_h ){
    if( !this.frameElement.style.height || !content_h ) return;
    var frame_height = IPG.Utility.trimUnit( this.frameElement.style.height );
    try{ return Math.round((frame_height/content_h)*frame_height); }catch(e){}
    return 0;
};

///////////////////////////////////////////////////////////
// スクロールバー
///////////////////////////////////////////////////////////

IPG.ScrollBar = function( element ){
    this.scrollbarElement = IPG.Utility.getElement( element );
    if( !this.scrollbarElement ) return null;
    
    this.document = this.scrollbarElement.ownerDocument || this.scrollbarElement.document;
    this.controllerElement = this.scrollbarElement;
    
    this.scrollbarElement.scrollbar = this;
    this.scrollbarElement.unselectable = "on";
    
    // スクロールバーでコントロールするスライダオブジェクト
    this.contentSlider;
    this.direction = {
        'vertical_sb':undefined,
        'horizontal_sb':undefined
    };
    this.controllerNodes = {
        'sb_frame':undefined,
        'sb_content':undefined,
        'sb_bg_top':undefined,
        'sb_bg_bottom':undefined,
        'sb_bg_left':undefined,
        'sb_bg_right':undefined,
        'moveup_node':undefined,
        'movedown_node':undefined,
        'moveleft_node':undefined,
        'moveright_node':undefined,
        'slider_node':undefined
    };
    this.detail = {
        'sb_width':undefined,
        'sb_height':undefined,
        'icon_height':undefined,
        'icon_width':undefined,
        'slider_frame_width':undefined,
        'slider_frame_height':undefined,
        'slider_width':undefined,
        'slider_height':undefined
    };
    this.sliderPos = {
        'base':undefined,
        'moveLimit':undefined,
        'rate':undefined,
        'min':undefined,
        'max':undefined,
        'last':undefined
    };
    this.timer = {
        'id':undefined,
        'interval':undefined
    };
    // イベントハンドラ
    this.eventHandler = {
        selectstart : this.onScrollBarSelectStart.bind( this ),
        mousedown : this.onScrollBarMouseDown.bind( this ),
        mousemove : this.onScrollBarMouseMove.bind( this ),
        mouseup : this.onScrollBarMouseUp.bind( this )
    };
    this.active = false;
    
    return this;
};

/////////////////////////////////////////////////////////////////////////
// スクロールバーイベント処理
/////////////////////////////////////////////////////////////////////////

IPG.ScrollBar.prototype.bindEvents = function(){
    if( !this.scrollbarElement ) return;
    
    Event.observe( this.controllerElement , "mousedown" , this.eventHandler.mousedown );
    Event.observe( this.controllerElement , "selectstart" , this.eventHandler.selectstart );
};

IPG.ScrollBar.prototype.rebindEvents = function(){
    if( !this.scrollbarElement ) return;
    
    Event.stopObserving( this.controllerElement , "mousedown" , this.eventHandler.mousedown );
    Event.stopObserving( this.controllerElement , "selectstart" , this.eventHandler.selectstart );
};

IPG.ScrollBar.prototype.onScrollBarMouseDown = function( evt ){
    evt = IPG.Utility.fixEvent( evt , this );
    
    this.moveRemainder = 0;
    
    // 左クリック以外は処理しない。
    if( evt.which != 1 ) return;
    // 既にアクティブ化してる場合も処理しない。
    if( this.active ) return;
    else this.active = true;
    
    IPG.Utility.clearTextRange();
    
    var isSliderNode=false;
    var counter = 1;
    var srcElement = evt.srcElement;
    var rate = this.sliderPos.rate;
    var controllerNodes = this.controllerNodes;
    // [mousedown]された位置に応じて、処理分岐。
    // スライダ上での[mousedown]
    if( srcElement.id && srcElement.id == controllerNodes.slider_node ){
        this.contentSlider.lastPos.x = evt.pageX;
        this.contentSlider.lastPos.y = evt.pageY;
        isSliderNode = true;
    // 各アイコン上での[mousedwon]
    }else if( srcElement.id && srcElement.id == controllerNodes.moveup_node ){
        this.callTimer( "up" , this.sliderPos.base , rate );
    }else if( srcElement.id && srcElement.id == controllerNodes.movedown_node ){
        this.callTimer( "down" , this.sliderPos.base , rate );
    }else if( srcElement.id && srcElement.id == controllerNodes.moveleft_node ){
        this.callTimer( "left" , this.sliderPos.base , rate );
    }else if( srcElement.id && srcElement.id == controllerNodes.moveright_node ){
        this.callTimer( "right" , this.sliderPos.base , rate );
    // 背景部での[mousedown]
    }else if( srcElement.id && srcElement.id == controllerNodes.sb_bg_top ){
        var offset = IPG.Utility.trimUnit( srcElement.style.height ) - evt.offsetY;
        counter = Math.ceil( offset / this.detail.slider_height );
        this.callTimer( "up" , this.detail.slider_height , rate , counter );
    }else if( srcElement.id && srcElement.id == controllerNodes.sb_bg_bottom ){
        var offset = evt.offsetY;
        counter = Math.ceil( offset / this.detail.slider_height );
        this.callTimer( "down" , this.detail.slider_height , rate , counter );
    }else if( srcElement.id && srcElement.id == controllerNodes.sb_bg_left ){
        var offset = IPG.Utility.trimUnit( srcElement.style.width ) - evt.offsetX;
        counter = Math.ceil( offset / this.detail.slider_width );
        this.callTimer( "left" , this.detail.slider_width , rate , counter );
    }else if( srcElement.id && srcElement.id == controllerNodes.sb_bg_right ){
        var offset = evt.offsetX;
        counter = Math.ceil( offset / this.detail.slider_width );
        this.callTimer( "right" , this.detail.slider_width , rate , counter );
    }
    
    if( isSliderNode ) Event.observe( this.document , "mousemove" , this.eventHandler.mousemove );
    Event.observe( this.document , "mouseup" , this.eventHandler.mouseup );
    Event.observe( this.document , "onlosecapture" , this.eventHandler.mouseup );
    if( Prototype.Browser.IE ) this.controllerElement.setCapture();
    
    //Event.stop( evt );
    evt.preventDefault();
    return false;
};
IPG.ScrollBar.prototype.onScrollBarMouseMove = function( evt ){
    
    evt = IPG.Utility.fixEvent( evt , this );
    
    if( !this.active ) return;
    
    var moveX,moveY;
    if( this.direction.vertical_sb ){
        moveY = ( evt.pageY - this.contentSlider.lastPos.y ); // スクロールバーの移動距離。
        
        // 比率計算したEPGの移動距離。
        var tmpMove = moveY/this.sliderPos.rate;
        // 移動距離が正か負か。NN=negative number 0は真として扱う。
        var isNN = ( tmpMove < 0 ) ? true : false;
        // EPG移動距離の整数部分。
        var integerMove = ( !isNN ) ? Math.floor( tmpMove ) : Math.ceil( tmpMove );
        // EPG移動距離の少数部分。
        var remainder = tmpMove - integerMove;
        // あまりはイベント発生の都度、加算していく。
        this.moveRemainder += remainder;
        if( this.moveRemainder >= 1 ){         // あまりの合計値が[1]以上の場合、合計値から[1]減算し、絶対値に[1]加算する。
            --this.moveRemainder;
            ++integerMove;
        }else if( this.moveRemainder <= -1 ){  // あまりの合計値が[1]以上の場合、合計値から[1]減算し、絶対値に[1]加算する。
            ++this.moveRemainder;
            --integerMove;
        }
        this.contentSlider.drawSlider( 0 , integerMove );
        this.drawScrollBar( -moveY );
        this.contentSlider.lastPos.y = evt.pageY;
    }else if( this.direction.horizontal_sb ){
        moveX = ( evt.pageX - this.contentSlider.lastPos.x ); // スクロールバーの移動距離。
        
        // 比率計算したEPGの移動距離。
        var tmpMove = moveX/this.sliderPos.rate;
        // 移動距離が正か負か。NN=negative number 0は真として扱う。
        var isNN = ( tmpMove < 0 ) ? true : false;
        // EPG移動距離の整数部分。
        var integerMove = ( !isNN ) ? Math.floor( tmpMove ) : Math.ceil( tmpMove );
        // EPG移動距離の少数部分。
        var remainder = tmpMove - integerMove;
        // あまりはイベント発生の都度、加算していく。
        this.moveRemainder += remainder;
        if( this.moveRemainder >= 1 ){         // あまりの合計値が[1]以上の場合、合計値から[1]減算し、絶対値に[1]加算する。
            --this.moveRemainder;
            ++integerMove;
        }else if( this.moveRemainder <= -1 ){  // あまりの合計値が[1]以上の場合、合計値から[1]減算し、絶対値に[1]加算する。
            ++this.moveRemainder;
            --integerMove;
        }
        this.contentSlider.drawSlider( integerMove , 0 );
        this.drawScrollBar( -moveX );
        this.contentSlider.lastPos.x = evt.pageX;
    }
    
    Event.stop( evt );
    return false;
};
IPG.ScrollBar.prototype.onScrollBarMouseUp = function( evt ){
    evt = IPG.Utility.fixEvent( evt , this );
    
    if( !this.active ) return;
    this.active = false;
    
    this.stopTimer();
    
    Event.stopObserving( this.document , "mousemove" , this.eventHandler.mousemove );
    Event.stopObserving( this.document , "mouseup" , this.eventHandler.mouseup );
    Event.stopObserving( this.document , "onlosecapture" , this.eventHandler.mouseup );
    if( Prototype.Browser.IE ) this.controllerElement.releaseCapture();
    
    evt.preventDefault();
    return false;
};
IPG.ScrollBar.prototype.onScrollBarSelectStart = function( evt ){
    Event.stop( evt );
    return false;
};

/////////////////////////////////////////////////////////////////////////
// スクロールバー描画
/////////////////////////////////////////////////////////////////////////

IPG.ScrollBar.prototype.drawScrollBar = function( movePx ){
    if( !this.controllerNodes.slider_node ) return;
    if( movePx === undefined ){ movePx = 0; }
    if( typeof(movePx) !== "number" ) return;
    
    var frameElm = IPG.Utility.getElement( this.controllerNodes.sb_frame );
    
    var newPosition;
    if( this.direction.vertical_sb ){
        newPosition = frameElm.scrollTop + movePx;
    }else if( this.direction.horizontal_sb ){
        newPosition = frameElm.scrollLeft + movePx;
    }
    
    //if( newPosition > this.sliderPos.max ) newPosition = this.sliderPos.max;
    //if( newPosition < this.sliderPos.min ) newPosition = this.sliderPos.min;
    
    if( this.direction.vertical_sb ){
        frameElm.scrollTop = newPosition;
        this.sliderPos.last = frameElm.scrollTop;
    }else if( this.direction.horizontal_sb ){
        frameElm.scrollLeft = newPosition;
        this.sliderPos.last = frameElm.scrollLeft;
    }
};

/////////////////////////////////////////////////////////////////////////
// スクロールバー用タイマー
/////////////////////////////////////////////////////////////////////////

IPG.ScrollBar.prototype.startTimer = function( direction , basePx , ratePx , counter ){
    if( !this.timer.interval ) this.timer.interval = 100;
    var thisObj = this;
    if( counter != undefined ) --counter;
    this.timer.id = setTimeout( function(){ thisObj.callTimer( direction , basePx , ratePx , counter ); } , this.timer.interval );
};

IPG.ScrollBar.prototype.stopTimer = function(){
    if( this.timer.id ) clearTimeout( this.timer.id );
};

IPG.ScrollBar.prototype.callTimer = function( direction , basePx , ratePx , counter ){
    if( !direction || basePx == undefined || ratePx == undefined ) return;
    if( counter != undefined && counter == 0 ) return;
    var sliderElm = IPG.Utility.getElement( this.controllerNodes.slider_node );
    if( direction == "up" ){
        this.contentSlider.drawSlider( 0 , Math.round( basePx/ratePx )*-1 );
        this.drawScrollBar( basePx );
    }else if( direction == "down" ){
        this.contentSlider.drawSlider( 0 , Math.round( basePx/ratePx ) );
        this.drawScrollBar( -basePx );
    }else if( direction == "left" ){
        this.contentSlider.drawSlider( Math.round( basePx/ratePx )*-1 , 0 );
        this.drawScrollBar( basePx );
    }else if( direction == "right" ){
        this.contentSlider.drawSlider( Math.round( basePx/ratePx ) , 0 );
        this.drawScrollBar( -basePx );
    }
    if( !counter ){
        basePx += 6;
        if( basePx > this.sliderPos.moveLimit )  basePx = this.sliderPos.moveLimit;
    }
    this.startTimer( direction , basePx , ratePx , counter );
};