function VIET_vnl_ui_TvGuide() {
    this.arItems = [];
    this.oScrollDECE = new DECE(100);
    this.bCalendarVis = false;
}
VIET_vnl_ui_TvGuide.prototype = {
    onload: function() {

        if( typeof parent.onTvGuideLoaded != "undefined" ) 
            parent.onTvGuideLoaded();

        oServerTime.init();
        this.replaceHref();

        //
        // load tv guide for today
        //
        //this.arItems = arStartupItems;
        this.updateGuideContent(arStartupItems, VIET_vnl_util_ParseDateTimeFromMySQL(sStartupDate), iStartupChannelId);

        //this.onscroll();

        var me = this;
        $('cnt').onscroll = function() {
            me.oScrollDECE.Exec( function() { me.onscroll(); } );
        }
    },

    replaceHref: function() {
        var arAs = document.getElementsByTagName('a');
        //var re1 = /\/\?tvGuideId=(\d+)/;
        //var re2 = /\?date=(.+)&channelId=(\d)/;
        var re = /\/program\/channel\/(\d+).*\/date\/(.*)/;
        for( var i=0; i<arAs.length; i++ ) {
            //
            // replacing guide item links with javascript action
            //
            //var arM1 = re1.exec(arAs[i].href);
            //if( arM1!=null && arM1.length>1 ) {
            //    arAs[i].href = 'javascript:oTvGuide.playGuideItem(' + arM1[1] + ')';
            //    arAs[i].target = '_self';
            //}
            //
            // replacing calendar links with javascript action
            //
            //else {
            //    var arM2 = re2.exec(arAs[i].href);
            //    if( arM2!=null && arM2.length>2 )
            //        arAs[i].href = 'javascript:oTvGuide.loadGuide("' + arM2[1] + '", ' + arM2[2] + ')';
            //}
            var arM = re.exec(arAs[i].href);
            if( arM!=null && arM.length>2 )
                arAs[i].href = 'javascript:oTvGuide.loadGuide("' + arM[2] + '", ' + arM[1] + ')';
        }
    },
    
    onscroll: function() {
        var rows = $('guideCnt').rows;
        var len = rows.length;
        if( len<=1 ) return;

        var winMin = $('cnt').scrollTop, winMax = $('cnt').scrollTop + $('cnt').offsetHeight;
        var dtLocalTime = getLocalTime();
        for( var i=0; i<len; i++ ) {
            var id = rows[i].id.substring(2);

            if( this.arItems[id]==null )
                continue;

            if( this.arItems[id].loaded )
                continue;

            var dtAirTime = new Date();
            if( this.arItems[id]['airTime']!=null ) {
                dtAirTime = VIET_vnl_util_ParseDateTimeFromMySQL(this.arItems[id]['airTime']);
                if( dtAirTime>dtLocalTime )
                    continue;
            }

            var rowTop = rows[i].offsetTop, rowBott = rows[i].offsetTop + rows[i].offsetHeight;
            var vis = (rowTop>=winMin && rowTop<winMax) || (rowBott>winMin && rowBott<=winMax);
            if( vis ) {
                if( $('giThumb'+id)!=null && this.arItems[id]!=null && this.arItems[id]['withClips'] ) {
                    this.arItems[id]['loaded'] = true;
                    this.loadGuideItemThumb(id, this.arItems[id]['thumbDocId'], dtAirTime);
                }
                else
                    this.arItems[id] = {loaded:true};
            } else if( rowTop>=winMax )
                break;
        }
    },

    //
    // determine if the item is hot, get thumbnail
    //
    loadGuideItemThumb: function(id, thumbDocId, dtAirTime) {

        var sUrl = getJsonUrl({action:'program-item', type:'thumbnail', 'thumbDocId':thumbDocId, airTime:dtAirTime, format:'json'});
        var handleSuccess = function(o){
            try {
                var arRes = eval("(" + o.responseText + ")");
                if( arRes.length>0 ) {
                    $('giThumb' + id).innerHTML = '<a href="javascript:oTvGuide.playGuideItem(' + id + ')">'
                        +   '<img id="guideindex_item_thumb_' + id + '" src="' + arRes[0] + '" class="guide_item_thumb" />'
                        +   '<div id="guideindex_item_playbu' + id + '" class="guide_item_thumb_play"></div></a>';
                }
            }
            catch(ex) {}
        }
        
        var handleFailure = function() {
        }

        YAHOO.util.Connect.asyncRequest('GET', sUrl, {success:handleSuccess, failure:handleFailure, argument:[]});
    },
    
    playGuideItem: function(iGuideId) {
        if( typeof parent.playGuide != "undefined" )
            parent.playGuide(iGuideId);
    },
    
    closeGuide: function() {
        if( typeof parent.onCloseTvGuide != "undefined" )
            parent.onCloseTvGuide();
    },
    
    loadGuide: function(sDate, iChannelId) {

	pageTracker._trackPageview('loadGuide ' + sDate + ' (' + iChannelId + ')');

        var dtDate = VIET_vnl_util_ParseDateTimeFromMySQL(sDate + ' 00:00:00');
        $('busy').innerHTML = 'Loading ' + VIET_vnl_util_GetChannelName(iChannelId) + ' TV guide for ' + VIET_vnl_util_ToDateString(dtDate, 'en', 's') + ' ...';
        $('busy').style.display = 'block';

        this.updateCalendar(dtDate, sDate, iChannelId);
        this.loadGuideContent(dtDate, iChannelId);
        //$('busy').style.display = 'none';
        //alert(sDate + ' ' + iChannelId);
    },

    //
    // update calendar for a given date
    //
    updateCalendar: function(dtDate, sDate, iChannelId) {
        //$('ch_1').innerHTML = (iChannelId==1 ? 'HTV7' : '<a class="lkCh" href="javascript:oTvGuide.loadGuide(\'' + sDate + '\', 1)">HTV7</a>');
        $('ch_1').className = (iChannelId==1 ? 'lkCh_A' : 'lkCh');
        $('ch_1').href = 'javascript:oTvGuide.loadGuide(\'' + sDate + '\', 1)';
        //$('ch_2').innerHTML = (iChannelId==2 ? 'HTV9' : '<a class="lkCh" href="javascript:oTvGuide.loadGuide(\'' + sDate + '\', 2)">HTV9</a>');
        $('ch_2').className = (iChannelId==2 ? 'lkCh_A' : 'lkCh');
        $('ch_2').href = 'javascript:oTvGuide.loadGuide(\'' + sDate + '\', 2)';

        $('monthTxt').innerHTML = VIET_vnl_util_ToMonthString(dtDate).toUpperCase();
        $('lkPrevMonth').href = 'javascript:oTvGuide.loadGuide("' + dtDate.getFullYear() + '-' + dtDate.getMonth() + '-' + dtDate.getDate() + '", ' + iChannelId + ')';
        $('lkNextMonth').href = 'javascript:oTvGuide.loadGuide("' + dtDate.getFullYear() + '-' + (dtDate.getMonth()+2) + '-' + dtDate.getDate() + '", ' + iChannelId + ')';

        var s = '<table id="calDays" border="0" cellpadding="0" cellspacing="0">';
        var dtToday = new Date();
        for( var i=1; i<=32; i++ ) {
            var dtTemp = new Date(dtDate.getFullYear(), dtDate.getMonth(), i, 0, 0, 0, 0);
            var bShowingDay = (dtDate.getDate()==i);
            var bToday = (dtToday.getFullYear()==dtTemp.getFullYear() && dtToday.getMonth()==dtTemp.getMonth() && dtToday.getDate()==dtTemp.getDate());
            
            // month-end
            if( dtTemp.getMonth()!=dtDate.getMonth() ) {
                if( dtTemp.getDay()!=0 ) {
                    for( var j=dtTemp.getDay(); j<7; j++ ) {
                        s += '<td></td>';
                    }
                    s += '</tr>\n';
                }
                break;
            }
            
            // month-start
            if( i==1 ) {
                s += '<tr>\n';
                for( var j=0; j<dtTemp.getDay(); j++ ) {
                    s += '<td></td>';
                }
            }

            // week-start
            else if( dtTemp.getDay()==0 )
                s += '<tr>\n';
            
            s += '<td><a class="' + (bToday ? 'lkCalToday' : 'lkCalDay') + (bShowingDay ? ' lkCalShowingDay' : '') + '" href="javascript:oTvGuide.loadGuide(\''
                + dtTemp.getFullYear() + '-' + (dtTemp.getMonth()+1) + '-' + dtTemp.getDate() + '\', ' + iChannelId + ')">' + i + '</a></td>\n';
            
            // week-end
            if( dtTemp.getDay()==6 )
                s += '</tr>\n';
        }
        s += '</table>';
        $('guideindex_caldaymonth_content').innerHTML = s;
    },

    //
    // get tv guide from server and update
    //
    loadGuideContent: function(dtDate, iChannelId) {
        var sUrl = getJsonUrl({action:'program', date:VIET_vnl_util_ToMySQLDate(dtDate), channel:iChannelId, format:'json'});

        var me = this;
        var handleSuccess = function(o){
            var obj;
            try {
                obj = eval("(" + o.responseText + ")");
                me.updateGuideContent(obj, dtDate, iChannelId);
            }
            catch(ex) {}
            $('busy').style.display = 'none';
        }

        var handleFailure = function() {
            $('busy').style.display = 'none';
        }

        YAHOO.util.Connect.asyncRequest('GET', sUrl, {success:handleSuccess, failure:handleFailure});
    },

    //
    // update interface for the tv guide content
    //
    updateGuideContent: function(arGuides, dtDate, iChannelId) {
        this.arItems = [];

        //$('cntHdr').innerHTML = VIET_vnl_util_GetChannelName(iChannelId) + ' - ' + VIET_vnl_util_ToDateString(dtDate, 'en', 'l');
        //$('guideindex_titlectrl_channel_bucenter').innerHTML = VIET_vnl_util_GetChannelName(iChannelId);
        var sDate = VIET_vnl_util_ToDateString(dtDate, 'en', 'l');
        $('guideindex_titlectrl_date_bucenter').innerHTML = VIET_vnl_util_GetChannelName(iChannelId) + ' &nbsp; | &nbsp; ' + sDate;

        var s = '';
        if( arGuides==null || arGuides.length<=0 )
            s = '<div id="noavail">No TV program found for this day (' + sDate + ').</div>';
        else {
            s = '<table id="guideCnt" class="guideCnt" cellpadding="0" cellspacing="0" border="0">';
            var dtNow = new Date();
            var reAir = this.isReAir(dtDate, iChannelId);
            for( var i=0; i<arGuides.length; i++ ) {

                var dtAirTime = VIET_vnl_util_ParseDateTimeFromMySQL(arGuides[i]["airTime"]);
                var id = arGuides[i]['id'];

                //
                // for channel 1-HTV7: re-air the morning with yesterday afternoon
                //
                if( reAir ) {
                    if( dtAirTime.getHours()<12 )
                        continue;
                    else if( dtAirTime.getDate()!=dtDate.getDate() )
                        dtAirTime.setMilliseconds( dtAirTime.getMilliseconds() + 12*60*60*1000 );
                }

                this.arItems[id] = arGuides[i]; 

                var iTemp = arGuides[i]["dTitle"].indexOf(':');
                //var arTitle = arGuides[i]["dTitle"].split(":", 2);
                var sCat = (iTemp>0 ? arGuides[i]["dTitle"].substring(0, iTemp) : "");
                var sTitle = (iTemp>0 ? arGuides[i]["dTitle"].substring(iTemp+1).replace(/^[\s\+]*/, '') : arGuides[i]["dTitle"]);
                var bHot = (dtAirTime.getTime()<=dtNow.getTime()) && arGuides[i]["withClips"];
                //var sHot = (bHot ? "Hot" : "");
                
                s += '<tr id="gi' + id + '" class="guide_item"';
                if( bHot )
                    s += ' onmouseover="oTvGuide.guideItem_onmouseover(\'' + id + '\')" onmouseout="oTvGuide.guideItem_onmouseout(\'' + id + '\')"';
                s += '><td class="guide_item_time">' 
                    +   (bHot ? '<a href="javascript:oTvGuide.playGuideItem(' + id + ')">' : '')
                    +   VIET_vnl_util_ToTvGuideTime(dtAirTime) + ' ' + VIET_vnl_util_ToTvGuideTimeAmPm(dtAirTime) 
                    +   (bHot ? '</a>' : '') + '</td>';
                    
                    /*<span class="giHr">'
                    + VIET_vnl_util_ToTvGuideTime(dtAirTime) + '</span><br />'
                    + '<span class="giAmpm">' + VIET_vnl_util_ToTvGuideTimeAmPm(dtAirTime) + '</span></td>'
                    + '<td class="giInfo' + (i==0 ? "" : " giLnT") + '">';*/

                s += '<td class="guide_item_thumb">'
                    +   '<div id="giThumb' + id + '" class="guide_item_thumb">'
                    +       (bHot ? '<a href="javascript:oTvGuide.playGuideItem(' + id + ')">' : '')
                    +       '<img id="guideindex_item_thumb_' + id + '" src="/images/px_clear.gif" class="guide_item_thumb" />'
                    +       '<div id="guideindex_item_playbu' + id + '" class="guide_item_thumb_play"></div>'
                    +       (bHot ? '</a>' : '')
                    +   '</div></td>'
                    +   '<td class="guide_item_info">' 
                    +       '<div id="giTt' + id + '" class="guide_item_info_title">'
                    +           (bHot ? '<a class="guide_item_info_title_lk" href="javascript:oTvGuide.playGuideItem(' + id + ')">' : '')
                    +               (sCat!='' ? '<div id="giCat' + id + '" class="guide_item_info_cat">' + sCat + ':</div>' : '')
                    +               sTitle
                    +           (bHot ? '</a>' : '')
                    +       '</div></td>';
 
                /*if( bHot ) {
                    s += '<table class="giInfo" cellpadding="0" cellspacing="0" border="0">'
                        +   '<tr><td class="giThumb"><div id="giThumb' + id + '" class="giThumb"><a href="javascript:oTvGuide.playGuideItem(' + id + ')"><img class="giThumb" src="/images/px_clear.gif" border="0" /></a></div></td>'
                        +   '<td class="giTxt">'
                        +   (sCat!="" ? '<div id="giCat' + id + '" class="giCat">' + sCat + ':</div>' : "")
                        +   '<div id="giTt' + id + '" class="giTt"><a class="giTt" href="javascript:oTvGuide.playGuideItem(' + id + ')">'
                        +       sTitle + '</a></div>'
                        +   '</td></tr>'
                        +   '</table>';
                }
                else {
                    s += (sCat!="" ? '<div id="giCat' + id + '" class="giCat">' + sCat + ':</div>' : "") 
                        + '<div id="giTt' + id + '" class="giTt">' + sTitle + '</div>';
                }*/

                s += '</tr>';
            }
            s += '</table>';
        }
        $('cnt').innerHTML = s;
        this.onscroll();
    },

    guideItem_onmouseover: function(id) {
        $('gi' + id).className = 'guide_item_mouseover';
        $('guideindex_item_playbu' + id).style.display = 'block';
    },
    
    guideItem_onmouseout: function(id) {
        $('gi' + id).className = 'guide_item';
        $('guideindex_item_playbu' + id).style.display = 'none';
    },

    //
    // toggle between showing or hiding calendar control
    //
    toggleCalendar: function() {
        $('guideindex_calendar').style.visibility = this.bCalendarVis ? 'hidden' : 'visible';
        $('guideindex_titlectrl_date_bucenter').className = 'button_center' + (this.bCalendarVis ? '' : ' button_hover');
        $('guideindex_titlectrl_date_budropdown').className = 'button_dropdown' + (this.bCalendarVis ? '' : ' button_hover');
        $('guideindex_titlectrl_date_buleft').className = 'button_left' + (this.bCalendarVis ? '' : ' button_hover');
        $('guideindex_titlectrl_date_buright').className = 'button_right' + (this.bCalendarVis ? '' : ' button_hover');
        this.bCalendarVis = !this.bCalendarVis;
    },

    //
    // for channel HTV7, re-air yesterday pm for today am
    //
    isReAir: function(dtDate, iChannelId) {
        var dtToday = new Date();
        return (iChannelId==1) && (dtDate.getFullYear()==dtToday.getFullYear()) 
            && (dtDate.getMonth()==dtToday.getMonth()) && (dtDate.getDate()==dtToday.getDate());
    }
}
var oTvGuide = new VIET_vnl_ui_TvGuide();
