content: {-# LANGUAGE ViewPatterns, TypeSynonymInstances, FlexibleInstances #-}
  
  module IHaskell.Display.Magic () where
  
  import qualified Data.ByteString as B
  import qualified Data.ByteString.Base64 as Base64
  import qualified Data.ByteString.Char8 as Char
  import           Data.ByteString.UTF8
  import qualified Data.ByteString.UTF8 as B
  import qualified Data.ByteString.Unsafe as B
  import           Data.Char
  import qualified Data.Text as T
  import qualified Data.Text.Encoding as T
  import           Text.Read
  
  import           Magic
  
  import           IHaskell.CSS (ihaskellCSS)
  import           IHaskell.Display
  import           IHaskell.IPython.Types (MimeType(MimeSvg))
  
  
  instance IHaskellDisplay T.Text where
    display = display . T.encodeUtf8
  
  instance IHaskellDisplay B.ByteString where
    display x = do
      m <- magicOpen []
      magicLoadDefault m
      f <- B.unsafeUseAsCStringLen x (magicCString m)
      return $ Display [withClass (parseMagic f) x]
  
  b64 :: B.ByteString -> String
  b64 = Char.unpack . Base64.encode
  
  withClass :: MagicClass -> B.ByteString -> DisplayData
  withClass SVG = DisplayData MimeSvg . T.decodeUtf8
  withClass (PNG w h) = png w h . T.decodeUtf8 . Base64.encode
  withClass JPG = jpg 400 300 . T.decodeUtf8 . Base64.encode
  withClass HTML = html' (Just ihaskellCSS) . B.toString
  withClass LaTeX = latex . B.toString
  withClass _ = plain . B.toString
  
  {- | parse the string produced by magic.
  
  >>> parseMagic "LaTeX 2e document, ASCII text, with very long lines"
  LaTeX
  
  >>> parseMagic "PNG image data, 480 x 480, 8-bit/color RGB, non-interlaced"
  PNG 480 480
  
  >>> parseMagic "HTML document, ASCII text, with very long lines"
  HTML
  
  >>> parseMagic "JPEG image data, JFIF standard 1.01"
  JPG
  
  -}
  parseMagic :: String -> MagicClass
  parseMagic f =
    case words f of
      "SVG":_                                                                                 -> SVG
      "PNG":_image:_data:(readMaybe -> Just w):_x:(readMaybe . takeWhile isDigit -> Just h):_ -> PNG w
                                                                                                   h
      "LaTeX":_                                                                               -> LaTeX
      "HTML":_                                                                                -> HTML
      "JPEG":_                                                                                -> JPG
      _                                                                                       -> Unknown
  
  data MagicClass = SVG
                  | PNG Int Int
                  | JPG
                  | HTML
                  | LaTeX
                  | Unknown
    deriving Show
  