module Chiasma.Ui.Data.Measure where

import Control.Lens (makeClassy)
import Prettyprinter (Pretty (..), (<+>))

import Chiasma.Data.Axis (Axis)
import Chiasma.Data.TmuxId (PaneId (..))
import Chiasma.Ui.Data.Tree (NNode, NTree)

data MPane =
  MPane {
    MPane -> PaneId
_paneId :: PaneId,
    MPane -> Int
_mainPosition :: Int,
    MPane -> Int
_offPosition :: Int
  }
  deriving stock (MPane -> MPane -> Bool
(MPane -> MPane -> Bool) -> (MPane -> MPane -> Bool) -> Eq MPane
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: MPane -> MPane -> Bool
== :: MPane -> MPane -> Bool
$c/= :: MPane -> MPane -> Bool
/= :: MPane -> MPane -> Bool
Eq, Int -> MPane -> ShowS
[MPane] -> ShowS
MPane -> String
(Int -> MPane -> ShowS)
-> (MPane -> String) -> ([MPane] -> ShowS) -> Show MPane
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> MPane -> ShowS
showsPrec :: Int -> MPane -> ShowS
$cshow :: MPane -> String
show :: MPane -> String
$cshowList :: [MPane] -> ShowS
showList :: [MPane] -> ShowS
Show)

makeClassy ''MPane

data MLayout =
  MLayout {
    MLayout -> PaneId
_reference :: PaneId,
    MLayout -> Int
_lMainPosition :: Int,
    MLayout -> Int
_lOffPosition :: Int,
    MLayout -> Axis
_axis :: Axis
  }
  deriving stock (MLayout -> MLayout -> Bool
(MLayout -> MLayout -> Bool)
-> (MLayout -> MLayout -> Bool) -> Eq MLayout
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: MLayout -> MLayout -> Bool
== :: MLayout -> MLayout -> Bool
$c/= :: MLayout -> MLayout -> Bool
/= :: MLayout -> MLayout -> Bool
Eq, Int -> MLayout -> ShowS
[MLayout] -> ShowS
MLayout -> String
(Int -> MLayout -> ShowS)
-> (MLayout -> String) -> ([MLayout] -> ShowS) -> Show MLayout
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> MLayout -> ShowS
showsPrec :: Int -> MLayout -> ShowS
$cshow :: MLayout -> String
show :: MLayout -> String
$cshowList :: [MLayout] -> ShowS
showList :: [MLayout] -> ShowS
Show)

makeClassy ''MLayout

data Measured a =
  Measured {
    forall a. Measured a -> Int
_size :: Int,
    forall a. Measured a -> a
_view :: a
  }
  deriving stock (Measured a -> Measured a -> Bool
(Measured a -> Measured a -> Bool)
-> (Measured a -> Measured a -> Bool) -> Eq (Measured a)
forall a. Eq a => Measured a -> Measured a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. Eq a => Measured a -> Measured a -> Bool
== :: Measured a -> Measured a -> Bool
$c/= :: forall a. Eq a => Measured a -> Measured a -> Bool
/= :: Measured a -> Measured a -> Bool
Eq, Int -> Measured a -> ShowS
[Measured a] -> ShowS
Measured a -> String
(Int -> Measured a -> ShowS)
-> (Measured a -> String)
-> ([Measured a] -> ShowS)
-> Show (Measured a)
forall a. Show a => Int -> Measured a -> ShowS
forall a. Show a => [Measured a] -> ShowS
forall a. Show a => Measured a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> Measured a -> ShowS
showsPrec :: Int -> Measured a -> ShowS
$cshow :: forall a. Show a => Measured a -> String
show :: Measured a -> String
$cshowList :: forall a. Show a => [Measured a] -> ShowS
showList :: [Measured a] -> ShowS
Show)

makeClassy ''Measured

type MeasureTree = NTree (Measured MLayout) (Measured MPane)
type MeasureTreeSub = NNode (Measured MLayout) (Measured MPane)

instance Pretty MLayout where
  pretty :: forall ann. MLayout -> Doc ann
pretty (MLayout (PaneId Int
refId) Int
mainPos Int
offPos Axis
axis') =
    Doc ann
"l –" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Doc ann
"ref:" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Int -> Doc ann
forall ann. Int -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty Int
refId Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Doc ann
"pos:" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Int -> Doc ann
forall ann. Int -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty Int
mainPos Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Doc ann
"(" Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Int -> Doc ann
forall ann. Int -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty Int
offPos Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann
")" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Axis -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Axis -> Doc ann
pretty Axis
axis'

instance Pretty MPane where
  pretty :: forall ann. MPane -> Doc ann
pretty (MPane (PaneId Int
paneId') Int
mainPos Int
offPos) =
    Doc ann
"p –" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Int -> Doc ann
forall ann. Int -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty Int
paneId' Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Doc ann
"pos:" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Int -> Doc ann
forall ann. Int -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty Int
mainPos Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Doc ann
"(" Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Int -> Doc ann
forall ann. Int -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty Int
offPos Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann
")"

instance Pretty a => Pretty (Measured a) where
  pretty :: forall ann. Measured a -> Doc ann
pretty (Measured Int
size' a
a) =
    a -> Doc ann
forall ann. a -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty a
a Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Doc ann
"size:" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Int -> Doc ann
forall ann. Int -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty Int
size'