content: ' ********** Copyright 2016-2019 Roku Corp.  All Rights Reserved. **********
  
  Function init()
      initProgressBar()
      initThumbnails()  ' hostPefix and trickInterval are passed in from interface fields'
  
      'set video node'
      m.ExtVideo = invalid
      initLoadingBar()
  
  end Function
  
  ' *** Progress Bar Section *** '
  Function initProgressBar()
    'progress bar nodes'
    m.progress = m.top.findNode("progress")
    m.progress.visible = false
  
    m.progressWidth = m.top.findNode("outlineRect").width
    m.progressRect = m.top.findNode("progressRect")
    m.leftProgressLabel = m.top.findNode("leftProgressLabel")
    m.rightProgressLabel = m.top.findNode("rightProgressLabel")
    m.progressMode = m.top.findNode("progressMode")
  end Function
  
  Function formatNumberString(number as Integer) as String
    numberText = number.toStr()
    if number <= 0
      numberText = "00"   ' min number is 0'
    else if number < 10
      numberText = "0" + numberText
    else if number > 99
      numberText = "99"   ' max number - saturates at 99'
    end if
    return numberText
  end Function
  
  Function setTimeText(timeInSeconds) as String
    hoursText = formatNumberString( Fix(timeInSeconds / 3600) )
    minutesText = formatNumberString( Fix(timeInSeconds / 60) )
    secondsText = formatNumberString( Fix(timeInSeconds MOD 60) )
  
    timeText = minutesText + ":" + secondsText
    if hoursText <> "00"
      timeText = hoursText + ":" + timeText
    end if
  
    return timeText
  end Function
  
  Function showProgressBar(position)
      m.progress.visible = true
      m.progressRect.width = position * m.progressWidth / m.videoDuration
      leftPositionSeconds = position * 100 / 100
      rightPositionSeconds = m.videoDuration - leftPositionSeconds
      m.leftProgressLabel.text = setTimeText(leftPositionSeconds)
      m.rightProgressLabel.text = setTimeText(rightPositionSeconds)
      setProgressMode()
  end Function
  
  Function hideProgressBar()
      m.progress.visible = false
  end Function
  
  Function setProgressMode()
    if m.trickPlaySpeed = 0
      m.progressMode.uri = "pkg:/images/TrickPlay_ButtonMode_PAUSE_HD.png"
    else if m.trickplayDirection = "forward"
      if m.trickplaySpeed = 1
        m.progressMode.uri = "pkg:/images/TrickPlay_ButtonMode_FWDx1_HD.png"
      else if m.trickplaySpeed = 2
        m.progressMode.uri = "pkg:/images/TrickPlay_ButtonMode_FWDx2_HD.png"
      else
        m.progressMode.uri = "pkg:/images/TrickPlay_ButtonMode_FWDx3_HD.png"
      end if
    else if m.trickplayDirection = "reverse"
      if m.trickplaySpeed = 1
        m.progressMode.uri = "pkg:/images/TrickPlay_ButtonMode_REWx1_HD.png"
      else if m.trickplaySpeed = 2
        m.progressMode.uri = "pkg:/images/TrickPlay_ButtonMode_REWx2_HD.png"
      else
        m.progressMode.uri = "pkg:/images/TrickPlay_ButtonMode_REWx3_HD.png"
      end if
    end if
  end Function
  
  Function setProgressModePlay()
    m.progressMode.uri = "pkg:/images/TrickPlay_ButtonMode_PLAY_HD.png"
  end Function
  
  ' *** Thumbnails Section *** '
  Function initThumbnails()
    ' thumbnails nodes'
    m.thumbnails = m.top.findNode("thumbnails")
    m.thumbnails.visible = false
  
    'm.hostPrefix = hostPrefix
    'm.trickInterval = trickInterval
    m.trickPosition = 0
  
    m.trickPlayTimer = createObject("roSGNode", "Timer")
    m.trickPlayTimer.duration = 1
    m.trickPlayTimer.repeat = True
    m.trickPlayTimer.observeField("fire", "handleTrickPlayTimer")
  
    'array with thumbnails'
    poster0 = m.top.findNode("poster_thumb_minus2")
    poster1 = m.top.findNode("poster_thumb_minus1")
    poster2 = m.top.findNode("poster_thumb_center")
    poster3 = m.top.findNode("poster_thumb_plus1")
    poster4 = m.top.findNode("poster_thumb_plus2")
    m.arrayPosters = []
    m.arrayPosters.push(poster0)
    m.arrayPosters.push(poster1)
    m.arrayPosters.push(poster2)
    m.arrayPosters.push(poster3)
    m.arrayPosters.push(poster4)
    resetSeekLogic()
  end Function
  
  Function resetSeekLogic()
    m.trickplayDirection = "paused"
    m.trickPlaySpeed = 0
    m.trickPlayTimer.duration = 1
  end Function
  
  Function isSeeking() as boolean
    return m.trickplayDirection <> "paused"
  end Function
  
  Function startSeeking(key)  ' key is either "fastforward" or "rewind"
    if m.trickplayDirection = "paused"
        m.trickplaySpeed = 1
        m.trickPlayTimer.duration = 1 / m.trickPlaySpeed
        ' set the trickplay direction'
        if key = "fastforward"
          m.trickplayDirection = "forward"
        else
          m.trickplayDirection = "reverse"
        end if
  
        m.trickPlayTimer.control = "START"
    else if key = "fastforward" and m.trickplayDirection <> "forward" or key = "rewind" and m.trickplayDirection <> "reverse"
        pauseSeeking(key, m.trickPosition * m.trickInterval)
    else
        ' set the trick play speed'
        m.trickPlaySpeed += 1
        if m.trickPlaySpeed > 3 ' saturate trickplay speed at 3x'
            m.trickPlaySpeed = 1
        end if
        m.trickPlayTimer.control = "STOP"
        m.trickPlayTimer.duration = 1 / m.trickPlaySpeed
        m.trickPlayTimer.control = "START"
    end if
    print "trickPlaySpeed= "; m.trickPlaySpeed
  
  end Function
  
  Function pauseSeeking(key, position)  ' key is either "left" or "right"
    m.trickPlayTimer.control = "STOP"
    'm.trickPosition = Fix(position / 5) + 1
    m.trickPlaySpeed = 0
    if m.trickplayDirection = "paused"
      showThumbnails(position)
      if key = "right"
        m.trickplayDirection = "forward"
      else
        m.trickplayDirection = "reverse"
      end if
    else if key = "right" or key = "fastforward"    ' shift thumbnails to the left - forward
      if m.trickPosition < Fix((m.videoDuration / m.trickInterval) + 1)
          m.trickPosition += 1
          shiftThumbnailsLeft()
      end if
      m.trickplayDirection = "forward"
    else if key = "left" or key = "rewind"    ' shift thumbnails to the right - reverse
      if m.trickPosition > 0
          m.trickPosition -= 1
          shiftThumbnailsRight()
      end if
      m.trickplayDirection = "reverse"
    end if
    showProgressBar(position)
  end Function
  
  Function endSeeking()
    m.trickPlayTimer.control = "STOP"
    ' is there a better way to force seek position?'
    m.ExtVideo.control = "stop"
    m.ExtVideo.control = "play"
    'm.trickPosition -= 1
    'm.trickplayDirection = "paused"
    seekPosition = Cdbl(m.trickPosition * m.trickInterval)
  
    ? "seekPosition= "; seekPosition
    m.ExtVideo.seek = seekPosition
  
    resetSeekLogic()
    setProgressModePlay()
  end Function
  
  Function showThumbnails(position)
      m.thumbnails.visible = true
      m.trickPosition = Fix(position / 5) + 1
      ? "m.trickPosition= ", m.trickPosition
  
      ' calculate the start index, special handling if m.trickPosition < 3
      ' the arrayPosters have 5 slots, don't fill lower two slots at beginning of the stream
      startIndex = 0
      endIndex = 4
      if m.trickPosition < 3
        startIndexData = [3, 2, 1]
        startIndex = startIndexData[m.trickPosition]
      end if
  
      for i = startIndex to endIndex
        ' array index 2 is the current position (poster_thumb_center), other indexes are offset'
        position = (m.trickPosition + i - 2) * m.trickInterval
        m.arrayPosters[i].uri = m.hostPrefix + "thumb-" + (m.trickPosition + i - 2).toStr() + ".jpg"
        ? "show - poster i="; i; ", position="; position; ", uri="; m.arrayPosters[i].uri
      end for
  end Function
  
  Function hideThumbnails()
      m.thumbnails.visible = false
  end Function
  
  Function shiftThumbnailsLeft()    ' forward direction'
    m.arrayPosters[0].uri = m.arrayPosters[1].uri
    m.arrayPosters[1].uri = m.arrayPosters[2].uri
    m.arrayPosters[2].uri = m.arrayPosters[3].uri
    m.arrayPosters[3].uri = m.arrayPosters[4].uri
    if m.trickPosition < (m.videoDuration / m.trickInterval) - 2
        m.arrayPosters[4].uri = m.hostPrefix + "thumb-" + (m.trickPosition + 2).toStr() + ".jpg"
    else
        m.arrayPosters[4].uri = ""
    end if
    ''? "shift left - thumb 4 uri= "; m.arrayPosters[4].uri
  end Function
  
  Function shiftThumbnailsRight()   ' reverse direction'
    m.arrayPosters[4].uri = m.arrayPosters[3].uri
    m.arrayPosters[3].uri = m.arrayPosters[2].uri
    m.arrayPosters[2].uri = m.arrayPosters[1].uri
    m.arrayPosters[1].uri = m.arrayPosters[0].uri
    if m.trickPosition > 2
        m.arrayPosters[0].uri = m.hostPrefix + "thumb-" + (m.trickPosition - 2).toStr() + ".jpg"
    else
        m.arrayPosters[0].uri = ""
    end if
    ''? "shift right - thumb 0 uri= "; m.arrayPosters[0].uri
  end Function
  
  Function handleTrickPlayTimer()
      'print "TrickPlayTimer fired"
      if m.trickplayDirection = "forward"
          if m.trickPosition < Fix((m.videoDuration / m.trickInterval) + 1)
              m.trickPosition += 1
              shiftThumbnailsLeft()
          end if
      else if m.trickplayDirection = "reverse"
          if m.trickPosition > 0
              m.trickPosition -= 1
              shiftThumbnailsRight()
          end if
      end if
      showProgressBar(m.trickPosition * m.trickInterval)
  end Function
  
  ' *** Loading Bar Section *** '
  Function initLoadingBar()
    m.loadingPercentage = 0
    m.loading = m.top.findNode("loading")
    m.loading.visible = false
    m.loadingWidth = m.top.findNode("loadOutlineRect").width
    m.loadingProgressRect = m.top.findNode("loadProgressRect")
  end Function
  
  Function showLoadingBar()
    m.loading.visible = true
    m.loadingProgressRect.width = m.loadingPercentage * m.loadingWidth / 100
  end Function
  
  Function hideLoadingBar()
    m.loading.visible = false
    m.loadingPercentage = 0
  end Function
  
  Function handleBufferingStatus(msg)
    bufferingStatus = msg.getData()
    if bufferingStatus <> invalid
      m.loadingPercentage = bufferingStatus.percentage
      print "buffering - percentage= "; m.loadingPercentage
      showLoadingBar()
      if m.loadingPercentage = 100
        hideLoadingBar()
        hideProgressBar()
        hideThumbnails()
  
        ' this resets the video reference every time playerUI is invoked '
        m.ExtVideo.unobserveField("bufferingStatus")
        m.ExtVideo = invalid
      end if
    end if
  end Function
  
  ' *** Special ad handling section *** '
  Function handleAdPodUpdate(msg)
    m.adPods = msg.GetData()
    for each adbreak in m.adPods
      print adbreak
    end for
  end Function
  
  Function onKeyEvent(key as String, press as Boolean) as Boolean  'Maps back button to leave video
      if press
          if m.ExtVideo = Invalid
            REM - TODO: find a better way to get the video node
            m.ExtVideo = m.top.getParent()
            m.videoDuration = m.ExtVideo.duration
            m.ExtVideo.observeField("bufferingStatus", "handleBufferingStatus")
            m.hostPrefix = m.ExtVideo.thumbnailHostPrefix
            m.trickInterval = m.ExtVideo.thumbnailIntervalInSecs
          end if
  
          if key = "fastforward" or key = "rewind"
            if not isSeeking()
              position = m.ExtVideo.position
            else
              position = m.trickPosition * m.trickInterval
            end if
  
            showProgressBar(position)
            startSeeking(key)
            showThumbnails(position)
  
          else if key = "left" or key = "right"
            if not isSeeking()
              position = m.ExtVideo.position
            else
              position = m.trickPosition * m.trickInterval
            end if
            pauseSeeking(key, position)
          else if key = "play" or key = "OK"
              if m.ExtVideo.state = "playing"
                  REM - TODO: BIF player behavior: OK key only works during trick play
                  ? "Hit play key in state: "; m.ExtVideo.state
                  showProgressBar(m.ExtVideo.position)
                  m.ExtVideo.control = "pause"
              else
                  ? "Hit play key in state: "; m.ExtVideo.state
                  m.ExtVideo.control = "resume"
                  if isSeeking()
                      showLoadingBar()
                      endSeeking()
                  else
                      hideProgressBar()
                  end if
              end if
          end if
      end if
  
  	return false
  end Function
  