module Mpv.Track where

import Control.Lens (_1, _2, _3, view)
import Data.List.Extra (firstJust)

import Mpv.Data.AudioId (AudioId (AudioId))
import Mpv.Data.AudioTrack (AudioTrack (AudioTrack))
import Mpv.Data.AudioTracks (AudioTracks (AudioTracks))
import qualified Mpv.Data.Property as Property
import Mpv.Data.Subtitle (Subtitle (Subtitle))
import Mpv.Data.SubtitleId (SubtitleId (SubtitleId))
import Mpv.Data.Subtitles (Subtitles (Subtitles))
import qualified Mpv.Data.Track as Track
import Mpv.Data.Track (Track (Track), TrackList (TrackList))
import Mpv.Data.VideoId (VideoId (VideoId))
import Mpv.Data.VideoTrack (VideoTrack (VideoTrack))
import Mpv.Data.VideoTracks (VideoTracks (VideoTracks))
import qualified Mpv.Effect.Mpv as Mpv
import Mpv.Effect.Mpv (Mpv)

toVideo :: Track -> Maybe VideoTrack
toVideo :: Track -> Maybe VideoTrack
toVideo = \case
  Track Maybe Int
id' Bool
sel Maybe Text
_ TrackType
Track.Video -> VideoTrack -> Maybe VideoTrack
forall a. a -> Maybe a
Just (Maybe VideoId -> Bool -> VideoTrack
VideoTrack (Int -> VideoId
VideoId (Int -> VideoId) -> Maybe Int -> Maybe VideoId
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Int
id') Bool
sel)
  Track
_ -> Maybe VideoTrack
forall a. Maybe a
Nothing

toAudio :: Track -> Maybe AudioTrack
toAudio :: Track -> Maybe AudioTrack
toAudio = \case
  Track Maybe Int
id' Bool
sel Maybe Text
lang TrackType
Track.Audio -> AudioTrack -> Maybe AudioTrack
forall a. a -> Maybe a
Just (Maybe AudioId -> Bool -> Maybe Text -> AudioTrack
AudioTrack (Int -> AudioId
AudioId (Int -> AudioId) -> Maybe Int -> Maybe AudioId
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Int
id') Bool
sel Maybe Text
lang)
  Track
_ -> Maybe AudioTrack
forall a. Maybe a
Nothing

toSubtitle :: Track -> Maybe Subtitle
toSubtitle :: Track -> Maybe Subtitle
toSubtitle = \case
  Track Maybe Int
id' Bool
sel Maybe Text
lang TrackType
Track.Sub -> Subtitle -> Maybe Subtitle
forall a. a -> Maybe a
Just (Maybe SubtitleId -> Bool -> Maybe Text -> Subtitle
Subtitle (Int -> SubtitleId
SubtitleId (Int -> SubtitleId) -> Maybe Int -> Maybe SubtitleId
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Int
id') Bool
sel Maybe Text
lang)
  Track
_ -> Maybe Subtitle
forall a. Maybe a
Nothing

trackIdIfSelected :: Track -> Maybe Int
trackIdIfSelected :: Track -> Maybe Int
trackIdIfSelected = \case
  Track Maybe Int
id' Bool
True Maybe Text
_ TrackType
_ -> Maybe Int
id'
  Track
_ -> Maybe Int
forall a. Maybe a
Nothing

trackType ::
  Integral i =>
  (Track -> Maybe a) ->
  (Maybe i -> [a] -> b) ->
  [Track] ->
  b
trackType :: forall i a b.
Integral i =>
(Track -> Maybe a) -> (Maybe i -> [a] -> b) -> [Track] -> b
trackType Track -> Maybe a
tpe Maybe i -> [a] -> b
grp [Track]
ts =
  Maybe i -> [a] -> b
grp (Int -> i
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> i) -> Maybe Int -> Maybe i
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Track -> Maybe Int) -> [Track] -> Maybe Int
forall a b. (a -> Maybe b) -> [a] -> Maybe b
firstJust Track -> Maybe Int
trackIdIfSelected [Track]
matchingTracks) [a]
finalTracks
  where
    ([Track]
matchingTracks, [a]
finalTracks) =
      [(Track, a)] -> ([Track], [a])
forall a b. [(a, b)] -> ([a], [b])
unzip ((Track -> Maybe (Track, a)) -> [Track] -> [(Track, a)]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe Track -> Maybe (Track, a)
withTrack [Track]
ts)
    withTrack :: Track -> Maybe (Track, a)
withTrack Track
a =
      (Track
a,) (a -> (Track, a)) -> Maybe a -> Maybe (Track, a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Track -> Maybe a
tpe Track
a

splitTracks ::
  [Track] ->
  (VideoTracks, AudioTracks, Subtitles)
splitTracks :: [Track] -> (VideoTracks, AudioTracks, Subtitles)
splitTracks [Track]
ts =
  ((Track -> Maybe VideoTrack)
-> (Maybe VideoId -> [VideoTrack] -> VideoTracks)
-> [Track]
-> VideoTracks
forall i a b.
Integral i =>
(Track -> Maybe a) -> (Maybe i -> [a] -> b) -> [Track] -> b
trackType Track -> Maybe VideoTrack
toVideo Maybe VideoId -> [VideoTrack] -> VideoTracks
VideoTracks [Track]
ts, (Track -> Maybe AudioTrack)
-> (Maybe AudioId -> [AudioTrack] -> AudioTracks)
-> [Track]
-> AudioTracks
forall i a b.
Integral i =>
(Track -> Maybe a) -> (Maybe i -> [a] -> b) -> [Track] -> b
trackType Track -> Maybe AudioTrack
toAudio Maybe AudioId -> [AudioTrack] -> AudioTracks
AudioTracks [Track]
ts, (Track -> Maybe Subtitle)
-> (Maybe SubtitleId -> [Subtitle] -> Subtitles)
-> [Track]
-> Subtitles
forall i a b.
Integral i =>
(Track -> Maybe a) -> (Maybe i -> [a] -> b) -> [Track] -> b
trackType Track -> Maybe Subtitle
toSubtitle Maybe SubtitleId -> [Subtitle] -> Subtitles
Subtitles [Track]
ts)

tracks ::
  Member Mpv r =>
  Sem r (VideoTracks, AudioTracks, Subtitles)
tracks :: forall (r :: [(* -> *) -> * -> *]).
Member Mpv r =>
Sem r (VideoTracks, AudioTracks, Subtitles)
tracks = do
  TrackList NonEmpty Track
allTracks <- Property TrackList -> Sem r TrackList
forall (r :: [(* -> *) -> * -> *]) v.
MemberWithError Mpv r =>
Property v -> Sem r v
Mpv.prop Property TrackList
Property.TrackList
  (VideoTracks, AudioTracks, Subtitles)
-> Sem r (VideoTracks, AudioTracks, Subtitles)
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([Track] -> (VideoTracks, AudioTracks, Subtitles)
splitTracks (NonEmpty Track -> [Track]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList NonEmpty Track
allTracks))

videoTracks ::
  Member Mpv r =>
  Sem r VideoTracks
videoTracks :: forall (r :: [(* -> *) -> * -> *]).
Member Mpv r =>
Sem r VideoTracks
videoTracks =
  Getting
  VideoTracks (VideoTracks, AudioTracks, Subtitles) VideoTracks
-> (VideoTracks, AudioTracks, Subtitles) -> VideoTracks
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting
  VideoTracks (VideoTracks, AudioTracks, Subtitles) VideoTracks
forall s t a b. Field1 s t a b => Lens s t a b
_1 ((VideoTracks, AudioTracks, Subtitles) -> VideoTracks)
-> Sem r (VideoTracks, AudioTracks, Subtitles) -> Sem r VideoTracks
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Sem r (VideoTracks, AudioTracks, Subtitles)
forall (r :: [(* -> *) -> * -> *]).
Member Mpv r =>
Sem r (VideoTracks, AudioTracks, Subtitles)
tracks

audioTracks ::
  Member Mpv r =>
  Sem r AudioTracks
audioTracks :: forall (r :: [(* -> *) -> * -> *]).
Member Mpv r =>
Sem r AudioTracks
audioTracks =
  Getting
  AudioTracks (VideoTracks, AudioTracks, Subtitles) AudioTracks
-> (VideoTracks, AudioTracks, Subtitles) -> AudioTracks
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting
  AudioTracks (VideoTracks, AudioTracks, Subtitles) AudioTracks
forall s t a b. Field2 s t a b => Lens s t a b
_2 ((VideoTracks, AudioTracks, Subtitles) -> AudioTracks)
-> Sem r (VideoTracks, AudioTracks, Subtitles) -> Sem r AudioTracks
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Sem r (VideoTracks, AudioTracks, Subtitles)
forall (r :: [(* -> *) -> * -> *]).
Member Mpv r =>
Sem r (VideoTracks, AudioTracks, Subtitles)
tracks

subtitles ::
  Member Mpv r =>
  Sem r Subtitles
subtitles :: forall (r :: [(* -> *) -> * -> *]). Member Mpv r => Sem r Subtitles
subtitles =
  Getting Subtitles (VideoTracks, AudioTracks, Subtitles) Subtitles
-> (VideoTracks, AudioTracks, Subtitles) -> Subtitles
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Subtitles (VideoTracks, AudioTracks, Subtitles) Subtitles
forall s t a b. Field3 s t a b => Lens s t a b
_3 ((VideoTracks, AudioTracks, Subtitles) -> Subtitles)
-> Sem r (VideoTracks, AudioTracks, Subtitles) -> Sem r Subtitles
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Sem r (VideoTracks, AudioTracks, Subtitles)
forall (r :: [(* -> *) -> * -> *]).
Member Mpv r =>
Sem r (VideoTracks, AudioTracks, Subtitles)
tracks