{-# LANGUAGE OverloadedStrings #-}

module Eventlog.Rendering.Types where

import Data.Char
import Data.String
import qualified Data.Text as T
import Text.Blaze.Html5

data IncludeTraceData
  = TraceData
  | NoTraceData

-- | Tab IDs must be usable as HTML and Javascript identifiers, so we allow a
-- limited selection of characters. This is enforced only at runtime by
-- 'mkTabID' and the 'IsString' instance, but that seems good enough for now.
newtype TabID = TabID T.Text

instance IsString TabID where
  fromString :: [Char] -> TabID
fromString = [Char] -> TabID
mkTabID

mkTabID :: String -> TabID
mkTabID :: [Char] -> TabID
mkTabID [Char]
s
    | (Char -> Bool) -> [Char] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Char -> Bool
valid [Char]
s = Text -> TabID
TabID ([Char] -> Text
T.pack [Char]
s)
    | Bool
otherwise   = [Char] -> TabID
forall a. HasCallStack => [Char] -> a
error ([Char] -> TabID) -> [Char] -> TabID
forall a b. (a -> b) -> a -> b
$ [Char]
"mkTabID: invalid tab ID: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
s
    where
      valid :: Char -> Bool
valid Char
c = Char -> Bool
isAscii Char
c Bool -> Bool -> Bool
&& (Char -> Bool
isAlpha Char
c Bool -> Bool -> Bool
|| Char -> Bool
isDigit Char
c Bool -> Bool -> Bool
|| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'_')

tabIDToVizID :: TabID -> T.Text
tabIDToVizID :: TabID -> Text
tabIDToVizID (TabID Text
t) = Text
"vis" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
t

tabIDToNavItemID :: TabID -> T.Text
tabIDToNavItemID :: TabID -> Text
tabIDToNavItemID (TabID Text
t) = Text
t Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"-tab"

tabIDToTabID :: TabID -> T.Text
tabIDToTabID :: TabID -> Text
tabIDToTabID (TabID Text
t) = Text
t

tabIDToHref :: TabID -> T.Text
tabIDToHref :: TabID -> Text
tabIDToHref (TabID Text
t) = Text
"#" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
t


data TabGroup = ManyTabs String [Tab]
              | SingleTab Tab

data Tab = Tab { Tab -> [Char]
tabName     :: String
               , Tab -> TabID
tabId       :: TabID
               , Tab -> Maybe Html
tabContent  :: Maybe Html
               , Tab -> Maybe Html
tabDocs     :: Maybe Html
               , Tab -> Bool
tabActive   :: Bool -- ^ Active by default?
               , Tab -> Bool
tabDisabled :: Bool
               }

mkTab :: String -> TabID -> Html -> Maybe Html -> Tab
mkTab :: [Char] -> TabID -> Html -> Maybe Html -> Tab
mkTab [Char]
name TabID
id_ Html
content Maybe Html
docs = [Char] -> TabID -> Maybe Html -> Maybe Html -> Bool -> Bool -> Tab
Tab [Char]
name TabID
id_ (Html -> Maybe Html
forall a. a -> Maybe a
Just Html
content) Maybe Html
docs Bool
False Bool
False

mkUnavailableTab :: String -> TabID -> Html -> Tab
mkUnavailableTab :: [Char] -> TabID -> Html -> Tab
mkUnavailableTab [Char]
name TabID
id_ Html
docs = [Char] -> TabID -> Maybe Html -> Maybe Html -> Bool -> Bool -> Tab
Tab [Char]
name TabID
id_ Maybe Html
forall a. Maybe a
Nothing (Html -> Maybe Html
forall a. a -> Maybe a
Just Html
docs) Bool
False Bool
True

mkOptionalTab :: String -> TabID -> (a -> Html) -> Maybe Html -> Html -> Maybe a -> Tab
mkOptionalTab :: forall a.
[Char]
-> TabID -> (a -> Html) -> Maybe Html -> Html -> Maybe a -> Tab
mkOptionalTab [Char]
name TabID
id_ a -> Html
mk_content Maybe Html
docs Html
no_docs Maybe a
mb = case Maybe a
mb of
    Maybe a
Nothing -> [Char] -> TabID -> Html -> Tab
mkUnavailableTab [Char]
name TabID
id_ Html
no_docs
    Just a
v  -> [Char] -> TabID -> Html -> Maybe Html -> Tab
mkTab [Char]
name TabID
id_ (a -> Html
mk_content a
v) Maybe Html
docs

noDocs :: Maybe Html
noDocs :: Maybe Html
noDocs = Maybe Html
forall a. Maybe a
Nothing