if ( typeof( IPG ) == 'undefined' ) IPG = {};
IPG.EpgController = function( controller , container , config ){
    this.version = "0.1";
    
    this.controllerElement = IPG.Utility.getElement( controller );
    if( !this.controllerElement ) return;
    
    this.container = container;
    if( !this.container ) return;
    
    this.config = config;
    if( !this.config ) return;
    
    this.document = this.controllerElement.ownerDocument || this.controllerElement.document;
    
    return this;
};



/********************************************************************************/
// ↓日付選択エリアのHTML出力＋イベント設定↓
/********************************************************************************/
IPG.EpgController.prototype.makeDateControllerHTML = function( documentElement ){
    if( !documentElement ) return;
    var html = "<div id=\"epg_date_controll_title\" style=\"width: 27px; height: 27px; position: relative; float: left;\"><img src=\""+this.config.config_xml.img_path.datectrl_title+"\" style=\"margin: -12px 0px 0px -11px; position: absolute; top: 50%; left: 50%;\"></div>";
    var list = documentElement.childNodes;
    var daylist = [ "（日）" , "（月）" , "（火）" , "（水）" , "（木）" , "（金）" , "（土）" ];
    if( list ){
        var len = list.length;
        for( var i = 0; i < len; i++ ){
            var date = list[i].childNodes[0].firstChild.nodeValue;
            var day_flg = list[i].childNodes[1].firstChild.nodeValue;
            var wday = new Date( date.split("-")[0], parseInt(date.split("-")[1],10)-1, date.split("-")[2] ).getDay();
            if( !i ){
                if( !this.config.current_date ) this.config.current_date = date;
                else if( IPG.Utility.comparSIDateStr( this.config.current_date , date ) > 0 ) this.config.current_date = date;
            }else if( (i+1) == len ){
                if( IPG.Utility.comparSIDateStr( date , this.config.current_date ) > 0 ) this.config.current_date = date;
            }
            var str = ( !i ) ? "今日" : date.slice( 5 , date.length ) ;
            var styletype = ( date == this.config.current_date ) ? "color: #0075CB; cursor: auto;" : ( day_flg == "1" ) ? " color: #F08080; cursor: pointer;" : " color: #001B67; cursor: pointer;";
            if( !i ) html += "<div style=\"width: 1px; height: 27px; background-image: url("+this.config.config_xml.img_path.datectrl_border2+"); margin-left: 5px; position: relative; float: left;\"></div>";
            html += "<div id=\"epg_date_controll_"+i+"\" name=\"epg_date_controll\" style=\""+styletype+" width: 70px; height: 27px; background-image: url("+this.config.config_xml.img_path.datectrl_body+"); position: relative; float: left;\" value=\""+date+"\" flg=\""+day_flg+"\">";
            html += "<div style=\"width:69px; height: 27px; position: absolute; top: 50%; margin-top: -0.7em; left: 50%; margin-left: -2.8em; font-size: 9px; font-weight: bold;\">"+str+daylist[wday]+"</div>";
            if( (i+1) != len ) html += "<div style=\"width: 1px; height: 27px; background-image: url("+this.config.config_xml.img_path.datectrl_border+"); position: absolute; right: 0px; float: left;\"></div>";
            html += "</div>";
            if( (i+1) == len ) html += "<div style=\"width: 1px; height: 27px; background-image: url("+this.config.config_xml.img_path.datectrl_border2+"); position: relative;float: left;\"></div>";
        }
    }
    return html;
};

IPG.EpgController.prototype.makeTopDateControllerHTML = function( documentElement ){
    if( !documentElement ) return;
    var html = "";
    var list = documentElement.childNodes;
    if( list ){
        for( var i = 0; i < 2; i++ ){
            var date = list[i].childNodes[0].firstChild.nodeValue;
            if( !this.config.current_date ) this.config.current_date = date;
            var img_path = ( !i ) ? this.config.config_xml.img_path.epg_today : this.config.config_xml.img_path.epg_tomorrow;
            html += "<div id=\"epg_date_controll_"+i+"\" name=\"epg_date_controll\" style=\"width: 119px; height: 30px; position: relative; margin: 0px 0px 0px 5px; float: left;\" value=\""+date+"\" flg=\""+i+"\"><a href=\"/epg/?epg_date="+date+"\"><img src=\""+img_path+"\" style=\"border: none;\"></a></div>";
        }
    }
    return html;
};
IPG.EpgController.prototype.dateControllerMouseDownEvent = function( evt ){
    evt = IPG.Utility.fixEvent( evt , this );
    
    // 左クリック以外は処理しない。
    if( evt.which != 1 ){
        evt.preventDefault();
        return false;
    }
    
    var controller = evt.srcElement;
    var tmp = controller.getAttribute( "value" );
    while( !tmp ){
        controller = controller.parentNode;
        tmp = controller.getAttribute( "value" );
    }
    this.config.current_date = controller.getAttribute( "value" );
    
    this.container.refresh();
    
    evt.preventDefault();
    return false;
};
IPG.EpgController.prototype.dateControllerMouseOverEvent = function( evt , isTop ){
    evt = IPG.Utility.fixEvent( evt , this );
    
    var controller = evt.srcElement;
    var tmp = controller.getAttribute( "value" );
    while( !tmp ){
        controller = controller.parentNode;
        tmp = controller.getAttribute( "value" );
    }
    
    if( !isTop ) Element.setStyle( controller , "color: #0075CB;" );
    else{
        var val = controller.getAttribute( "flg" );
        var img_path = ( !parseInt( val ,10 ) ) ? this.config.config_xml.img_path.epg_today_over : this.config.config_xml.img_path.epg_tomorrow_over;
        evt.srcElement.src = img_path;
    }
    
    Event.stop( evt );
    return false;
};
IPG.EpgController.prototype.dateControllerMouseOutEvent = function( evt , isTop  ){
    evt = IPG.Utility.fixEvent( evt , this );
    
    var controller = evt.srcElement;
    var tmp = controller.getAttribute( "value" );
    while( !tmp ){
        controller = controller.parentNode;
        tmp = controller.getAttribute( "value" );
    }
    
    if( !isTop ){
        var target_date = controller.getAttribute( "value" );
        var target_day_flg = controller.getAttribute( "flg" );
        var color = ( target_date == this.config.current_date ) ? "color: #0075CB;" : ( target_day_flg == "1" ) ? " color: #F08080;" : " color: #001B67;";
        Element.setStyle( controller , color );
    }else{
        var val = controller.getAttribute( "flg" );
        var img_path = ( !parseInt( val ,10 ) ) ? this.config.config_xml.img_path.epg_today : this.config.config_xml.img_path.epg_tomorrow;
        evt.srcElement.src = img_path;
    }
    
    Event.stop( evt );
    return false;
};

