module Proteome.Data.FilesState where

import Path (Abs, File, Path, filename, parent)
import Ribosome (pathText)
import Ribosome.Menu (Filter, MenuItem (MenuItem), Modal)
import qualified Ribosome.Menu.MenuState as MenuState
import Ribosome.Menu.MenuState (FilterMode (FilterMode), MenuMode (cycleFilter, renderFilter))
import Exon (exon)

data FileSegments =
  FileSegments {
    FileSegments -> Path Abs File
path :: Path Abs File,
    FileSegments -> Text
name :: Text,
    FileSegments -> Text
dir :: Text
  }
  deriving stock (FileSegments -> FileSegments -> Bool
(FileSegments -> FileSegments -> Bool)
-> (FileSegments -> FileSegments -> Bool) -> Eq FileSegments
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: FileSegments -> FileSegments -> Bool
$c/= :: FileSegments -> FileSegments -> Bool
== :: FileSegments -> FileSegments -> Bool
$c== :: FileSegments -> FileSegments -> Bool
Eq, Int -> FileSegments -> ShowS
[FileSegments] -> ShowS
FileSegments -> String
(Int -> FileSegments -> ShowS)
-> (FileSegments -> String)
-> ([FileSegments] -> ShowS)
-> Show FileSegments
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [FileSegments] -> ShowS
$cshowList :: [FileSegments] -> ShowS
show :: FileSegments -> String
$cshow :: FileSegments -> String
showsPrec :: Int -> FileSegments -> ShowS
$cshowsPrec :: Int -> FileSegments -> ShowS
Show, (forall x. FileSegments -> Rep FileSegments x)
-> (forall x. Rep FileSegments x -> FileSegments)
-> Generic FileSegments
forall x. Rep FileSegments x -> FileSegments
forall x. FileSegments -> Rep FileSegments x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep FileSegments x -> FileSegments
$cfrom :: forall x. FileSegments -> Rep FileSegments x
Generic)

fileSegments :: Path Abs File -> FileSegments
fileSegments :: Path Abs File -> FileSegments
fileSegments Path Abs File
path =
  FileSegments :: Path Abs File -> Text -> Text -> FileSegments
FileSegments {
    $sel:name:FileSegments :: Text
name = Path Rel File -> Text
forall b t. Path b t -> Text
pathText (Path Abs File -> Path Rel File
forall b. Path b File -> Path Rel File
filename Path Abs File
path),
    $sel:dir:FileSegments :: Text
dir = Path Abs Dir -> Text
forall b t. Path b t -> Text
pathText (Path Abs File -> Path Abs Dir
forall b t. Path b t -> Path b Dir
parent Path Abs File
path),
    Path Abs File
path :: Path Abs File
$sel:path:FileSegments :: Path Abs File
..
  }

data Segment =
  Full
  |
  Name
  |
  Dir
  deriving stock (Segment -> Segment -> Bool
(Segment -> Segment -> Bool)
-> (Segment -> Segment -> Bool) -> Eq Segment
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Segment -> Segment -> Bool
$c/= :: Segment -> Segment -> Bool
== :: Segment -> Segment -> Bool
$c== :: Segment -> Segment -> Bool
Eq, Int -> Segment -> ShowS
[Segment] -> ShowS
Segment -> String
(Int -> Segment -> ShowS)
-> (Segment -> String) -> ([Segment] -> ShowS) -> Show Segment
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Segment] -> ShowS
$cshowList :: [Segment] -> ShowS
show :: Segment -> String
$cshow :: Segment -> String
showsPrec :: Int -> Segment -> ShowS
$cshowsPrec :: Int -> Segment -> ShowS
Show, Eq Segment
Eq Segment
-> (Segment -> Segment -> Ordering)
-> (Segment -> Segment -> Bool)
-> (Segment -> Segment -> Bool)
-> (Segment -> Segment -> Bool)
-> (Segment -> Segment -> Bool)
-> (Segment -> Segment -> Segment)
-> (Segment -> Segment -> Segment)
-> Ord Segment
Segment -> Segment -> Bool
Segment -> Segment -> Ordering
Segment -> Segment -> Segment
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Segment -> Segment -> Segment
$cmin :: Segment -> Segment -> Segment
max :: Segment -> Segment -> Segment
$cmax :: Segment -> Segment -> Segment
>= :: Segment -> Segment -> Bool
$c>= :: Segment -> Segment -> Bool
> :: Segment -> Segment -> Bool
$c> :: Segment -> Segment -> Bool
<= :: Segment -> Segment -> Bool
$c<= :: Segment -> Segment -> Bool
< :: Segment -> Segment -> Bool
$c< :: Segment -> Segment -> Bool
compare :: Segment -> Segment -> Ordering
$ccompare :: Segment -> Segment -> Ordering
Ord)

renderSegment :: Segment -> Text
renderSegment :: Segment -> Text
renderSegment = \case
  Segment
Full -> Text
"full"
  Segment
Name -> Text
"name"
  Segment
Dir -> Text
"dir"

