{-# LANGUAGE ExtendedDefaultRules #-}
{-# OPTIONS_GHC -Wno-type-defaults #-}

module Halogen.HTML.Layout.BorderLayout (BorderLayout) where

import Clay qualified as C
import Clay.Extra.Grid qualified as C
import Data.Default
import HPrelude
import Halogen.HTML qualified as HH
import Halogen.HTML.Layout
import Halogen.HTML.Properties qualified as HP

data BorderLayout w i = BorderLayout
  { forall w i. BorderLayout w i -> Last (HTML w i)
north :: Last (HH.HTML w i)
  , forall w i. BorderLayout w i -> Last (HTML w i)
south :: Last (HH.HTML w i)
  , forall w i. BorderLayout w i -> Last (HTML w i)
east :: Last (HH.HTML w i)
  , forall w i. BorderLayout w i -> Last (HTML w i)
west :: Last (HH.HTML w i)
  , forall w i. BorderLayout w i -> Last (HTML w i)
center :: Last (HH.HTML w i)
  }

borderLayoutStyle :: LayoutSettings BorderLayout -> C.Css
borderLayoutStyle :: LayoutSettings BorderLayout -> Css
borderLayoutStyle BorderLayoutSettings {forall a. Maybe (Size a)
gap :: forall a. Maybe (Size a)
width :: forall a. Maybe (Size a)
height :: forall a. Maybe (Size a)
gap :: LayoutSettings BorderLayout -> forall a. Maybe (Size a)
width :: LayoutSettings BorderLayout -> forall a. Maybe (Size a)
height :: LayoutSettings BorderLayout -> forall a. Maybe (Size a)
..} = do
  Display -> Css
C.display Display
C.inlineGrid
  (Size (ZonkAny 0) -> Css) -> Maybe (Size (ZonkAny 0)) -> Css
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ Size (ZonkAny 0) -> Css
forall a. Size a -> Css
C.gridGap Maybe (Size (ZonkAny 0))
forall a. Maybe (Size a)
gap
  (Size (ZonkAny 1) -> Css) -> Maybe (Size (ZonkAny 1)) -> Css
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ Size (ZonkAny 1) -> Css
forall a. Size a -> Css
C.width Maybe (Size (ZonkAny 1))
forall a. Maybe (Size a)
width
  (Size (ZonkAny 2) -> Css) -> Maybe (Size (ZonkAny 2)) -> Css
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ Size (ZonkAny 2) -> Css
forall a. Size a -> Css
C.height Maybe (Size (ZonkAny 2))
forall a. Maybe (Size a)
height

  [Text] -> Css
C.gridTemplateAreas
    ([Text] -> Css) -> [Text] -> Css
forall a b. (a -> b) -> a -> b
$ [ Text
"north north north"
      , Text
"west center east"
      , Text
"south south south"
      ]

  [Size LengthUnit] -> Css
forall a. [Size a] -> Css
C.gridTemplateColumns [Size LengthUnit
forall a. Auto a => a
C.auto, Number -> Size LengthUnit
C.fr Number
1, Size LengthUnit
forall a. Auto a => a
C.auto]
  [Size LengthUnit] -> Css
forall a. [Size a] -> Css
C.gridTemplateRows [Size LengthUnit
forall a. Auto a => a
C.auto, Number -> Size LengthUnit
C.fr Number
1, Size LengthUnit
forall a. Auto a => a
C.auto]

instance Default (LayoutSettings BorderLayout) where
  def :: LayoutSettings BorderLayout
def =
    BorderLayoutSettings
      { gap :: forall a. Maybe (Size a)
gap = Maybe (Size a)
forall a. Maybe a
forall a. Maybe (Size a)
Nothing
      , width :: forall a. Maybe (Size a)
width = Maybe (Size a)
forall a. Maybe a
forall a. Maybe (Size a)
Nothing
      , height :: forall a. Maybe (Size a)
height = Maybe (Size a)
forall a. Maybe a
forall a. Maybe (Size a)
Nothing
      }

instance Layout BorderLayout where
  data LayoutConstraints _ = North | South | East | West | Center

  data LayoutSettings _ = BorderLayoutSettings
    { LayoutSettings BorderLayout -> forall a. Maybe (Size a)
gap :: forall a. Maybe (C.Size a)
    , LayoutSettings BorderLayout -> forall a. Maybe (Size a)
width :: forall a. Maybe (C.Size a)
    , LayoutSettings BorderLayout -> forall a. Maybe (Size a)
height :: forall a. Maybe (C.Size a)
    }

  layout :: forall w i.
LayoutSettings BorderLayout -> BorderLayout w i -> HTML w i
layout LayoutSettings BorderLayout
settings BorderLayout {Last (HTML w i)
north :: forall w i. BorderLayout w i -> Last (HTML w i)
south :: forall w i. BorderLayout w i -> Last (HTML w i)
east :: forall w i. BorderLayout w i -> Last (HTML w i)
west :: forall w i. BorderLayout w i -> Last (HTML w i)
center :: forall w i. BorderLayout w i -> Last (HTML w i)
north :: Last (HTML w i)
south :: Last (HTML w i)
east :: Last (HTML w i)
west :: Last (HTML w i)
center :: Last (HTML w i)
..} =
    Node HTMLdiv w i
forall w i. Node HTMLdiv w i
HH.div [Css -> IProp HTMLdiv i
forall (r :: Row (*)) i. HasType "style" Text r => Css -> IProp r i
HP.style (Css -> IProp HTMLdiv i) -> Css -> IProp HTMLdiv i
forall a b. (a -> b) -> a -> b
$ LayoutSettings BorderLayout -> Css
borderLayoutStyle LayoutSettings BorderLayout
settings]
      ([HTML w i] -> HTML w i) -> [HTML w i] -> HTML w i
forall a b. (a -> b) -> a -> b
$ [Maybe (HTML w i)] -> [HTML w i]
forall a. [Maybe a] -> [a]
catMaybes
        [ Node HTMLdiv w i
forall w i. Node HTMLdiv w i
HH.div [Css -> IProp HTMLdiv i
forall (r :: Row (*)) i. HasType "style" Text r => Css -> IProp r i
HP.style (Css -> IProp HTMLdiv i) -> Css -> IProp HTMLdiv i
forall a b. (a -> b) -> a -> b
$ String -> Css
forall a. ToGridLines4 a => a -> Css
C.gridArea String
"north"] ([HTML w i] -> HTML w i)
-> (HTML w i -> [HTML w i]) -> HTML w i -> HTML w i
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HTML w i -> [HTML w i]
forall a. a -> [a]
forall (f :: * -> *) a. Applicative f => a -> f a
pure (HTML w i -> HTML w i) -> Maybe (HTML w i) -> Maybe (HTML w i)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Last (HTML w i) -> Maybe (HTML w i)
forall a. Last a -> Maybe a
getLast Last (HTML w i)
north
        , Node HTMLdiv w i
forall w i. Node HTMLdiv w i
HH.div [Css -> IProp HTMLdiv i
forall (r :: Row (*)) i. HasType "style" Text r => Css -> IProp r i
HP.style (Css -> IProp HTMLdiv i) -> Css -> IProp HTMLdiv i
forall a b. (a -> b) -> a -> b
$ String -> Css
forall a. ToGridLines4 a => a -> Css
C.gridArea String
"south"] ([HTML w i] -> HTML w i)
-> (HTML w i -> [HTML w i]) -> HTML w i -> HTML w i
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HTML w i -> [HTML w i]
forall a. a -> [a]
forall (f :: * -> *) a. Applicative f => a -> f a
pure (HTML w i -> HTML w i) -> Maybe (HTML w i) -> Maybe (HTML w i)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Last (HTML w i) -> Maybe (HTML w i)
forall a. Last a -> Maybe a
getLast Last (HTML w i)
south
        , Node HTMLdiv w i
forall w i. Node HTMLdiv w i
HH.div [Css -> IProp HTMLdiv i
forall (r :: Row (*)) i. HasType "style" Text r => Css -> IProp r i
HP.style (Css -> IProp HTMLdiv i) -> Css -> IProp HTMLdiv i
forall a b. (a -> b) -> a -> b
$ String -> Css
forall a. ToGridLines4 a => a -> Css
C.gridArea String
"east"] ([HTML w i] -> HTML w i)
-> (HTML w i -> [HTML w i]) -> HTML w i -> HTML w i
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HTML w i -> [HTML w i]
forall a. a -> [a]
forall (f :: * -> *) a. Applicative f => a -> f a
pure (HTML w i -> HTML w i) -> Maybe (HTML w i) -> Maybe (HTML w i)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Last (HTML w i) -> Maybe (HTML w i)
forall a. Last a -> Maybe a
getLast Last (HTML w i)
east
        , Node HTMLdiv w i
forall w i. Node HTMLdiv w i
HH.div [Css -> IProp HTMLdiv i
forall (r :: Row (*)) i. HasType "style" Text r => Css -> IProp r i
HP.style (Css -> IProp HTMLdiv i) -> Css -> IProp HTMLdiv i
forall a b. (a -> b) -> a -> b
$ String -> Css
forall a. ToGridLines4 a => a -> Css
C.gridArea String
"west"] ([HTML w i] -> HTML w i)
-> (HTML w i -> [HTML w i]) -> HTML w i -> HTML w i
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HTML w i -> [HTML w i]
forall a. a -> [a]
forall (f :: * -> *) a. Applicative f => a -> f a
pure (HTML w i -> HTML w i) -> Maybe (HTML w i) -> Maybe (HTML w i)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Last (HTML w i) -> Maybe (HTML w i)
forall a. Last a -> Maybe a
getLast Last (HTML w i)
west
        , Node HTMLdiv w i
forall w i. Node HTMLdiv w i
HH.div [Css -> IProp HTMLdiv i
forall (r :: Row (*)) i. HasType "style" Text r => Css -> IProp r i
HP.style (Css -> IProp HTMLdiv i) -> Css -> IProp HTMLdiv i
forall a b. (a -> b) -> a -> b
$ String -> Css
forall a. ToGridLines4 a => a -> Css
C.gridArea String
"center"] ([HTML w i] -> HTML w i)
-> (HTML w i -> [HTML w i]) -> HTML w i -> HTML w i
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HTML w i -> [HTML w i]
forall a. a -> [a]
forall (f :: * -> *) a. Applicative f => a -> f a
pure (HTML w i -> HTML w i) -> Maybe (HTML w i) -> Maybe (HTML w i)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Last (HTML w i) -> Maybe (HTML w i)
forall a. Last a -> Maybe a
getLast Last (HTML w i)
center
        ]

  layoutEnd :: forall w i. BorderLayout w i
layoutEnd = Last (HTML w i)
-> Last (HTML w i)
-> Last (HTML w i)
-> Last (HTML w i)
-> Last (HTML w i)
-> BorderLayout w i
forall w i.
Last (HTML w i)
-> Last (HTML w i)
-> Last (HTML w i)
-> Last (HTML w i)
-> Last (HTML w i)
-> BorderLayout w i
BorderLayout Last (HTML w i)
forall a. Monoid a => a
mempty Last (HTML w i)
forall a. Monoid a => a
mempty Last (HTML w i)
forall a. Monoid a => a
mempty Last (HTML w i)
forall a. Monoid a => a
mempty Last (HTML w i)
forall a. Monoid a => a
mempty

  addComponent :: forall w i.
LayoutConstraints BorderLayout
-> HTML w i -> BorderLayout w i -> BorderLayout w i
addComponent LayoutConstraints BorderLayout
side HTML w i
h BorderLayout w i
b = case LayoutConstraints BorderLayout
side of
    LayoutConstraints BorderLayout
R:LayoutConstraintsBorderLayout
North -> BorderLayout w i
b {north = b.north <> pure h}
    LayoutConstraints BorderLayout
R:LayoutConstraintsBorderLayout
South -> BorderLayout w i
b {south = b.south <> pure h}
    LayoutConstraints BorderLayout
R:LayoutConstraintsBorderLayout
East -> BorderLayout w i
b {east = b.east <> pure h}
    LayoutConstraints BorderLayout
R:LayoutConstraintsBorderLayout
West -> BorderLayout w i
b {west = b.west <> pure h}
    LayoutConstraints BorderLayout
R:LayoutConstraintsBorderLayout
Center -> BorderLayout w i
b {center = b.center <> pure h}