/***
IPG.EpgController.prototype.dateControllerLArrowMouseDownEvent = function( evt ){
    evt = IPG.Utility.fixEvent( evt , this );
    
    // 矢印ボタン押された時の処理。
    //IPG.Utility.debugOut( '[dateController L ArrowMouseDownEvent]' , "debug" , "blueviolet" );
    
    //this.container.refresh();
    //Event.stop( evt );
    evt.preventDefault();
    return false;
};
IPG.EpgController.prototype.dateControllerLArrowMouseOverEvent = function( evt ){
    evt = IPG.Utility.fixEvent( evt , this );
    evt.srcElement.src = this.config.config_xml.img_path.datectrl_leftarrow_over;
    Event.stop( evt );
    return false;
};
IPG.EpgController.prototype.dateControllerLArrowMouseOutEvent = function( evt ){
    evt = IPG.Utility.fixEvent( evt , this );
    evt.srcElement.src = this.config.config_xml.img_path.datectrl_leftarrow;
    Event.stop( evt );
    return false;
};

IPG.EpgController.prototype.dateControllerRArrowMouseDownEvent = function( evt ){
    evt = IPG.Utility.fixEvent( evt , this );
    
    // 矢印ボタン押された時の処理。
    //IPG.Utility.debugOut( '[dateController R ArrowMouseDownEvent]' , "debug" , "blueviolet" );
    
    //this.container.refresh();
    //Event.stop( evt );
    evt.preventDefault();
    return false;
};
IPG.EpgController.prototype.dateControllerRArrowMouseOverEvent = function( evt ){
    evt = IPG.Utility.fixEvent( evt , this );
    evt.srcElement.src = this.config.config_xml.img_path.datectrl_rightarrow_over;
    Event.stop( evt );
    return false;
};
IPG.EpgController.prototype.dateControllerRArrowMouseOutEvent = function( evt ){
    evt = IPG.Utility.fixEvent( evt , this );
    evt.srcElement.src = this.config.config_xml.img_path.datectrl_rightarrow;
    Event.stop( evt );
    return false;
};

IPG.EpgController.prototype.dateControllerCalendarMouseDownEvent = function( evt ){
    evt = IPG.Utility.fixEvent( evt , this );
    
    // カレンダーボタン押された時の処理。
    //IPG.Utility.debugOut( '[dateController Calendar MouseDownEvent]' , "debug" , "blueviolet" );
    
    //Event.stop( evt );
    evt.preventDefault();
    return false;
};
IPG.EpgController.prototype.dateControllerCalendarMouseOverEvent = function( evt ){
    evt = IPG.Utility.fixEvent( evt , this );
    evt.srcElement.src = this.config.config_xml.img_path.datectrl_calendar_over;
    Event.stop( evt );
    return false;
};
IPG.EpgController.prototype.dateControllerCalendarMouseOutEvent = function( evt ){
    evt = IPG.Utility.fixEvent( evt , this );
    evt.srcElement.src = this.config.config_xml.img_path.datectrl_calendar;
    Event.stop( evt );
    return false;
};
***/

