--------------------------------------------------------------------------------
{-# LANGUAGE OverloadedStrings #-}
module Patat.Images
    ( Backend
    , Handle
    , new
    , drawImage
    ) where


--------------------------------------------------------------------------------
import           Control.Exception           (catch)
import qualified Data.Aeson                  as A
import qualified Data.Text                   as T
import           Patat.Cleanup
import           Patat.Images.Internal
import qualified Patat.Images.ITerm2         as ITerm2
import qualified Patat.Images.Kitty          as Kitty
import qualified Patat.Images.W3m            as W3m
import           Patat.Presentation.Internal


--------------------------------------------------------------------------------
new :: ImageSettings -> IO Handle
new :: ImageSettings -> IO Handle
new ImageSettings
is
    | ImageSettings -> Text
isBackend ImageSettings
is Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"auto" = IO Handle
auto
    | Just (Backend Config a -> IO Handle
b) <- Text -> [(Text, Backend)] -> Maybe Backend
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup (ImageSettings -> Text
isBackend ImageSettings
is) [(Text, Backend)]
backends =
        case Value -> Result a
forall a. FromJSON a => Value -> Result a
A.fromJSON (Object -> Value
A.Object (Object -> Value) -> Object -> Value
forall a b. (a -> b) -> a -> b
$ ImageSettings -> Object
isParams ImageSettings
is) of
            A.Success a
c -> Config a -> IO Handle
b (a -> Config a
forall a. a -> Config a
Explicit a
c)
            A.Error String
err -> String -> IO Handle
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> IO Handle) -> String -> IO Handle
forall a b. (a -> b) -> a -> b
$
                String
"Patat.Images.new: Error parsing config for " String -> String -> String
forall a. [a] -> [a] -> [a]
++
                Text -> String
forall a. Show a => a -> String
show (ImageSettings -> Text
isBackend ImageSettings
is) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" image backend: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
err
new ImageSettings
is = String -> IO Handle
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> IO Handle) -> String -> IO Handle
forall a b. (a -> b) -> a -> b
$
    String
"Patat.Images.new: Could not find " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Text -> String
forall a. Show a => a -> String
show (ImageSettings -> Text
isBackend ImageSettings
is) String -> String -> String
forall a. [a] -> [a] -> [a]
++
    String
" image backend."


--------------------------------------------------------------------------------
auto :: IO Handle
auto :: IO Handle
auto = [Text] -> [(Text, Backend)] -> IO Handle
go [] [(Text, Backend)]
backends
  where
    go :: [Text] -> [(Text, Backend)] -> IO Handle
go [Text]
names ((Text
name, Backend Config a -> IO Handle
b) : [(Text, Backend)]
bs) = IO Handle -> (BackendNotSupported -> IO Handle) -> IO Handle
forall e a. Exception e => IO a -> (e -> IO a) -> IO a
catch
        (Config a -> IO Handle
b Config a
forall a. Config a
Auto)
        (\(BackendNotSupported String
_) -> [Text] -> [(Text, Backend)] -> IO Handle
go (Text
name Text -> [Text] -> [Text]
forall a. a -> [a] -> [a]
: [Text]
names) [(Text, Backend)]
bs)
    go [Text]
names [] = String -> IO Handle
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> IO Handle) -> String -> IO Handle
forall a b. (a -> b) -> a -> b
$
        String
"Could not find a supported backend, tried: " String -> String -> String
forall a. [a] -> [a] -> [a]
++
        Text -> String
T.unpack (Text -> [Text] -> Text
T.intercalate Text
", " ([Text] -> [Text]
forall a. [a] -> [a]
reverse [Text]
names))


--------------------------------------------------------------------------------
-- | All supported backends.  We can use CPP to include or exclude some
-- depending on platform availability.
backends :: [(T.Text, Backend)]
backends :: [(Text, Backend)]
backends =
    [ (Text
"iterm2", Backend
ITerm2.backend)
    , (Text
"kitty",  Backend
Kitty.backend)
    , (Text
"w3m",    Backend
W3m.backend)
    ]


--------------------------------------------------------------------------------
drawImage :: Handle -> FilePath -> IO Cleanup
drawImage :: Handle -> String -> IO Cleanup
drawImage = Handle -> String -> IO Cleanup
hDrawImage