content: 
  
  sub init()
      m.EPGLaunchCompleteSignaled = false
      m.scheduleGrid = m.top.findNode("scheduleGrid")
      m.detailsPane = m.top.findNode("detailsPane")
      m.detailsPane.observeField("watchSelectedChannel", "onWatchChannelSelected")
      m.detailsPane.observeField("recordSelectedChannel", "onRecordChannelSelected")
      m.detailsPane.observeField("recordSeriesSelectedChannel", "onRecordSeriesChannelSelected")
      m.gridStartDate = CreateObject("roDateTime")
      m.scheduleGrid.contentStartTime = m.gridStartDate.AsSeconds() - 1800
      m.gridEndDate = createObject("roDateTime")
      m.gridEndDate.FromSeconds(m.gridStartDate.AsSeconds() + (24 * 60 * 60))
      m.scheduleGrid.observeField("programFocused", "onProgramFocused")
      m.scheduleGrid.observeField("programSelected", "onProgramSelected")
      m.scheduleGrid.observeField("leftEdgeTargetTime", "onGridScrolled")
      m.scheduleGrid.channelInfoWidth = 350
      m.gridMoveAnimation = m.top.findNode("gridMoveAnimation")
      m.gridMoveAnimationPosition = m.top.findNode("gridMoveAnimationPosition")
      m.LoadChannelsTask = createObject("roSGNode", "LoadChannelsTask")
      m.LoadChannelsTask.observeField("channels", "onChannelsLoaded")
      m.LoadChannelsTask.control = "RUN"
      m.top.lastFocus = m.scheduleGrid
      m.channelIndex = {}
  end sub
  
  sub channelFilterSet()
      m.scheduleGrid.jumpToChannel = 0
      if m.top.filter <> invalid and m.LoadChannelsTask.filter <> m.top.filter
          if m.LoadChannelsTask.state = "run" then
              m.LoadChannelsTask.control = "stop"
          end if
          m.LoadChannelsTask.filter = m.top.filter
          m.LoadChannelsTask.control = "RUN"
      end if
  end sub
  
  
  sub channelsearchTermSet()
      m.scheduleGrid.jumpToChannel = 0
  
      if LCase(m.top.searchTerm) = LCase(tr("all")) or m.LoadChannelsTask.searchTerm = LCase(tr("all"))
          m.top.searchTerm = " "
          m.LoadChannelsTask.searchTerm = " "
          startLoadingSpinner()
          m.LoadChannelsTask.control = "RUN"
  
      else if m.top.searchTerm <> invalid and LCase(m.LoadChannelsTask.searchTerm) <> LCase(m.top.searchTerm)
          if m.LoadChannelsTask.state = "run" then
              m.LoadChannelsTask.control = "stop"
          end if
          m.LoadChannelsTask.searchTerm = m.top.searchTerm
          startLoadingSpinner()
          m.LoadChannelsTask.control = "RUN"
      end if
  end sub
  
  
  sub onChannelsLoaded()
      gridData = createObject("roSGNode", "ContentNode")
      counter = 0
      channelIdList = ""
  
      if m.LoadChannelsTask.channels.count() > 0
          for each item in m.LoadChannelsTask.channels
              gridData.appendChild(item)
              m.channelIndex[item.Id] = counter
              counter = counter + 1
              channelIdList = channelIdList + item.Id + ","
          end for
          m.scheduleGrid.content = gridData
          m.LoadScheduleTask = createObject("roSGNode", "LoadScheduleTask")
          m.LoadScheduleTask.observeField("schedule", "onScheduleLoaded")
          m.LoadScheduleTask.startTime = m.gridStartDate.ToISOString()
          m.LoadScheduleTask.endTime = m.gridEndDate.ToISOString()
          m.LoadScheduleTask.channelIds = channelIdList
          m.LoadScheduleTask.control = "RUN"
          m.LoadProgramDetailsTask = createObject("roSGNode", "LoadProgramDetailsTask")
          m.LoadProgramDetailsTask.observeField("programDetails", "onProgramDetailsLoaded")
          m.scheduleGrid.setFocus(true)
          if m.EPGLaunchCompleteSignaled = false
              m.top.signalBeacon("EPGLaunchComplete") ' Required Roku Performance monitoring
              m.EPGLaunchCompleteSignaled = true
          end if
          m.LoadChannelsTask.channels = []
      end if
  end sub
  
  
  sub onScheduleLoaded()
  
      if m.scheduleGrid.content.GetChildCount() <= 0
          return
      end if
      for each item in m.LoadScheduleTask.schedule
          channel = m.scheduleGrid.content.GetChild(m.channelIndex[item.ChannelId])
          if channel.PosterUrl <> ""
              item.channelLogoUri = channel.PosterUrl
          end if
          if channel.Title <> ""
              item.channelName = channel.Title
          end if
          channel.appendChild(item)
      end for
      m.scheduleGrid.showLoadingDataFeedback = false
      m.scheduleGrid.setFocus(true)
      m.LoadScheduleTask.schedule = []
      stopLoadingSpinner()
  end sub
  
  sub onProgramFocused()
      m.top.watchChannel = invalid
  
      if m.scheduleGrid.content.getChildCount() <= 0
          channel = invalid
      else
          channel = m.scheduleGrid.content.GetChild(m.scheduleGrid.programFocusedDetails.focusChannelIndex)
      end if
      m.detailsPane.channel = channel
      m.top.focusedChannel = channel
  
      if channel = invalid or channel.getChildCount() = 0
          m.detailsPane.programDetails = invalid
          return
      end if
      prog = channel.GetChild(m.scheduleGrid.programFocusedDetails.focusIndex)
      if prog <> invalid and prog.fullyLoaded = false
          m.LoadProgramDetailsTask.programId = prog.Id
          m.LoadProgramDetailsTask.channelIndex = m.scheduleGrid.programFocusedDetails.focusChannelIndex
          m.LoadProgramDetailsTask.programIndex = m.scheduleGrid.programFocusedDetails.focusIndex
          m.LoadProgramDetailsTask.control = "RUN"
      end if
      m.detailsPane.programDetails = prog
  end sub
  
  
  sub onProgramDetailsLoaded()
      if m.LoadProgramDetailsTask.programDetails = invalid then
          return
      end if
      channel = m.scheduleGrid.content.GetChild(m.LoadProgramDetailsTask.programDetails.channelIndex)
  
      if m.LoadProgramDetailsTask.programDetails.PosterUrl = invalid or m.LoadProgramDetailsTask.programDetails.PosterUrl = ""
          m.LoadProgramDetailsTask.programDetails.PosterUrl = channel.PosterUrl
      end if
      channel.ReplaceChild(m.LoadProgramDetailsTask.programDetails, m.LoadProgramDetailsTask.programDetails.programIndex)
      m.LoadProgramDetailsTask.programDetails = invalid
      m.scheduleGrid.showLoadingDataFeedback = false
  end sub
  
  sub onProgramSelected()
  
      if m.detailsPane.programDetails = invalid
          m.top.watchChannel = m.scheduleGrid.content.GetChild(m.scheduleGrid.programFocusedDetails.focusChannelIndex)
          return
      end if
  
      focusProgramDetails(true)
  end sub
  
  
  sub focusProgramDetails(setFocused)
      h = m.detailsPane.height
      if h < 400 then
          h = 400
      end if
      h = h + 160 + 80
      if setFocused = true
          m.gridMoveAnimationPosition.keyValue = [
              [
                  0
                  600
              ]
              [
                  0
                  h
              ]
          ]
          m.detailsPane.setFocus(true)
          m.detailsPane.hasFocus = true
          m.top.lastFocus = m.detailsPane
      else
          m.detailsPane.hasFocus = false
          m.gridMoveAnimationPosition.keyValue = [
              [
                  0
                  h
              ]
              [
                  0
                  600
              ]
          ]
          m.scheduleGrid.setFocus(true)
          m.top.lastFocus = m.scheduleGrid
      end if
      m.gridMoveAnimation.control = "start"
  end sub
  
  
  sub onWatchChannelSelected()
      if m.detailsPane.watchSelectedChannel = false then
          return
      end if
  
      focusProgramDetails(false)
      m.top.watchChannel = m.detailsPane.channel
  end sub
  
  
  sub onGridScrolled()
  
      if m.scheduleGrid.leftEdgeTargetTime + (12 * 60 * 60) > m.gridEndDate.AsSeconds()
  
          if m.LoadScheduleTask.state <> "run"
              m.LoadScheduleTask.startTime = m.gridEndDate.ToISOString()
              m.gridEndDate.FromSeconds(m.gridEndDate.AsSeconds() + (24 * 60 * 60))
              m.LoadScheduleTask.endTime = m.gridEndDate.ToISOString()
              m.LoadScheduleTask.control = "RUN"
          end if
      end if
  end sub
  
  
  sub onRecordChannelSelected()
      if m.detailsPane.recordSelectedChannel = false then
          return
      end if
  
      focusProgramDetails(false)
      m.scheduleGrid.showLoadingDataFeedback = true
      m.RecordProgramTask = createObject("roSGNode", "RecordProgramTask")
      m.RecordProgramTask.programDetails = m.detailsPane.programDetails
      m.RecordProgramTask.recordSeries = false
      m.RecordProgramTask.observeField("recordOperationDone", "onRecordOperationDone")
      m.RecordProgramTask.control = "RUN"
  end sub
  
  
  sub onRecordSeriesChannelSelected()
      if m.detailsPane.recordSeriesSelectedChannel = false then
          return
      end if
  
      focusProgramDetails(false)
      m.scheduleGrid.showLoadingDataFeedback = true
      m.RecordProgramTask = createObject("roSGNode", "RecordProgramTask")
      m.RecordProgramTask.programDetails = m.detailsPane.programDetails
      m.RecordProgramTask.recordSeries = true
      m.RecordProgramTask.observeField("recordOperationDone", "onRecordOperationDone")
      m.RecordProgramTask.control = "RUN"
  end sub
  
  sub onRecordOperationDone()
      if m.RecordProgramTask.recordSeries = true and m.LoadScheduleTask.state <> "run"
          m.LoadScheduleTask.control = "RUN"
      else
  
  
          channel = m.scheduleGrid.content.GetChild(m.scheduleGrid.programFocusedDetails.focusChannelIndex)
          prog = channel.GetChild(m.scheduleGrid.programFocusedDetails.focusIndex)
          m.LoadProgramDetailsTask.programId = prog.Id
          m.LoadProgramDetailsTask.channelIndex = m.scheduleGrid.programFocusedDetails.focusChannelIndex
          m.LoadProgramDetailsTask.programIndex = m.scheduleGrid.programFocusedDetails.focusIndex
          m.LoadProgramDetailsTask.control = "RUN"
      end if
  end sub
  
  function onKeyEvent(key as string, press as boolean) as boolean
      if not press then
          return false
      end if
      detailsGrp = m.top.findNode("detailsPane")
      gridGrp = m.top.findNode("scheduleGrid")
      if key = "back" and detailsGrp.isInFocusChain()
          focusProgramDetails(false)
          detailsGrp.setFocus(false)
          gridGrp.setFocus(true)
          return true
      else if key = "back"
          m.LoadChannelsTask.control = "stop"
          m.global.sceneManager.callFunc("popScene")
          return true
      end if
      return false
  end function