IPG.EpgController.prototype.removeDateControllerEvent = function( element ){
    if( !element ) return;
    if( element.childNodes && element.childNodes.length ){
        var len = element.childNodes.length;
        for( var i = 0; i < len; i++ ){
            if( element.childNodes[i].getAttribute( "name" ) == "epg_date_controll" ){
                Event.stopObserving( element.childNodes[i] , "mousedown" , this.dateControllerBoundMouseDown );
                Event.stopObserving( element.childNodes[i] , "mouseover" , this.dateControllerBoundMouseOver );
                Event.stopObserving( element.childNodes[i] , "mouseout" , this.dateControllerBoundMouseOut );
/***
            }else if( element.childNodes[i].id == "epg_date_controll_leftarrow" ){
                Event.stopObserving( element.childNodes[i] , "mousedown" , this.dateControllerLArrowBoundMouseDown );
                Event.stopObserving( element.childNodes[i] , "mouseover" , this.dateControllerLArrowBoundMouseOver );
                Event.stopObserving( element.childNodes[i] , "mouseout" , this.dateControllerLArrowBoundMouseOut );
            }else if( element.childNodes[i].id == "epg_date_controll_rightarrow" ){
                Event.stopObserving( element.childNodes[i] , "mousedown" , this.dateControllerRArrowBoundMouseDown );
                Event.stopObserving( element.childNodes[i] , "mouseover" , this.dateControllerRArrowBoundMouseOver );
                Event.stopObserving( element.childNodes[i] , "mouseout" , this.dateControllerRArrowBoundMouseOut );
            }else if( element.childNodes[i].id == "epg_date_controll_calendar" ){
                Event.stopObserving( element.childNodes[i] , "mousedown" , this.dateControllerCalendarBoundMouseDown );
                Event.stopObserving( element.childNodes[i] , "mouseover" , this.dateControllerCalendarBoundMouseOver );
                Event.stopObserving( element.childNodes[i] , "mouseout" , this.dateControllerCalendarBoundMouseOut );
***/
            }
        }
    }
};
IPG.EpgController.prototype.removeTopDateControllerEvent = function( element ){
    if( !element ) return;
    if( element.childNodes && element.childNodes.length ){
        var len = element.childNodes.length;
        for( var i = 0; i < len; i++ ){
            if( element.childNodes[i].getAttribute( "name" ) == "epg_date_controll" ){
                Event.stopObserving( element.childNodes[i] , "mouseover" , this.dateControllerBoundMouseOver );
                Event.stopObserving( element.childNodes[i] , "mouseout" , this.dateControllerBoundMouseOut );
            }
        }
    }
};
IPG.EpgController.prototype.bindDateControllerEvent = function( element ){
    if( !element ) return;
    if( element.childNodes && element.childNodes.length ){
        var len = element.childNodes.length;
        for( var i = 0; i < len; i++ ){
            if( element.childNodes[i].getAttribute( "name" ) == "epg_date_controll" ){
                // 選択中箇所には[mousedown]イベントの割り当ては行わない。
                if( element.childNodes[i].getAttribute( "value" ) != this.config.current_date ){
                    Event.observe( element.childNodes[i] , "mousedown" , this.dateControllerBoundMouseDown );
                    Event.observe( element.childNodes[i] , "mouseover" , this.dateControllerBoundMouseOver );
                    Event.observe( element.childNodes[i] , "mouseout" , this.dateControllerBoundMouseOut );
                }
/***
            }else if( element.childNodes[i].id == "epg_date_controll_leftarrow" ){
                Event.observe( element.childNodes[i] , "mousedown" , this.dateControllerLArrowBoundMouseDown );
                Event.observe( element.childNodes[i] , "mouseover" , this.dateControllerLArrowBoundMouseOver );
                Event.observe( element.childNodes[i] , "mouseout" , this.dateControllerLArrowBoundMouseOut );
            }else if( element.childNodes[i].id == "epg_date_controll_rightarrow" ){
                Event.observe( element.childNodes[i] , "mousedown" , this.dateControllerRArrowBoundMouseDown );
                Event.observe( element.childNodes[i] , "mouseover" , this.dateControllerRArrowBoundMouseOver );
                Event.observe( element.childNodes[i] , "mouseout" , this.dateControllerRArrowBoundMouseOut );
            }else if( element.childNodes[i].id == "epg_date_controll_calendar" ){
                Event.observe( element.childNodes[i] , "mousedown" , this.dateControllerCalendarBoundMouseDown );
                Event.observe( element.childNodes[i] , "mouseover" , this.dateControllerCalendarBoundMouseOver );
                Event.observe( element.childNodes[i] , "mouseout" , this.dateControllerCalendarBoundMouseOut );
***/
            }
        }
    }
};
IPG.EpgController.prototype.bindTopDateControllerEvent = function( element ){
    if( !element ) return;
    if( element.childNodes && element.childNodes.length ){
        var len = element.childNodes.length;
        for( var i = 0; i < len; i++ ){
            if( element.childNodes[i].getAttribute( "name" ) == "epg_date_controll" ){
                // TOPではアンカーリンクなので、mousedownはキャッチしない。
                Event.observe( element.childNodes[i] , "mouseover" , this.dateControllerBoundMouseOver );
                Event.observe( element.childNodes[i] , "mouseout" , this.dateControllerBoundMouseOut );
            }
        }
    }
};
IPG.EpgController.prototype.onDateControllerComplete = function( xhrObj ){
    if( xhrObj && xhrObj.responseXML && xhrObj.responseXML.documentElement ){
        $("epg_date_controller").innerHTML = this.makeDateControllerHTML( xhrObj.responseXML.documentElement );
        this.bindDateControllerEvent( this.dateSelectNode );
    }
    xhrObj = null;
};
IPG.EpgController.prototype.createDateController = function(){
    if( !this.dateSelectNode ){
        this.dateSelectNode = this.document.createElement("div");
        this.controllerElement.appendChild( this.dateSelectNode );
        Element.setStyle( this.dateSelectNode , "width: 594px; height: 27px; position: relative;" );
        this.dateSelectNode.id = "epg_date_controller";
        
        this.dateControllerBoundMouseDown = this.dateControllerMouseDownEvent.bind(this);
        this.dateControllerBoundMouseOver = this.dateControllerMouseOverEvent.bind(this);
        this.dateControllerBoundMouseOut = this.dateControllerMouseOutEvent.bind(this);
        /***
        this.dateControllerLArrowBoundMouseDown = this.dateControllerLArrowMouseDownEvent.bind(this);
        this.dateControllerLArrowBoundMouseOver = this.dateControllerLArrowMouseOverEvent.bind(this);
        this.dateControllerLArrowBoundMouseOut = this.dateControllerLArrowMouseOutEvent.bind(this);
        
        this.dateControllerRArrowBoundMouseDown = this.dateControllerRArrowMouseDownEvent.bind(this);
        this.dateControllerRArrowBoundMouseOver = this.dateControllerRArrowMouseOverEvent.bind(this);
        this.dateControllerRArrowBoundMouseOut = this.dateControllerRArrowMouseOutEvent.bind(this);
        
        this.dateControllerCalendarBoundMouseDown = this.dateControllerCalendarMouseDownEvent.bind(this);
        this.dateControllerCalendarBoundMouseOver = this.dateControllerCalendarMouseOverEvent.bind(this);
        this.dateControllerCalendarBoundMouseOut = this.dateControllerCalendarMouseOutEvent.bind(this);
        ***/
    }else{
        this.removeDateControllerEvent( this.dateSelectNode );
    }
    
    var ajaxOpt = {
        'method': 'get',
        'asynchronous': false
    };
    var xhrObj = new Ajax.Request( this.config.config_xml.api_url.getEpgCalendar , ajaxOpt );
    if( xhrObj && xhrObj._complete ){
        $("epg_date_controller").innerHTML = this.makeDateControllerHTML( xhrObj.transport.responseXML.documentElement );
        this.bindDateControllerEvent( this.dateSelectNode );
    }else{
        Element.setStyle( $( "epg_cloak" ) , "display: block;" );
        $( "cloak_img" ).src = this.config.error_image;
    }
};
IPG.EpgController.prototype.createTopDateController = function(){
    if( !this.dateSelectNode ){
        this.dateSelectNode = this.document.createElement("div");
        this.controllerElement.appendChild( this.dateSelectNode );
        Element.setStyle( this.dateSelectNode , "width: 256px; height: 30px; position: relative; margin-top: 10px; float: left;" );
        this.dateSelectNode.id = "epg_date_controller";
        
        this.dateControllerBoundMouseOver = this.dateControllerMouseOverEvent.bindAsEventListener( this , true );
        this.dateControllerBoundMouseOut = this.dateControllerMouseOutEvent.bindAsEventListener( this , true );
    }else{
        this.removeDateControllerEvent( this.dateSelectNode );
    }
    
    var ajaxOpt = {
        'method': 'get',
        'asynchronous': false
    };
    var xhrObj = new Ajax.Request( this.config.config_xml.api_url.getEpgCalendar , ajaxOpt );
    if( xhrObj && xhrObj._complete ){
        $("epg_date_controller").innerHTML = this.makeTopDateControllerHTML( xhrObj.transport.responseXML.documentElement );
        this.bindTopDateControllerEvent( this.dateSelectNode );
    }else{
        Element.setStyle( $( "epg_cloak" ) , "display: block;" );
        $( "cloak_img" ).src = this.config.error_image;
    }
};
/********************************************************************************/
// ↑日付選択エリアのHTML出力＋イベント設定↑
/********************************************************************************/




