{- |
Copyright: (c) 2018-2019 Kowainik
SPDX-License-Identifier: MPL-2.0
Maintainer: Kowainik <xrom.xkov@gmail.com>

This module contains useful helpers to work with 'Widget's
-}

module Summoner.Tui.Widget
       ( label
       , borderLabel
       , borderName
       , hArrange
       , listInBorder
       ) where

import Brick.Types (Padding (Pad), Widget)
import Brick.Widgets.Border (borderWithLabel)
import Brick.Widgets.Center (center)
import Brick.Widgets.Core (hBox, hLimit, padLeftRight, padRight, str, txtWrap, vBox, vLimit,
                           withAttr, (<+>))


-- | Adds label to the Form's field.
label :: String -> Widget n -> Widget n
label :: String -> Widget n -> Widget n
label l :: String
l = Widget n -> Widget n -> Widget n
forall n. Widget n -> Widget n -> Widget n
(<+>) (String -> Widget n
forall n. String -> Widget n
str String
l)

{- | Like 'borderWithLabel' but receives 'String'. Also adds padding and fancy
unicode characters for border label.

__Example:__

@
┌─────╼ Some label ╾───┐
│                      │
│                      │
│                      │
│                      │
│                      │
└──────────────────────┘
@
-}
borderLabel :: String -> Widget n -> Widget n
borderLabel :: String -> Widget n -> Widget n
borderLabel l :: String
l = Widget n -> Widget n -> Widget n
forall n. Widget n -> Widget n -> Widget n
borderWithLabel (String -> Widget n
forall n. String -> Widget n
borderName String
l)

-- | Border label pretty text 'Widget'
borderName :: String -> Widget n
borderName :: String -> Widget n
borderName l :: String
l = String -> Widget n
forall n. String -> Widget n
str "╼" Widget n -> Widget n -> Widget n
forall n. Widget n -> Widget n -> Widget n
<+> Int -> Widget n -> Widget n
forall n. Int -> Widget n -> Widget n
padLeftRight 1 (String -> Widget n
forall n. String -> Widget n
str String
l) Widget n -> Widget n -> Widget n
forall n. Widget n -> Widget n -> Widget n
<+> String -> Widget n
forall n. String -> Widget n
str "╾"

{- | Arranges 'Widget's horizontally.

__Example:__

@
 [x] Cabal   [ ] Stack
@
-}
hArrange :: [Widget n] -> Widget n
hArrange :: [Widget n] -> Widget n
hArrange = [Widget n] -> Widget n
forall n. [Widget n] -> Widget n
hBox ([Widget n] -> Widget n)
-> ([Widget n] -> [Widget n]) -> [Widget n] -> Widget n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Widget n -> Widget n) -> [Widget n] -> [Widget n]
forall a. (a -> a) -> [a] -> [a]
updateHead (Padding -> Widget n -> Widget n
forall n. Padding -> Widget n -> Widget n
padRight (Int -> Padding
Pad 2))
  where
    updateHead :: (a -> a) -> [a] -> [a]
    updateHead :: (a -> a) -> [a] -> [a]
updateHead _ []       = []
    updateHead f :: a -> a
f (a :: a
a : as :: [a]
as) = a -> a
f a
a a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
as

{- | Shows list of elements inside 'borderWithLabel'.

__Example:__

@
┌────────────Some label──────────────────┐
│                                        │
│          > 8.2.2                       │
│          > 8.4.3                       │
│          > 8.4.4                       │
│                                        │
└────────────────────────────────────────┘
@
-}
listInBorder
    :: String  -- ^ Border label
    -> Int     -- ^ Horizontal limit
    -> Int     -- ^ Additional vertical limit
    -> [Text]  -- ^ List of text entries
    -> Widget n
listInBorder :: String -> Int -> Int -> [Text] -> Widget n
listInBorder name :: String
name limitH :: Int
limitH extraLimitV :: Int
extraLimitV list :: [Text]
list = Widget n -> Widget n
forall n. Widget n -> Widget n
center
    (Widget n -> Widget n) -> Widget n -> Widget n
forall a b. (a -> b) -> a -> b
$ Int -> Widget n -> Widget n
forall n. Int -> Widget n -> Widget n
hLimit Int
limitH
    (Widget n -> Widget n) -> Widget n -> Widget n
forall a b. (a -> b) -> a -> b
$ Int -> Widget n -> Widget n
forall n. Int -> Widget n -> Widget n
vLimit ([Text] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Text]
list Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 4 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
extraLimitV)
    (Widget n -> Widget n) -> Widget n -> Widget n
forall a b. (a -> b) -> a -> b
$ String -> Widget n -> Widget n
forall n. String -> Widget n -> Widget n
borderLabel String
name
    (Widget n -> Widget n) -> Widget n -> Widget n
forall a b. (a -> b) -> a -> b
$ Widget n -> Widget n
forall n. Widget n -> Widget n
center
    (Widget n -> Widget n) -> Widget n -> Widget n
forall a b. (a -> b) -> a -> b
$ [Widget n] -> Widget n
forall n. [Widget n] -> Widget n
vBox
    ([Widget n] -> Widget n) -> [Widget n] -> Widget n
forall a b. (a -> b) -> a -> b
$ (Text -> Widget n) -> [Text] -> [Widget n]
forall a b. (a -> b) -> [a] -> [b]
map (AttrName -> Widget n -> Widget n
forall n. AttrName -> Widget n -> Widget n
withAttr "blue-fg" (Widget n -> Widget n) -> (Text -> Widget n) -> Text -> Widget n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Widget n
forall n. Text -> Widget n
txtWrap (Text -> Widget n) -> (Text -> Text) -> Text -> Widget n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ("➤ " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>)) [Text]
list