components_tvshows_TVListDetails.bs

import "pkg:/source/utils/config.bs"
import "pkg:/source/utils/misc.bs"

sub init()
  m.title = m.top.findNode("title")
  m.title.text = tr("Loading...")
  m.overview = m.top.findNode("overview")
  m.poster = m.top.findNode("poster")
  m.infoBar = m.top.findnode("infoBar")
  m.videoCodec = m.top.findNode("video_codec")
end sub

sub itemContentChanged()
  item = m.top.itemContent
  itemData = item.json
  userSettings = m.global.session.user.settings

  ' Set default video source if user hasn't selected one yet
  if item.selectedVideoStreamId = "" and isValid(itemData.MediaSources)
    item.selectedVideoStreamId = itemData.MediaSources[0].id
  end if

  if isValid(itemData.parentIndexNumber) and itemData.parentIndexNumber = 0
    indexNumber = `${tr("Special")} - `
  else if isValid(itemData.indexNumber)
    indexNumber = `${itemData.indexNumber}. `
    if isValid(itemData.indexNumberEnd)
      indexNumber = `${itemData.indexNumber}-${itemData.indexNumberEnd}. `
    end if
  else
    indexNumber = ""
  end if
  m.title.text = indexNumber + item.title
  m.overview.text = item.overview

  if isValid(itemData.PremiereDate)
    airDate = CreateObject("roDateTime")
    airDate.FromISO8601String(itemData.PremiereDate)
    m.top.findNode("aired").text = airDate.AsDateString("short-month-no-weekday")
  end if

  imageUrl = item.posterURL

  if userSettings["ui.tvshows.blurunwatched"] = true
    if itemData.lookup("Type") = "Episode"
      if not itemData.userdata.played
        imageUrl = imageUrl + "&blur=15"
      end if
    end if
  end if

  m.poster.uri = imageUrl

  if type(itemData.RunTimeTicks) = "roInt" or type(itemData.RunTimeTicks) = "LongInteger"
    runTime = getRuntime()
    if runTime < 2
      m.top.findNode("runtime").text = "1 min"
    else
      m.top.findNode("runtime").text = stri(runTime).trim() + " mins"
    end if

    if userSettings["ui.design.hideclock"] <> true
      m.top.findNode("endtime").text = tr("Ends at %1").Replace("%1", getEndTime())
    end if
  end if

  if userSettings["ui.tvshows.disableCommunityRating"] = false
    if isValid(itemData.communityRating)
      if m.communityRating = invalid
        m.communityRating = CreateObject("roSGNode", "CommunityRating")
        m.communityRating.id = "communityRating"
      end if

      m.communityRating.rating = itemData.communityRating
      m.infoBar.insertChild(m.communityRating, 1)
    else
      if m.communityRating <> invalid
        m.infoBar.removeChild(m.communityRating)
      end if
    end if
  else
    if m.communityRating <> invalid
      m.infoBar.removeChild(m.communityRating)
    end if
  end if

  ' Mark as watched
  if isValid(itemData.UserData) and isValid(itemData.UserData.Played)
    m.poster.isWatched = itemData.UserData.Played
  end if

  ' Update progress bar
  if isValid(itemData.UserData) and isValidAndNotEmpty(itemData.UserData.PlayedPercentage)
    m.poster.playedPercentage = itemData.UserData.PlayedPercentage
  end if

  ' Display current video_codec and check if there is more than one video to choose from...
  m.videoCodec.visible = false
  if isValid(itemData.MediaSources)
    for i = 0 to itemData.MediaSources.Count() - 1
      if item.selectedVideoStreamId = itemData.MediaSources[i].id and isValid(itemData.MediaSources[i].MediaStreams[0])
        m.videoCodec.text = tr("Video") + ": "
        if isValid(itemData.MediaSources[i].MediaStreams[0].DisplayTitle)
          m.videoCodec.text = m.videoCodec.text + itemData.MediaSources[i].MediaStreams[0].DisplayTitle
        else
          m.videoCodec.text = m.videoCodec.text + tr("N/A")
        end if
        SetupAudioDisplay(itemData.MediaSources[i].MediaStreams, item.selectedAudioStreamIndex)
        exit for
      end if
    end for
    m.videoCodec.visible = true
    DisplayVideoAvailable(itemData.MediaSources)
  end if
end sub

' Display current audio_codec and check if there is more than one audio track to choose from...
sub SetupAudioDisplay(mediaStreams as object, selectedAudioStreamIndex as integer)
  audioIdx = invalid
  if isValid(mediaStreams)
    for i = 0 to mediaStreams.Count() - 1
      if LCase(mediaStreams[i].Type) = "audio" and audioIdx = invalid
        if selectedAudioStreamIndex > 0 and selectedAudioStreamIndex < mediaStreams.Count()
          audioIdx = selectedAudioStreamIndex
        else
          audioIdx = i
        end if
        m.top.findNode("audio_codec").text = tr("Audio") + ": " + mediaStreams[audioIdx].DisplayTitle
      end if
      if isValid(audioIdx) then exit for
    end for
  end if

  if isValid(audioIdx)
    m.top.findNode("audio_codec").visible = true
    DisplayAudioAvailable(mediaStreams)
  else
    m.top.findNode("audio_codec").visible = false
  end if
end sub

' Adds "+N" (e.g. +1) if there is more than one video version to choose from
sub DisplayVideoAvailable(streams as object)
  count = 0
  for i = 0 to streams.Count() - 1
    if LCase(streams[i].VideoType) = "videofile"
      count++
    end if
  end for

  if count > 1
    m.top.findnode("video_codec_count").text = "+" + stri(count - 1).trim()
  end if
end sub

' Adds "+N" (e.g. +1) if there is more than one audio track to choose from
sub DisplayAudioAvailable(streams as object)
  count = 0
  for i = 0 to streams.Count() - 1
    if streams[i].Type = "Audio"
      count++
    end if
  end for

  if count > 1
    m.top.findnode("audio_codec_count").text = "+" + stri(count - 1).trim()
  end if
end sub

function getRuntime() as integer
  itemData = m.top.itemContent.json

  ' A tick is .1ms, so 1/10,000,000 for ticks to seconds,
  ' then 1/60 for seconds to minutess... 1/600,000,000
  return int(itemData.RunTimeTicks / 600000000.0)
end function

function getEndTime() as string
  itemData = m.top.itemContent.json
  date = CreateObject("roDateTime")
  duration_s = int(itemData.RunTimeTicks / 10000000.0)
  date.fromSeconds(date.asSeconds() + duration_s)
  date.toLocalTime()

  return formatTime(date)
end function

sub focusChanged()
  if m.top.itemHasFocus = true
    ' text to speech for accessibility
    if m.global.device.isAudioGuideEnabled = true
      txt2Speech = CreateObject("roTextToSpeech")
      txt2Speech.Flush()
      txt2Speech.Say(m.title.text)
      txt2Speech.Say(m.overview.text)
    end if
  end if
end sub