/********************************************************************************/
// ↓時間選択エリアのHTML出力＋イベント設定↓
/********************************************************************************/
IPG.EpgController.prototype.checkTimeRange = function( hour ){
    var hour = parseInt( hour , 10 );
    return ( 5 <= hour && hour < 12 ) ? 0 : ( 12 <= hour && hour < 19 ) ? 1 : ( 19 <= hour && hour < 23 ) ? 2 : 3;
};
IPG.EpgController.prototype.createTimeController = function(){
    if( !this.timeSelectNode ){
        this.timeSelectNode = this.document.createElement("div");
        this.controllerElement.appendChild( this.timeSelectNode );
        Element.setStyle( this.timeSelectNode , "width: 291px; height: 27px; position: relative; float: left;" );
        this.timeSelectNode.id = "epg_time_controller";
        var html = "<div id=\"epg_time_controll_title\" style=\"width: 27px; height: 27px; position: relative; float: left;\"><img src=\""+this.config.config_xml.img_path.timectrl_title+"\" style=\"margin: -12px 0px 0px -11px; position: absolute; top: 50%; left: 50%;\"></div>";
        html += "<div id=\"epg_time_controll_text\" style=\"width: 259px; height: 27px; margin-left: 5px; color: #686868; font-size: 9px; font-weight: bold; float: left;\">";
        html += "<div style=\"margin: 7px 0px 0px 0px; float: left;\">時間:</div>";
        html += "<div id=\"epg_time_controll_0\" name=\"epg_time_controll\" value=\"0\" style=\"padding: 7px 5px 0px 5px; float: left;\">5:00～</div>";
        html += "<div style=\"margin: 7px 0px 0px 0px;float: left;\">｜</div>";
        html += "<div id=\"epg_time_controll_1\" name=\"epg_time_controll\" value=\"1\" style=\"padding: 7px 5px 0px 5px; float: left;\">12:00～</div>";
        html += "<div style=\"margin: 7px 0px 0px 0px;float: left;\">｜</div>";
        html += "<div id=\"epg_time_controll_2\" name=\"epg_time_controll\" value=\"2\" style=\"padding: 7px 5px 0px 5px; float: left;\">19:00～</div>";
        html += "<div style=\"margin: 7px 0px 0px 0px;float: left;\">｜</div>";
        html += "<div id=\"epg_time_controll_3\" name=\"epg_time_controll\" value=\"3\" style=\"padding: 7px 5px 0px 5px; float: left;\">23:00～</div>";
        html += "</div>";
        this.timeSelectNode.innerHTML = html;
        this.timeControllerEventMethod = this.timeControllerEvent.bind( this );
    }
    this.bindTimeControllerEvent();
};
IPG.EpgController.prototype.timeControllerEvent = function( evt ){
    evt = IPG.Utility.fixEvent( evt , this );
    
    // 左クリック以外は処理しない。
    if( evt.which != 1 ){
        evt.preventDefault();
        return false;
    }
    
    var controller = $("epg_time_controll_text");
    if( !controller || !controller.childNodes || !controller.childNodes.length ) return;
    for( var i = 0; i < controller.childNodes.length; i++ ){
        if( controller.childNodes[i].getAttribute( "name" ) == "epg_time_controll" ){
            
            var today_str = $( "epg_date_controll_0" ).getAttribute( "value" );
            if( today_str == this.config.current_date ){
                var node_range = controller.childNodes[i].getAttribute( "value" );
                var server_hour_range = this.checkTimeRange( this.config.server_date.hour );
                if( node_range >= server_hour_range ){
                    Element.setStyle( controller.childNodes[i] , "color: #001B67; cursor: pointer;" );
                }else{
                   Element.setStyle( controller.childNodes[i] , "color: #686868; cursor: auto;" );
                }
            }else{
                Element.setStyle( controller.childNodes[i] , "color: #001B67; cursor: pointer;" );
            }
        }
    }
    Element.setStyle( evt.srcElement , "color: #0075CB; cursor: pointer;" );
    // EPGの描画位置を指定された時間枠にあわせるよう再描画
    
    var selectedRange = evt.srcElement.getAttribute( "value" );
    var currentDataArray = this.config.current_date.split( "-" );
    var moveToDate = undefined;
    if( selectedRange && selectedRange == 0 ){
        moveToDate = new Date( currentDataArray[0] , parseInt( currentDataArray[1] ,10 )-1 , currentDataArray[2] , "05" , "00" , "00" );
    }else if( selectedRange && selectedRange == 1 ){
        moveToDate = new Date( currentDataArray[0] , parseInt( currentDataArray[1] ,10 )-1 , currentDataArray[2] , "12" , "00" , "00" );
    }else if( selectedRange && selectedRange == 2 ){
        moveToDate = new Date( currentDataArray[0] , parseInt( currentDataArray[1] ,10 )-1 , currentDataArray[2] , "19" , "00" , "00" );
    }else if( selectedRange && selectedRange == 3 ){
        moveToDate = new Date( currentDataArray[0] , parseInt( currentDataArray[1] ,10 )-1 , currentDataArray[2] , "23" , "00" , "00" );
    }
    var earliestPgTime = this.container.serviceListmanager.earliestPgTime;
    var latestPgTime = this.container.serviceListmanager.latestPgTime;
    
    var newTop = 0;
    if( IPG.Utility.comparSIDateStr( earliestPgTime , moveToDate.getTime() ) < 0 ){
        //ジャンプ先の時間が一番早い開始時間よりも過去。→移動しない。
    }else{
        if( IPG.Utility.comparSIDateStr( moveToDate.getTime() , latestPgTime ) < 0 ){
            //ジャンプ先の時間が一番遅い開始終了よりも未来。→移動しない。
        }
        newTop = IPG.Utility.getMinuteDistance( earliestPgTime , moveToDate.getTime() );
        newTop = ( this.config.resize_flg ) ? ( newTop * this.config.config_xml.epg_info.minute_height * this.config.config_xml.epg_info.zoom_rate ) : ( newTop * this.config.config_xml.epg_info.minute_height );
    }
    // EPG再描画
    var slider = this.container.epgSlider;
    if( slider ){
        var currentX = 0;
        var currentY = 0;
        if( slider.scrollXAxisElements ){
            currentX = slider.scrollXAxisElements[0].scrollLeft;
        }
        if( slider.scrollYAxisElements ){
            for( var i = 0 , len = slider.scrollYAxisElements.length; i < len; i++ ){
                var target = slider.scrollYAxisElements[i];
                target.scrollTop = newTop;
            }
            currentY = target.scrollTop;
        }
        slider.setCurrentPosition( currentX , currentY );
        
        var yAxisSb = slider.scrollYAxisScrollBar;
        if( yAxisSb ){
            var tmpMoveY = newTop*yAxisSb.sliderPos.rate;
            var isNN_Y = ( tmpMoveY < 0 ) ? true : false;
            var integerMoveY = ( !isNN_Y ) ? Math.floor( tmpMoveY ) : Math.ceil( tmpMoveY );
            var frameElm = IPG.Utility.getElement( yAxisSb.controllerNodes.sb_frame );
            var newPosition = yAxisSb.sliderPos.max - integerMoveY;
            frameElm.scrollTop = newPosition;
        }
    }
    //Event.stop( evt );
    evt.preventDefault();
    return false;
};
IPG.EpgController.prototype.bindTimeControllerEvent = function(){
    var element = $( "epg_time_controll_text" );
    if( element && element.childNodes && element.childNodes.length ){
        for( var i = 0; i < element.childNodes.length; i++ ){
            if( element.childNodes[i].getAttribute( "name" ) == "epg_time_controll" ){
                
                Event.stopObserving( element.childNodes[i] , "mousedown" , this.timeControllerEventMethod );
                
                // 選択日付が当日の場合
                var today_str = $( "epg_date_controll_0" ).getAttribute( "value" );
                if( today_str == this.config.current_date ){
                    var node_range = element.childNodes[i].getAttribute( "value" );
                    var server_hour_range = this.checkTimeRange( this.config.server_date.hour );
                    if( node_range >= server_hour_range ){
                        // 色の判定。
                        var color = "color: #001B67; cursor: pointer;";
                        if( node_range == server_hour_range ) color = "color: #0075CB; cursor: pointer;";
                        Element.setStyle( element.childNodes[i] , color );
                        Event.observe( element.childNodes[i] , "mousedown" , this.timeControllerEventMethod );
                    }else{
                       Element.setStyle( element.childNodes[i] , "color: #686868; cursor: auto;" );
                    }
                }else{
                    Element.setStyle( element.childNodes[i] , "color: #001B67; cursor: pointer;" );
                    Event.observe( element.childNodes[i] , "mousedown" , this.timeControllerEventMethod );
                }
            }
        }
    }
};