segmentExtract :: MenuItem FileSegments -> Segment -> Text
segmentExtract :: MenuItem FileSegments -> Segment -> Text
segmentExtract (MenuItem FileSegments {Text
Path Abs File
dir :: Text
name :: Text
path :: Path Abs File
$sel:dir:FileSegments :: FileSegments -> Text
$sel:name:FileSegments :: FileSegments -> Text
$sel:path:FileSegments :: FileSegments -> Path Abs File
..} Text
_ Text
render) = \case
  Segment
Full -> Text
render
  Segment
Name -> Text
name
  Segment
Dir -> Text
dir

cycle :: Segment -> Segment
cycle :: Segment -> Segment
cycle = \case
  Segment
Full -> Segment
Name
  Segment
Name -> Segment
Dir
  Segment
Dir -> Segment
Full

data FilesMode =
  FilesMode {
    FilesMode -> Filter
mode :: Filter,
    FilesMode -> Segment
segment :: Segment
  }
  deriving stock (FilesMode -> FilesMode -> Bool
(FilesMode -> FilesMode -> Bool)
-> (FilesMode -> FilesMode -> Bool) -> Eq FilesMode
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: FilesMode -> FilesMode -> Bool
$c/= :: FilesMode -> FilesMode -> Bool
== :: FilesMode -> FilesMode -> Bool
$c== :: FilesMode -> FilesMode -> Bool
Eq, Int -> FilesMode -> ShowS
[FilesMode] -> ShowS
FilesMode -> String
(Int -> FilesMode -> ShowS)
-> (FilesMode -> String)
-> ([FilesMode] -> ShowS)
-> Show FilesMode
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [FilesMode] -> ShowS
$cshowList :: [FilesMode] -> ShowS
show :: FilesMode -> String
$cshow :: FilesMode -> String
showsPrec :: Int -> FilesMode -> ShowS
$cshowsPrec :: Int -> FilesMode -> ShowS
Show, Eq FilesMode
Eq FilesMode
-> (FilesMode -> FilesMode -> Ordering)
-> (FilesMode -> FilesMode -> Bool)
-> (FilesMode -> FilesMode -> Bool)
-> (FilesMode -> FilesMode -> Bool)
-> (FilesMode -> FilesMode -> Bool)
-> (FilesMode -> FilesMode -> FilesMode)
-> (FilesMode -> FilesMode -> FilesMode)
-> Ord FilesMode
FilesMode -> FilesMode -> Bool
FilesMode -> FilesMode -> Ordering
FilesMode -> FilesMode -> FilesMode
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: FilesMode -> FilesMode -> FilesMode
$cmin :: FilesMode -> FilesMode -> FilesMode
max :: FilesMode -> FilesMode -> FilesMode
$cmax :: FilesMode -> FilesMode -> FilesMode
>= :: FilesMode -> FilesMode -> Bool
$c>= :: FilesMode -> FilesMode -> Bool
> :: FilesMode -> FilesMode -> Bool
$c> :: FilesMode -> FilesMode -> Bool
<= :: FilesMode -> FilesMode -> Bool
$c<= :: FilesMode -> FilesMode -> Bool
< :: FilesMode -> FilesMode -> Bool
$c< :: FilesMode -> FilesMode -> Bool
compare :: FilesMode -> FilesMode -> Ordering
$ccompare :: FilesMode -> FilesMode -> Ordering
Ord, (forall x. FilesMode -> Rep FilesMode x)
-> (forall x. Rep FilesMode x -> FilesMode) -> Generic FilesMode
forall x. Rep FilesMode x -> FilesMode
forall x. FilesMode -> Rep FilesMode x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep FilesMode x -> FilesMode
$cfrom :: forall x. FilesMode -> Rep FilesMode x
Generic)

type FilesState =
  Modal FilesMode FileSegments

instance MenuMode FileSegments FilesMode where
  type Filter FilesMode =
    FilterMode Filter

  cycleFilter :: FilesMode -> FilesMode
cycleFilter (FilesMode Filter
mode Segment
segment) =
    Filter -> Segment -> FilesMode
FilesMode (Filter -> Filter
forall i mode. MenuMode i mode => mode -> mode
cycleFilter Filter
mode) Segment
segment

  renderFilter :: FilesMode -> Text
renderFilter (FilesMode Filter
mode Segment
_) =
    Filter -> Text
forall i mode. MenuMode i mode => mode -> Text
renderFilter Filter
mode

  renderExtra :: FilesMode -> Maybe Text
renderExtra (FilesMode Filter
_ Segment
segment) =
    Text -> Maybe Text
forall a. a -> Maybe a
Just [exon|🔧 #{renderSegment segment}|]

  filterMode :: FilesMode -> Filter FilesMode FileSegments
filterMode (FilesMode Filter
mode Segment
segment) =
    Filter
-> (MenuItem FileSegments -> Maybe Text)
-> FilterMode Filter FileSegments
forall f i. f -> (MenuItem i -> Maybe Text) -> FilterMode f i
FilterMode Filter
mode (Text -> Maybe Text
forall a. a -> Maybe a
Just (Text -> Maybe Text)
-> (MenuItem FileSegments -> Text)
-> MenuItem FileSegments
-> Maybe Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (MenuItem FileSegments -> Segment -> Text)
-> Segment -> MenuItem FileSegments -> Text
forall a b c. (a -> b -> c) -> b -> a -> c
flip MenuItem FileSegments -> Segment -> Text
segmentExtract Segment
segment)