{-# Language TemplateHaskell, OverloadedStrings #-}

{-|
Module      : Client.State.Help
Description : Type and utility functions for the help buffer
Copyright   : (c) TheDaemoness, 2024
License     : ISC
Maintainer  : emertens@gmail.com

The help buffer is basically a glorified list of @Image'@s with some additional bookkeeping data.
-}

module Client.State.Help
  (HelpState
  , HelpQuery(..)
  , hsQuery
  , hsImages
  , helpQueryToText
  , makeHelp
  , awaitHelp
  , awaitingHelp
  , applyHelpReply
  ) where

import Client.Image.PackedImage (Image')
import Control.Lens
import Data.Text (Text, append)
import Irc.Codes
import Irc.Message (IrcMsg (Reply))
import Client.Image.MircFormatting (parseIrcText)
import Client.Image.Palette (Palette)

data HelpQuery = HelpList | HelpCmd Text | HelpNet Text Text | HelpNetPartial Text Text (Maybe Text)

helpQueryToText :: HelpQuery -> Maybe Text
helpQueryToText :: HelpQuery -> Maybe Text
helpQueryToText (HelpQuery
HelpList)                   = Maybe Text
forall a. Maybe a
Nothing
helpQueryToText (HelpCmd Text
txt)                = Text -> Maybe Text
forall a. a -> Maybe a
Just Text
txt
helpQueryToText (HelpNet Text
net Text
topic)          = Text -> Maybe Text
forall a. a -> Maybe a
Just (Text
net Text -> Text -> Text
`append` Text
":" Text -> Text -> Text
`append` Text
topic)
helpQueryToText (HelpNetPartial Text
net Text
topic Maybe Text
_) = Text -> Maybe Text
forall a. a -> Maybe a
Just (Text
net Text -> Text -> Text
`append` Text
":" Text -> Text -> Text
`append` Text
topic)

-- | Cached help query and rendered help text.
data HelpState = HelpState
  { HelpState -> HelpQuery
_hsQuery  :: HelpQuery
  , HelpState -> [Image']
_hsImages :: [Image']
  }

makeLenses ''HelpState

makeHelp :: Maybe Text -> [Image'] -> HelpState
makeHelp :: Maybe Text -> [Image'] -> HelpState
makeHelp (Just Text
cmd) [Image']
images = HelpState { _hsQuery :: HelpQuery
_hsQuery = Text -> HelpQuery
HelpCmd Text
cmd, _hsImages :: [Image']
_hsImages = [Image']
images }
makeHelp Maybe Text
Nothing    [Image']
images = HelpState { _hsQuery :: HelpQuery
_hsQuery = HelpQuery
HelpList,    _hsImages :: [Image']
_hsImages = [Image']
images }

awaitHelp :: Text -> Text -> HelpState
awaitHelp :: Text -> Text -> HelpState
awaitHelp Text
net Text
query = HelpState { _hsQuery :: HelpQuery
_hsQuery = Text -> Text -> Maybe Text -> HelpQuery
HelpNetPartial Text
net Text
query Maybe Text
forall a. Maybe a
Nothing, _hsImages :: [Image']
_hsImages = [] }

awaitingHelp :: HelpState -> Maybe Text
awaitingHelp :: HelpState -> Maybe Text
awaitingHelp HelpState
hs = case HelpState -> HelpQuery
_hsQuery HelpState
hs of
  HelpNetPartial Text
net Text
_ Maybe Text
_ -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
net
  HelpQuery
_                      -> Maybe Text
forall a. Maybe a
Nothing

applyHelpReply :: Palette -> IrcMsg -> HelpState -> HelpState
applyHelpReply :: Palette -> IrcMsg -> HelpState -> HelpState
applyHelpReply Palette
pal IrcMsg
irc HelpState
hs = case (IrcMsg
irc, HelpState -> HelpQuery
_hsQuery HelpState
hs) of
  (Reply Text
_ ReplyCode
RPL_HELPSTART (Text
_:Text
rtopic':Text
text:[Text]
_), HelpNetPartial Text
net Text
topic Maybe Text
Nothing) ->
    HelpState
       { _hsQuery :: HelpQuery
_hsQuery = Text -> Text -> Maybe Text -> HelpQuery
HelpNetPartial Text
net Text
topic (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
rtopic')
       , _hsImages :: [Image']
_hsImages = [Palette -> Text -> Image'
parseIrcText Palette
pal Text
text]
       }
  (Reply Text
_ ReplyCode
RPL_HELPTXT (Text
_:Text
rtopic':Text
text:[Text]
_), HelpNetPartial Text
_ Text
_ (Just Text
rtopic)) | Text
rtopic' Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
rtopic ->
    HelpState
hs { _hsImages = parseIrcText pal text:_hsImages hs }
  (Reply Text
_ ReplyCode
RPL_ENDOFHELP (Text
_:Text
rtopic':Text
text:[Text]
_), HelpNetPartial Text
net Text
topic (Just Text
rtopic)) | Text
rtopic' Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
rtopic ->
    HelpState
      { _hsQuery :: HelpQuery
_hsQuery = Text -> Text -> HelpQuery
HelpNet Text
net Text
topic
      , _hsImages :: [Image']
_hsImages = Palette -> Text -> Image'
parseIrcText Palette
pal Text
textImage' -> [Image'] -> [Image']
forall a. a -> [a] -> [a]
:HelpState -> [Image']
_hsImages HelpState
hs
      }
  (IrcMsg, HelpQuery)
_ -> HelpState
hs