/********************************************************************************/
// [地上波/BS]選択エリアのHTML出力＋イベント設定
/********************************************************************************/
IPG.EpgController.prototype.createCategoryController = function(){
    if( !this.categorySelectNode ){
        
        var clearNode = this.document.createElement("div");
        this.controllerElement.appendChild( clearNode );
        Element.setStyle( clearNode , "font-size: 0px; width: 0px; height: 0px; position: relative; clear: both;" );
        
        this.categorySelectNode = this.document.createElement("div");
        this.controllerElement.appendChild( this.categorySelectNode );
        Element.setStyle( this.categorySelectNode , "width: 243px; height: 24px; margin-top: 7px; position: relative; float: left;" );
        this.categorySelectNode.id = "epg_category_controller";
        
        // [BS]選択時の地域IDは「０」じゃなくなった。新たにBCTYPEを設ける。
        var buf = "";
        if( this.config.cookie.bctype == "OTD" ){
            buf += "<div id=\"epg_category_controll_0\" name=\"epg_category_controll\" value=\"OTD\" style=\"background-image: url("+this.config.config_xml.img_path.category_otd_selected+"); width: 119px; height: 24px; cursor: auto; float: left;\"></div>";
            buf += "<div id=\"epg_category_controll_1\" name=\"epg_category_controll\" value=\"BSD\" style=\"background-image: url("+this.config.config_xml.img_path.category_bsd+"); width: 119px; height: 24px; margin-left: 5px; cursor: pointer; float: left;\"></div>";
        }else if( this.config.cookie.bctype == "BSD" ){
            buf += "<div id=\"epg_category_controll_0\" name=\"epg_category_controll\" value=\"OTD\" style=\"background-image: url("+this.config.config_xml.img_path.category_otd+"); width: 119px; height: 24px; cursor: pointer; float: left;\"></div>";
            buf += "<div id=\"epg_category_controll_1\" name=\"epg_category_controll\" value=\"BSD\" style=\"background-image: url("+this.config.config_xml.img_path.category_bsd_selected+"); width: 119px; height: 24px; margin-left: 5px; cursor: auto; float: left;\"></div>";
        }
        this.categorySelectNode.innerHTML = buf;
        this.categoryControllerEventMethod = this.CategoryControllerEvent.bind(this);
    }
    this.bindCategoryControllerEvent( this.categorySelectNode );
};

