source_utils_rowItemImage.bs

import "pkg:/source/api/Image.bs"
import "pkg:/source/utils/itemImageUrl.bs"
import "pkg:/source/utils/misc.bs"

' Returns the image URL for a row item based on its type, slot dimensions, and user settings.
'
' Does NOT handle blur — blur is appended by the caller (JRRowItem) after the URL is resolved.
'
' @param item - JellyfinBaseItem content node
' @param slotWidth - width of the image area in pixels (from rowSlotSize constant)
' @param posterHeight - height of the image area in pixels; pass rowSlotSize[1] directly —
'                       text is laid out below the slot by the caller, so do NOT subtract
'                       the text area before passing this value (that would double-subtract it)
' @param userSettings - m.global.user.settings node (may be invalid)
' @param useEpisodeImages - pre-computed from m.global.user.config.useEpisodeImagesInNextUpAndResume;
'                           only relevant when uiGeneralEpisodeImages = "webclient"
' @param applyEpisodeImageSetting - when false, skip the uiGeneralEpisodeImages user setting entirely
'                                   and always show the episode's own Primary image. Use false for
'                                   extras rows (season episode lists, person TV shows) where the
'                                   setting is only meaningful for home rows (Continue Watching, Next Up).
' @returns Image URL string, or "" if no image is available
function getRowItemImageUrl(item as object, slotWidth as integer, posterHeight as integer, userSettings as object, useEpisodeImages = false as boolean, applyEpisodeImageSetting = true as boolean) as string
  if not isValid(item) then return ""
  if not isValidAndNotEmpty(item.id) then return ""

  size = { width: slotWidth, height: posterHeight }

  ' Library tiles: Primary image only (Thumb/Backdrop not available for these types)
  if item.type = "CollectionFolder" or item.type = "UserView" or item.type = "Channel"
    return getItemImageUrl(item, "Primary", size)
  end if

  ' Episodes and Recordings: image type controlled by user setting.
  ' applyEpisodeImageSetting = false bypasses the setting entirely (used by extras rows
  ' where the episode's own screenshot is always the right choice).
  if item.type = "Episode" or LCase(item.type) = "recording"
    if applyEpisodeImageSetting and isValid(userSettings)
      episodeImageSetting = userSettings.uiGeneralEpisodeImages
      ' Two logical paths: episode art (wide Thumb/Backdrop of the episode) or
      ' show art (wide Thumb/Backdrop of the series, bypassing episode-level images).
      if episodeImageSetting = "episode"
        return getItemThumbnailUrl(item, size)
      else if episodeImageSetting = "show"
        return getItemParentWidePosterUrl(item, size)
      else if episodeImageSetting = "webclient"
        ' Respect the Jellyfin web client's "use episode images" config flag.
        ' Collapses to the same two paths as "episode" and "show".
        return useEpisodeImages ? getItemThumbnailUrl(item, size) : getItemParentWidePosterUrl(item, size)
      end if
    end if
    ' Default (and extras rows): episode's own Primary image (screenshot), fall back to series wide art
    episodeUrl = getItemPosterUrl(item, size)
    if episodeUrl <> "" then return episodeUrl
    return getItemWidePosterUrl(item, size)
  end if

  ' Program: portrait poster with inline channel art fallback
  ' (channelId and channelPrimaryImageTag are fields on the Program item itself)
  if item.type = "Program"
    url = getItemPosterUrl(item, size)
    if url = "" and isValidAndNotEmpty(item.channelId) and isValidAndNotEmpty(item.channelPrimaryImageTag)
      url = ImageURL(item.channelId, "Primary", { tag: item.channelPrimaryImageTag, maxWidth: slotWidth, maxHeight: posterHeight })
    end if
    return url
  end if

  ' TvChannel: Primary image (channel logo stored as Primary, not Thumb/Backdrop)
  ' PhotoAlbum: wide thumb
  if item.type = "TvChannel"
    return getItemPosterUrl(item, size)
  end if
  if item.type = "PhotoAlbum"
    return getItemWidePosterUrl(item, size)
  end if

  ' Photos are stored as Primary images in Jellyfin (no Thumb/Backdrop).
  ' Use Primary image; slot shape already set to WIDE by createLatestInRows for photo libraries.
  if item.type = "Photo"
    return getItemPosterUrl(item, size)
  end if

  ' Square-native types: Primary image (square crop via scaleToZoom on the poster)
  if item.type = "MusicAlbum" or item.type = "MusicArtist" or item.type = "Audio"
    return getItemPosterUrl(item, size)
  end if

  ' All remaining types (Movie, Series, Season, BoxSet, Person, Video, MusicVideo, etc.):
  ' Use slot shape to determine image strategy.
  ' Wide slot (slotWidth > posterHeight): try wide image first, fall back to portrait.
  ' Portrait/square slot: use portrait poster.
  if slotWidth > posterHeight
    url = getItemWidePosterUrl(item, size)
    if url = "" then url = getItemPosterUrl(item, size)
    return url
  end if

  return getItemPosterUrl(item, size)
end function