play (Just pos) app@(PlayerApp l _ chan _) = do
    (proc, duration, tId) <- liftIO $ playSong song
    return (updateAppStatus app Play pos) {
        playback = Just (Playback pos proc duration duration tId)
      }
  where
    songs = L.listElements l
    song = songs Vec.! pos
    failSongInfo :: SomeException -> IO SongInfo
    failSongInfo _ = return $ SongInfo (-1)
    playSong :: Song -> IO (ProcessHandle, Double, ThreadId)
    playSong (Song _ path _) = do
      musicDir <- defaultMusicDirectory
      (SongInfo duration) <- catch
        (fetchSongInfo $ musicDir </> path)
        failSongInfo
      proc <- AP.play $ musicDir </> path
      tId <- playheadAdvanceLoop chan
      return (proc, duration, tId)


-- Stops current song and play selected song.
play (Just pos) app@(PlayerApp l _ chan _) = do
    (proc, duration, tId) <- liftIO $ playSong song
    return (updateAppStatus app Play pos) {
        playback = Just (Playback pos proc duration duration tId)
      }
  where
    songs = L.listElements l
    song = songs Vec.! pos
    failSongInfo :: SomeException -> IO SongInfo
    failSongInfo _ = return $ SongInfo (-1)
    playSong :: Song -> IO (ProcessHandle, Double, ThreadId)
    playSong (Song _ path _) = do
      musicDir <- defaultMusicDirectory
      (SongInfo duration) <- catch
        (fetchSongInfo $ musicDir </> path)
        failSongInfo
      proc <- AP.play $ musicDir </> path
      tId <- playheadAdvanceLoop chan
      return (proc, duration, tId)


-- Stops current song and play selected song.
play (Just pos) app@(PlayerApp l _ chan _) = do
    (proc, duration, tId) <- liftIO $ playSong song
    return (updateAppStatus app Play pos) {
        playback = Just (Playback pos proc duration duration tId)
      }
  where
    songs = L.listElements l
    song = songs Vec.! pos
    failSongInfo :: SomeException -> IO SongInfo
    failSongInfo _ = return $ SongInfo (-1)
    playSong :: Song -> IO (ProcessHandle, Double, ThreadId)
    playSong (Song _ path _) = do
      musicDir <- defaultMusicDirectory
      (SongInfo duration) <- catch
        (fetchSongInfo $ musicDir </> path)
        failSongInfo
      proc <- AP.play $ musicDir </> path
      tId <- playheadAdvanceLoop chan
      return (proc, duration, tId)


-- Stops current song and play selected song.