IPG.EpgController.prototype.CategoryControllerEvent = function( evt ){
    evt = IPG.Utility.fixEvent( evt , this );
    
    // 左クリック以外は処理しない。
    if( evt.which != 1 ){
        evt.preventDefault();
        return false;
    }
    
    var selected_type = evt.srcElement.getAttribute( "value" );
    
    var otdNode = $("epg_category_controll_0");
    var bsdNode = $("epg_category_controll_1");
    
    if( selected_type == "OTD" ){
        Element.setStyle( otdNode , "background-image: url("+this.config.config_xml.img_path.category_otd_selected+"); cursor: auto;" );
        Element.setStyle( bsdNode , "background-image: url("+this.config.config_xml.img_path.category_bsd+"); cursor: pointer;" );
    }else if( selected_type == "BSD" ){
        Element.setStyle( otdNode , "background-image: url("+this.config.config_xml.img_path.category_otd+"); cursor: pointer;" );
        Element.setStyle( bsdNode , "background-image: url("+this.config.config_xml.img_path.category_bsd_selected+"); cursor: auto;" );
    }
    /*
    if( !controller || !controller.childNodes || !controller.childNodes.length ) return;
    for( var i = 0; i < controller.childNodes.length; i++ ){
        if( controller.childNodes[i].getAttribute( "name" ) == "epg_category_controll" ){
            Element.setStyle( controller.childNodes[i] , "background-color: gainsboro" );
        }
    }
    */
    
    this.config.cookie.bctype = selected_type;
    
    if( this.config.cookie.bctype == "BSD" && this.sortNode ){
        this.sortNode.style.visibility = "hidden";
    }else if( this.config.cookie.bctype == "OTD" && this.sortNode ){
        this.sortNode.style.visibility = "visible";
    }
    
    this.container.refresh();
    
    //Event.stop( evt );
    evt.preventDefault();
    return false;
};

IPG.EpgController.prototype.bindCategoryControllerEvent = function( element ){
    if( element.childNodes && element.childNodes.length ){
        for( var i = 0; i < element.childNodes.length; i++ ){
            
            Event.stopObserving( element.childNodes[i] , "mousedown" , this.categoryControllerEventMethod );
            
            // 選択中箇所にはイベントの割り当ては行わない。
            if( element.childNodes[i].getAttribute( "value" ) == this.config.cookie.bctype ) continue;
            
            Event.observe( element.childNodes[i] , "mousedown" , this.categoryControllerEventMethod );
        }
    }
};

/********************************************************************************/
// 地域選択エリアのHTML出力＋イベント設定
/********************************************************************************/
IPG.EpgController.prototype.createAreaSelector = function( areaListManager ){
    if( !this.areaSelectNode ){
        this.areaSelectNode = this.document.createElement("div");
        this.controllerElement.appendChild( this.areaSelectNode );
        Element.setStyle( this.areaSelectNode , "width: 195px; height: 27px; position: relative; float: left;" );
        this.areaSelectNode.id = "epg_area_controller";
    }
    if( areaListManager ){
        // 作成ノード内容を生成。
        var def_val = ( this.config.cookie.area && this.config.cookie.area == this.config.config_xml.epg_info.area_bs_id ) ? this.config.config_xml.epg_info.area_default_id : this.config.cookie.area;
        areaListManager.makeAreaSelector( this.areaSelectNode , def_val );
    }else{
        //IPG.Utility.debugOut( '[onException@EpgController]' , "debug" , "red" );
        this.areaSelectNode.innerHTML = "地域情報のロードに失敗。";
    }
};
IPG.EpgController.prototype.createTopAreaSelector = function( areaListManager ){
    if( !this.areaSelectNode ){
        this.areaSelectNode = this.document.createElement("div");
        this.controllerElement.appendChild( this.areaSelectNode );
        Element.setStyle( this.areaSelectNode , "width: 195px; height: 27px; position: relative; float: right;" );
        this.areaSelectNode.id = "epg_area_controller";
    }
    if( areaListManager ){
        // 作成ノード内容を生成。
        var def_val = ( this.config.cookie.area && this.config.cookie.area == this.config.config_xml.epg_info.area_bs_id ) ? this.config.config_xml.epg_info.area_default_id : this.config.cookie.area;
        areaListManager.makeAreaSelector( this.areaSelectNode , def_val );
    }else{
        //IPG.Utility.debugOut( '[onException@EpgController]' , "debug" , "red" );
        this.areaSelectNode.innerHTML = "地域情報のロードに失敗。";
    }
};

/********************************************************************************/
// ソートタイプ変更エリアのHTML出力＋イベント設定
/********************************************************************************/
IPG.EpgController.prototype.createSortController = function( isTop ){
    if( !this.sortNode ){
        this.sortNode = this.document.createElement("div");
        this.controllerElement.appendChild( this.sortNode );
        if( !isTop ) Element.setStyle( this.sortNode , "width: 119px; height:26px; background-image: url("+this.config.config_xml.img_path.sortctrl_button+"); position: relative; left: 445px; cursor: pointer; float: left;" );
        else Element.setStyle( this.sortNode , "width: 119px; height:26px; background-image: url("+this.config.config_xml.img_path.sortctrl_button+"); position: relative; margin-top: 10px; cursor: pointer; float: left;" );
        this.sortNode.id = "epg_sort_controll";
        this.sortControllerEventMethod = this.sortControllerEvent.bind( this );
        this.sortControllerMouseOverMethod = this.sortControllerMouseOver.bind( this );
        this.sortControllerMouseOutMethod = this.sortControllerMouseOut.bind( this );
    }
    if( this.config.cookie.bctype == "BSD" ) this.sortNode.style.visibility = "hidden";
    this.bindSortControllerEvent( this.sortNode );
};

IPG.EpgController.prototype.sortControllerEvent = function( evt ){
    //IPG.Utility.debugOut( '[EventHandler@sortControllerEvent]' , "debug" , "red" );
    evt = IPG.Utility.fixEvent( evt , this );
    
    // 左クリック以外は処理しない。
    if( evt.which != 1 ){
        evt.preventDefault();
        return false;
    }
    
    var doc = evt.srcElement.ownerDocument || evt.srcElement.document;
    var controll = doc.getElementById( "epg_sort_controll" );
    if( !controll ) return;
    if( this.config.cookie.sorttype == 1 ){
        this.config.cookie.sorttype = 0;
        //Element.setStyle( controll , "border: 1px solid black" );
    }else{
        this.config.cookie.sorttype = 1;
        //Element.setStyle( controll , "border: 1px solid red" );
    }
    this.container.refresh();
    
    //Event.stop( evt );
    evt.preventDefault();
    return false;
};
IPG.EpgController.prototype.sortControllerMouseOver = function( evt ){
    evt = IPG.Utility.fixEvent( evt , this );
    Element.setStyle( this.sortNode , "background-image: url("+this.config.config_xml.img_path.sortctrl_button_over+");" );
    Event.stop( evt );
    return false;
};
IPG.EpgController.prototype.sortControllerMouseOut = function( evt ){
    evt = IPG.Utility.fixEvent( evt , this );
    Element.setStyle( this.sortNode , "background-image: url("+this.config.config_xml.img_path.sortctrl_button+");" );
    Event.stop( evt );
    return false;
};

IPG.EpgController.prototype.bindSortControllerEvent = function( element ){
    if( !element ) return;
    Event.observe( element , "mousedown" , this.sortControllerEventMethod );
    Event.observe( element , "mouseover" , this.sortControllerMouseOverMethod );
    Event.observe( element , "mouseout" , this.sortControllerMouseOutMethod );
};

/********************************************************************************/
// ジャンルカラー変更エリアのHTML出力＋イベント設定
/********************************************************************************/
IPG.EpgController.prototype.createGenreColorController = function( genreListManager ){
    if( !this.genreSelectorNode ){
        this.genreSelectorNode = this.document.createElement("div");
        this.controllerElement.appendChild( this.genreSelectorNode );
        this.genreSelectorNode.id = "epg_genrecolor_controll";
        Element.setStyle( this.genreSelectorNode , "width: 135px; height:26px; position: relative; left: 450px; cursor: pointer; float: left; z-index: 2;" );
        
        var imgNode = this.document.createElement("img");
        this.genreSelectorNode.appendChild( imgNode );
        imgNode.id = "epg_genrecolor_controll_button";
        imgNode.src = this.config.config_xml.img_path.genrectrl_button;
    }
    if( genreListManager ){
        genreListManager.createGenreColorSelector( this.genreSelectorNode );
    }else{
        //IPG.Utility.debugOut( '[onException@EpgController]' , "debug" , "darkolivegreen" );
    }
};

/********************************************************************************/
// EPGサイズ変更エリアのHTML出力＋イベント設定
/********************************************************************************/
IPG.EpgController.prototype.createResizeController = function(){
    if( !this.resizeNode ){
        this.resizeNode = this.document.createElement("div");
        this.controllerElement.appendChild( this.resizeNode );
        Element.setStyle( this.resizeNode , "width: 31px; height:27px; background-image: url("+this.config.config_xml.img_path.resizectrl_button_plus+"); position: relative; left: 455px; cursor: pointer; float: left; z-index: 1;" );
        this.resizeNode.id = "epg_resize_controll";
        this.resizeControllerEventMethod = this.resizeControllerEvent.bind( this );
    }
    this.bindResizeControllerEvent( this.resizeNode );
};
IPG.EpgController.prototype.resizeControllerEvent = function( evt ){
    evt = IPG.Utility.fixEvent( evt , this );
    
    // 左クリック以外は処理しない。
    if( evt.which != 1 ){
        evt.preventDefault();
        return false;
    }
    
    var doc = evt.srcElement.ownerDocument || evt.srcElement.document;
    var controll = doc.getElementById( "epg_resize_controll" );
    if( !controll ) return;
    if( this.config.resize_flg == 1 ){
        this.config.resize_flg = 0;
        this.container.serviceListmanager.resize_flg = 0;
        Element.setStyle( controll , "background-image: url("+this.config.config_xml.img_path.resizectrl_button_plus+");" );
    }else{
        this.config.resize_flg = 1;
        this.container.serviceListmanager.resize_flg = 1;
        Element.setStyle( controll , "background-image: url("+this.config.config_xml.img_path.resizectrl_button_minus+");" );
    }
    
    this.container.refresh();
	
	// リフレッシュじゃなくて、現在表示中の内容を変更するだけの処理を実装するのもアリ。TODO?
	
    //Event.stop( evt );
    evt.preventDefault();
    return false;
};
IPG.EpgController.prototype.bindResizeControllerEvent = function( element ){
    if( !element ) return;
    Event.observe( element , "mousedown" , this.resizeControllerEventMethod );
};
