module Taskell.Events.State
    -- App
    ( continue
    , write
    , setTime
    , countCurrent
    , setHeight
    -- Taskell.UI.Main
    , normalise
    -- Main
    , create
    -- Taskell.Events.Actions.Normal
    , quit
    , startEdit
    , startCreate
    , createListStart
    , editListStart
    , deleteCurrentList
    , clearItem
    , clearDate
    , above
    , below
    , bottom
    , top
    , previous
    , duplicate
    , next
    , left
    , right
    , up
    , down
    , moveLeftTop
    , moveRightTop
    , moveLeftBottom
    , moveRightBottom
    , moveToLast
    , delete
    , selectList
    , listLeft
    , listRight
    , undo
    , redo
    , store
    , searchMode
    , clearSearch
    , appendSearch
    -- Taskell.Events.Actions.Insert
    , createList
    , removeBlank
    , newItem
    , normalMode
    , finishTask
    , finishListTitle
    -- Taskell.Events.Actions.Modal
    , showHelp
    , showMoveTo
    , moveTo
    , getCurrentList
    , getCurrentTask
    , setCurrentTask
    ) where

import ClassyPrelude hiding (delete)

import Control.Lens ((%~), (&), (.~), (?~), (^.))

import Data.Char       (digitToInt, ord)
import Data.Text       (strip)
import Data.Time.Zones (TZ)

import qualified Taskell.Data.List  as L (List, deleteTask, duplicate, getTask, move, nearest, new,
                                          newAt, nextTask, prevTask, title, update)
import qualified Taskell.Data.Lists as Lists
import           Taskell.Data.Task  (Task, isBlank, name)
import           Taskell.Types

import qualified Taskell.Events.State.History    as History (redo, store, undo)
import           Taskell.Events.State.Types
import           Taskell.Events.State.Types.Mode (InsertMode (..), InsertType (..), ModalType (..),
                                                  Mode (..))
import           Taskell.UI.Draw.Field           (Field, blankField, getText, textToField)

type InternalStateful = State -> State

create :: TZ -> UTCTime -> FilePath -> Lists.Lists -> State
create :: TZ -> UTCTime -> FilePath -> Lists -> State
create TZ
tz UTCTime
t FilePath
p Lists
ls =
    State :: Mode
-> History Moment
-> FilePath
-> Maybe Lists
-> Int
-> Maybe Field
-> UTCTime
-> TZ
-> State
State
    { _mode :: Mode
_mode = Mode
Normal
    , _history :: History Moment
_history = Lists -> History Moment
fresh Lists
ls
    , _path :: FilePath
_path = FilePath
p
    , _io :: Maybe Lists
_io = Maybe Lists
forall a. Maybe a
Nothing
    , _height :: Int
_height = Int
0
    , _searchTerm :: Maybe Field
_searchTerm = Maybe Field
forall a. Maybe a
Nothing
    , _time :: UTCTime
_time = UTCTime
t
    , _timeZone :: TZ
_timeZone = TZ
tz
    }

-- app state
quit :: Stateful
quit :: Stateful
quit = Stateful
forall (f :: * -> *) a. Applicative f => a -> f a
pure Stateful -> (State -> State) -> Stateful
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. ((Mode -> Identity Mode) -> State -> Identity State
Lens' State Mode
mode ((Mode -> Identity Mode) -> State -> Identity State)
-> Mode -> State -> State
forall s t a b. ASetter s t a b -> b -> s -> t
.~ Mode
Shutdown)

continue :: State -> State
continue :: State -> State
continue = (Maybe Lists -> Identity (Maybe Lists)) -> State -> Identity State
Lens' State (Maybe Lists)
io ((Maybe Lists -> Identity (Maybe Lists))
 -> State -> Identity State)
-> Maybe Lists -> State -> State
forall s t a b. ASetter s t a b -> b -> s -> t
.~ Maybe Lists
forall a. Maybe a
Nothing

store :: Stateful
store :: Stateful
store State
state = Stateful
forall (f :: * -> *) a. Applicative f => a -> f a
pure Stateful -> Stateful
forall a b. (a -> b) -> a -> b
$ State
state State -> (State -> State) -> State
forall a b. a -> (a -> b) -> b
& (History Moment -> Identity (History Moment))
-> State -> Identity State
Lens' State (History Moment)
history ((History Moment -> Identity (History Moment))
 -> State -> Identity State)
-> (History Moment -> History Moment) -> State -> State
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ History Moment -> History Moment
forall a. History a -> History a
History.store

undo :: Stateful
undo :: Stateful
undo State
state = Stateful
forall (f :: * -> *) a. Applicative f => a -> f a
pure Stateful -> Stateful
forall a b. (a -> b) -> a -> b
$ State
state State -> (State -> State) -> State
forall a b. a -> (a -> b) -> b
& (History Moment -> Identity (History Moment))
-> State -> Identity State
Lens' State (History Moment)
history ((History Moment -> Identity (History Moment))
 -> State -> Identity State)
-> (History Moment -> History Moment) -> State -> State
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ History Moment -> History Moment
forall a. History a -> History a
History.undo

redo :: Stateful
redo :: Stateful
redo State
state = Stateful
forall (f :: * -> *) a. Applicative f => a -> f a
pure Stateful -> Stateful
forall a b. (a -> b) -> a -> b
$ State
state State -> (State -> State) -> State
forall a b. a -> (a -> b) -> b
& (History Moment -> Identity (History Moment))
-> State -> Identity State
Lens' State (History Moment)
history ((History Moment -> Identity (History Moment))
 -> State -> Identity State)
-> (History Moment -> History Moment) -> State -> State
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ History Moment -> History Moment
forall a. History a -> History a
History.redo

setTime :: UTCTime -> State -> State
setTime :: UTCTime -> State -> State
setTime UTCTime
t = (UTCTime -> Identity UTCTime) -> State -> Identity State
Lens' State UTCTime
time ((UTCTime -> Identity UTCTime) -> State -> Identity State)
-> UTCTime -> State -> State
forall s t a b. ASetter s t a b -> b -> s -> t
.~ UTCTime
t

write :: Stateful
write :: Stateful
write State
state = Stateful
forall (f :: * -> *) a. Applicative f => a -> f a
pure Stateful -> Stateful
forall a b. (a -> b) -> a -> b
$ State
state State -> (State -> State) -> State
forall a b. a -> (a -> b) -> b
& ((Maybe Lists -> Identity (Maybe Lists)) -> State -> Identity State
Lens' State (Maybe Lists)
io ((Maybe Lists -> Identity (Maybe Lists))
 -> State -> Identity State)
-> Lists -> State -> State
forall s t a b. ASetter s t a (Maybe b) -> b -> s -> t
?~ (State
state State -> Getting Lists State Lists -> Lists
forall s a. s -> Getting a s a -> a
^. Getting Lists State Lists
Lens' State Lists
lists))

-- createList
createList :: Stateful
createList :: Stateful
createList State
state =
    Stateful
forall (f :: * -> *) a. Applicative f => a -> f a
pure Stateful -> Stateful
forall a b. (a -> b) -> a -> b
$
    case State
state State -> Getting Mode State Mode -> Mode
forall s a. s -> Getting a s a -> a
^. Getting Mode State Mode
Lens' State Mode
mode of
        Insert InsertType
IList InsertMode
ICreate Field
f ->
            State -> State
updateListToLast (State -> State) -> (Lists -> State) -> Lists -> State
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. State -> Lists -> State
setLists State
state (Lists -> State) -> Lists -> State
forall a b. (a -> b) -> a -> b
$ Text -> Update
Lists.newList (Field -> Text
getText Field
f) Update -> Update
forall a b. (a -> b) -> a -> b
$ State
state State -> Getting Lists State Lists -> Lists
forall s a. s -> Getting a s a -> a
^. Getting Lists State Lists
Lens' State Lists
lists
        Mode
_ -> State
state

updateListToLast :: InternalStateful
updateListToLast :: State -> State
updateListToLast State
state = State -> Int -> State
setCurrentList State
state (Lists -> Int
forall mono. MonoFoldable mono => mono -> Int
length (State
state State -> Getting Lists State Lists -> Lists
forall s a. s -> Getting a s a -> a
^. Getting Lists State Lists
Lens' State Lists
lists) Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)

createListStart :: Stateful
createListStart :: Stateful
createListStart = Stateful
forall (f :: * -> *) a. Applicative f => a -> f a
pure Stateful -> (State -> State) -> Stateful
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. ((Mode -> Identity Mode) -> State -> Identity State
Lens' State Mode
mode ((Mode -> Identity Mode) -> State -> Identity State)
-> Mode -> State -> State
forall s t a b. ASetter s t a b -> b -> s -> t
.~ InsertType -> InsertMode -> Field -> Mode
Insert InsertType
IList InsertMode
ICreate Field
blankField)

-- editList
editListStart :: Stateful
editListStart :: Stateful
editListStart State
state = do
    Field
f <- Text -> Field
textToField (Text -> Field) -> (List -> Text) -> List -> Field
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (List -> Getting Text List Text -> Text
forall s a. s -> Getting a s a -> a
^. Getting Text List Text
Lens' List Text
L.title) (List -> Field) -> Maybe List -> Maybe Field
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> State -> Maybe List
getList State
state
    Stateful
forall (f :: * -> *) a. Applicative f => a -> f a
pure Stateful -> Stateful
forall a b. (a -> b) -> a -> b
$ State
state State -> (State -> State) -> State
forall a b. a -> (a -> b) -> b
& (Mode -> Identity Mode) -> State -> Identity State
Lens' State Mode
mode ((Mode -> Identity Mode) -> State -> Identity State)
-> Mode -> State -> State
forall s t a b. ASetter s t a b -> b -> s -> t
.~ InsertType -> InsertMode -> Field -> Mode
Insert InsertType
IList InsertMode
IEdit Field
f

deleteCurrentList :: Stateful
deleteCurrentList :: Stateful
deleteCurrentList State
state =
    Stateful
forall (f :: * -> *) a. Applicative f => a -> f a
pure Stateful -> (Lists -> State) -> Lists -> Maybe State
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. State -> State
fixIndex (State -> State) -> (Lists -> State) -> Lists -> State
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. State -> Lists -> State
setLists State
state (Lists -> Maybe State) -> Lists -> Maybe State
forall a b. (a -> b) -> a -> b
$ Int -> Update
Lists.delete (State -> Int
getCurrentList State
state) (State
state State -> Getting Lists State Lists -> Lists
forall s a. s -> Getting a s a -> a
^. Getting Lists State Lists
Lens' State Lists
lists)

-- insert
getCurrentTask :: State -> Maybe Task
getCurrentTask :: State -> Maybe Task
getCurrentTask State
state = State -> Maybe List
getList State
state Maybe List -> (List -> Maybe Task) -> Maybe Task
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Int -> List -> Maybe Task
L.getTask (State -> Int
getIndex State
state)

setCurrentTask :: Task -> Stateful
setCurrentTask :: Task -> Stateful
setCurrentTask Task
task State
state = State -> List -> State
setList State
state (List -> State) -> (List -> List) -> List -> State
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Int -> Task -> List -> List
L.update (State -> Int
getIndex State
state) Task
task (List -> State) -> Maybe List -> Maybe State
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> State -> Maybe List
getList State
state

setCurrentTaskText :: Text -> Stateful
setCurrentTaskText :: Text -> Stateful
setCurrentTaskText Text
text State
state =
    (Task -> Stateful) -> State -> Task -> Maybe State
forall a b c. (a -> b -> c) -> b -> a -> c
flip Task -> Stateful
setCurrentTask State
state (Task -> Maybe State) -> Maybe Task -> Maybe State
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< ((Text -> Identity Text) -> Task -> Identity Task
Lens' Task Text
name ((Text -> Identity Text) -> Task -> Identity Task)
-> Text -> Task -> Task
forall s t a b. ASetter s t a b -> b -> s -> t
.~ Text -> Text
strip Text
text) (Task -> Task) -> Maybe Task -> Maybe Task
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> State -> Maybe Task
getCurrentTask State
state

startCreate :: Stateful
startCreate :: Stateful
startCreate = Stateful
forall (f :: * -> *) a. Applicative f => a -> f a
pure Stateful -> (State -> State) -> Stateful
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. ((Mode -> Identity Mode) -> State -> Identity State
Lens' State Mode
mode ((Mode -> Identity Mode) -> State -> Identity State)
-> Mode -> State -> State
forall s t a b. ASetter s t a b -> b -> s -> t
.~ InsertType -> InsertMode -> Field -> Mode
Insert InsertType
ITask InsertMode
ICreate Field
blankField)

startEdit :: Stateful
startEdit :: Stateful
startEdit State
state = do
    Field
field <- Text -> Field
textToField (Text -> Field) -> (Task -> Text) -> Task -> Field
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (Task -> Getting Text Task Text -> Text
forall s a. s -> Getting a s a -> a
^. Getting Text Task Text
Lens' Task Text
name) (Task -> Field) -> Maybe Task -> Maybe Field
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> State -> Maybe Task
getCurrentTask State
state
    Stateful
forall (f :: * -> *) a. Applicative f => a -> f a
pure Stateful -> Stateful
forall a b. (a -> b) -> a -> b
$ State
state State -> (State -> State) -> State
forall a b. a -> (a -> b) -> b
& (Mode -> Identity Mode) -> State -> Identity State
Lens' State Mode
mode ((Mode -> Identity Mode) -> State -> Identity State)
-> Mode -> State -> State
forall s t a b. ASetter s t a b -> b -> s -> t
.~ InsertType -> InsertMode -> Field -> Mode
Insert InsertType
ITask InsertMode
IEdit Field
field

finishTask :: Stateful
finishTask :: Stateful
finishTask State
state =
    case State
state State -> Getting Mode State Mode -> Mode
forall s a. s -> Getting a s a -> a
^. Getting Mode State Mode
Lens' State Mode
mode of
        Insert InsertType
ITask InsertMode
iMode Field
f ->
            Text -> Stateful
setCurrentTaskText (Field -> Text
getText Field
f) Stateful -> Stateful
forall a b. (a -> b) -> a -> b
$ State
state State -> (State -> State) -> State
forall a b. a -> (a -> b) -> b
& ((Mode -> Identity Mode) -> State -> Identity State
Lens' State Mode
mode ((Mode -> Identity Mode) -> State -> Identity State)
-> Mode -> State -> State
forall s t a b. ASetter s t a b -> b -> s -> t
.~ InsertType -> InsertMode -> Field -> Mode
Insert InsertType
ITask InsertMode
iMode Field
blankField)
        Mode
_ -> Stateful
forall (f :: * -> *) a. Applicative f => a -> f a
pure State
state

finishListTitle :: Stateful
finishListTitle :: Stateful
finishListTitle State
state =
    case State
state State -> Getting Mode State Mode -> Mode
forall s a. s -> Getting a s a -> a
^. Getting Mode State Mode
Lens' State Mode
mode of
        Insert InsertType
IList InsertMode
iMode Field
f ->
            Text -> Stateful
setCurrentListTitle (Field -> Text
getText Field
f) Stateful -> Stateful
forall a b. (a -> b) -> a -> b
$ State
state State -> (State -> State) -> State
forall a b. a -> (a -> b) -> b
& ((Mode -> Identity Mode) -> State -> Identity State
Lens' State Mode
mode ((Mode -> Identity Mode) -> State -> Identity State)
-> Mode -> State -> State
forall s t a b. ASetter s t a b -> b -> s -> t
.~ InsertType -> InsertMode -> Field -> Mode
Insert InsertType
IList InsertMode
iMode Field
blankField)
        Mode
_ -> Stateful
forall (f :: * -> *) a. Applicative f => a -> f a
pure State
state

normalMode :: Stateful
normalMode :: Stateful
normalMode = Stateful
forall (f :: * -> *) a. Applicative f => a -> f a
pure Stateful -> (State -> State) -> Stateful
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. ((Mode -> Identity Mode) -> State -> Identity State
Lens' State Mode
mode ((Mode -> Identity Mode) -> State -> Identity State)
-> Mode -> State -> State
forall s t a b. ASetter s t a b -> b -> s -> t
.~ Mode
Normal)

addToListAt :: Int -> Stateful
addToListAt :: Int -> Stateful
addToListAt Int
offset State
state = do
    let idx :: Int
idx = State -> Int
getIndex State
state Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
offset
    State -> State
fixIndex (State -> State) -> (List -> State) -> List -> State
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. State -> List -> State
setList (State -> Int -> State
setIndex State
state Int
idx) (List -> State) -> (List -> List) -> List -> State
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Int -> List -> List
L.newAt Int
idx (List -> State) -> Maybe List -> Maybe State
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> State -> Maybe List
getList State
state

above :: Stateful
above :: Stateful
above = Int -> Stateful
addToListAt Int
0

below :: Stateful
below :: Stateful
below = Int -> Stateful
addToListAt Int
1

newItem :: Stateful
newItem :: Stateful
newItem State
state = State -> State
selectLast (State -> State) -> (List -> State) -> List -> State
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. State -> List -> State
setList State
state (List -> State) -> (List -> List) -> List -> State
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. List -> List
L.new (List -> State) -> Maybe List -> Maybe State
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> State -> Maybe List
getList State
state

duplicate :: Stateful
duplicate :: Stateful
duplicate State
state = State -> List -> State
setList State
state (List -> State) -> Maybe List -> Maybe State
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Int -> List -> Maybe List
L.duplicate (State -> Int
getIndex State
state) (List -> Maybe List) -> Maybe List -> Maybe List
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< State -> Maybe List
getList State
state)

clearItem :: Stateful
clearItem :: Stateful
clearItem = Text -> Stateful
setCurrentTaskText Text
""

clearDate :: Stateful
clearDate :: Stateful
clearDate State
state = Stateful
forall (f :: * -> *) a. Applicative f => a -> f a
pure Stateful -> Stateful
forall a b. (a -> b) -> a -> b
$ State
state State -> (State -> State) -> State
forall a b. a -> (a -> b) -> b
& (Lists -> Identity Lists) -> State -> Identity State
Lens' State Lists
lists ((Lists -> Identity Lists) -> State -> Identity State)
-> Lists -> State -> State
forall s t a b. ASetter s t a b -> b -> s -> t
.~ Pointer -> Update
Lists.clearDue (State
state State -> Getting Pointer State Pointer -> Pointer
forall s a. s -> Getting a s a -> a
^. Getting Pointer State Pointer
Lens' State Pointer
current) (State
state State -> Getting Lists State Lists -> Lists
forall s a. s -> Getting a s a -> a
^. Getting Lists State Lists
Lens' State Lists
lists)

bottom :: Stateful
bottom :: Stateful
bottom = Stateful
forall (f :: * -> *) a. Applicative f => a -> f a
pure Stateful -> (State -> State) -> Stateful
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. State -> State
selectLast

selectLast :: InternalStateful
selectLast :: State -> State
selectLast State
state = State -> Int -> State
setIndex State
state (State -> Int
countCurrent State
state Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)

top :: Stateful
top :: Stateful
top = Stateful
forall (f :: * -> *) a. Applicative f => a -> f a
pure Stateful -> (State -> State) -> Stateful
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. State -> State
selectFirst

selectFirst :: InternalStateful
selectFirst :: State -> State
selectFirst State
state = State -> Int -> State
setIndex State
state (Int
0)

removeBlank :: Stateful
removeBlank :: Stateful
removeBlank State
state = do
    Task
currentTask <- State -> Maybe Task
getCurrentTask State
state
    (if Task -> Bool
isBlank Task
currentTask
         then Stateful
delete
         else Stateful
forall (f :: * -> *) a. Applicative f => a -> f a
pure)
        State
state

-- moving
--
moveVertical :: Int -> Stateful
moveVertical :: Int -> Stateful
moveVertical Int
dir State
state = do
    (List
lst, Int
idx) <- Int -> Int -> Maybe Text -> List -> Maybe (List, Int)
L.move (State -> Int
getIndex State
state) Int
dir (Field -> Text
getText (Field -> Text) -> Maybe Field -> Maybe Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> State
state State -> Getting (Maybe Field) State (Maybe Field) -> Maybe Field
forall s a. s -> Getting a s a -> a
^. Getting (Maybe Field) State (Maybe Field)
Lens' State (Maybe Field)
searchTerm) (List -> Maybe (List, Int)) -> Maybe List -> Maybe (List, Int)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< State -> Maybe List
getList State
state
    Stateful
forall (f :: * -> *) a. Applicative f => a -> f a
pure Stateful -> Stateful
forall a b. (a -> b) -> a -> b
$ State -> Int -> State
setIndex (State -> List -> State
setList State
state List
lst) Int
idx

up :: Stateful
up :: Stateful
up = Int -> Stateful
moveVertical (-Int
1)

down :: Stateful
down :: Stateful
down = Int -> Stateful
moveVertical Int
1

moveHorizontal :: Int -> Lists.ListPosition -> State -> Maybe State
moveHorizontal :: Int -> ListPosition -> Stateful
moveHorizontal Int
idx ListPosition
pos State
state =
    State -> State
fixIndex (State -> State) -> (Lists -> State) -> Lists -> State
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. State -> Lists -> State
setLists State
state (Lists -> State) -> Maybe Lists -> Maybe State
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ListPosition -> Pointer -> Lists -> Int -> Maybe Lists
Lists.changeList ListPosition
pos (State
state State -> Getting Pointer State Pointer -> Pointer
forall s a. s -> Getting a s a -> a
^. Getting Pointer State Pointer
Lens' State Pointer
current) (State
state State -> Getting Lists State Lists -> Lists
forall s a. s -> Getting a s a -> a
^. Getting Lists State Lists
Lens' State Lists
lists) Int
idx

moveLeftBottom :: Stateful
moveLeftBottom :: Stateful
moveLeftBottom = Int -> ListPosition -> Stateful
moveHorizontal (-Int
1) ListPosition
Lists.Bottom

moveRightBottom :: Stateful
moveRightBottom :: Stateful
moveRightBottom = Int -> ListPosition -> Stateful
moveHorizontal Int
1 ListPosition
Lists.Bottom

moveLeftTop :: Stateful
moveLeftTop :: Stateful
moveLeftTop = Int -> ListPosition -> Stateful
moveHorizontal (-Int
1) ListPosition
Lists.Top

moveRightTop :: Stateful
moveRightTop :: Stateful
moveRightTop = Int -> ListPosition -> Stateful
moveHorizontal Int
1 ListPosition
Lists.Top

moveToLast :: Stateful
moveToLast :: Stateful
moveToLast State
state =
    if Int
idx Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
cur
        then Stateful
forall (f :: * -> *) a. Applicative f => a -> f a
pure State
state
        else Int -> ListPosition -> Stateful
moveHorizontal (Int
idx Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
cur) ListPosition
Lists.Bottom State
state
  where
    idx :: Int
idx = Lists -> Int
forall mono. MonoFoldable mono => mono -> Int
length (State
state State -> Getting Lists State Lists -> Lists
forall s a. s -> Getting a s a -> a
^. Getting Lists State Lists
Lens' State Lists
lists) Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
    cur :: Int
cur = State -> Int
getCurrentList State
state

selectList :: Char -> Stateful
selectList :: Char -> Stateful
selectList Char
idx State
state =
    Stateful
forall (f :: * -> *) a. Applicative f => a -> f a
pure Stateful -> Stateful
forall a b. (a -> b) -> a -> b
$
    (if Bool
exists
         then (Pointer -> Identity Pointer) -> State -> Identity State
Lens' State Pointer
current ((Pointer -> Identity Pointer) -> State -> Identity State)
-> Pointer -> State -> State
forall s t a b. ASetter s t a b -> b -> s -> t
.~ (Int -> ListIndex
ListIndex Int
list, Int -> TaskIndex
TaskIndex Int
0)
         else State -> State
forall k (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id)
        State
state
  where
    list :: Int
list = Char -> Int
digitToInt Char
idx Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
    exists :: Bool
exists = Int -> Lists -> Bool
Lists.exists Int
list (State
state State -> Getting Lists State Lists -> Lists
forall s a. s -> Getting a s a -> a
^. Getting Lists State Lists
Lens' State Lists
lists)

-- removing
delete :: Stateful
delete :: Stateful
delete State
state = State -> State
fixIndex (State -> State) -> (List -> State) -> List -> State
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. State -> List -> State
setList State
state (List -> State) -> (List -> List) -> List -> State
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Int -> List -> List
L.deleteTask (State -> Int
getIndex State
state) (List -> State) -> Maybe List -> Maybe State
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> State -> Maybe List
getList State
state

-- list and index
countCurrent :: State -> Int
countCurrent :: State -> Int
countCurrent State
state = Int -> Lists -> Int
Lists.count (State -> Int
getCurrentList State
state) (State
state State -> Getting Lists State Lists -> Lists
forall s a. s -> Getting a s a -> a
^. Getting Lists State Lists
Lens' State Lists
lists)

setIndex :: State -> Int -> State
setIndex :: State -> Int -> State
setIndex State
state Int
idx = State
state State -> (State -> State) -> State
forall a b. a -> (a -> b) -> b
& (Pointer -> Identity Pointer) -> State -> Identity State
Lens' State Pointer
current ((Pointer -> Identity Pointer) -> State -> Identity State)
-> Pointer -> State -> State
forall s t a b. ASetter s t a b -> b -> s -> t
.~ (Int -> ListIndex
ListIndex (State -> Int
getCurrentList State
state), Int -> TaskIndex
TaskIndex Int
idx)

setCurrentList :: State -> Int -> State
setCurrentList :: State -> Int -> State
setCurrentList State
state Int
idx = State
state State -> (State -> State) -> State
forall a b. a -> (a -> b) -> b
& (Pointer -> Identity Pointer) -> State -> Identity State
Lens' State Pointer
current ((Pointer -> Identity Pointer) -> State -> Identity State)
-> Pointer -> State -> State
forall s t a b. ASetter s t a b -> b -> s -> t
.~ (Int -> ListIndex
ListIndex Int
idx, Int -> TaskIndex
TaskIndex (State -> Int
getIndex State
state))

getIndex :: State -> Int
getIndex :: State -> Int
getIndex = TaskIndex -> Int
showTaskIndex (TaskIndex -> Int) -> (State -> TaskIndex) -> State -> Int
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Pointer -> TaskIndex
forall a b. (a, b) -> b
snd (Pointer -> TaskIndex) -> (State -> Pointer) -> State -> TaskIndex
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (State -> Getting Pointer State Pointer -> Pointer
forall s a. s -> Getting a s a -> a
^. Getting Pointer State Pointer
Lens' State Pointer
current)

changeTask :: (Int -> Maybe Text -> L.List -> Int) -> Stateful
changeTask :: (Int -> Maybe Text -> List -> Int) -> Stateful
changeTask Int -> Maybe Text -> List -> Int
fn State
state = do
    List
list <- State -> Maybe List
getList State
state
    let idx :: Int
idx = State -> Int
getIndex State
state
    let term :: Maybe Text
term = Field -> Text
getText (Field -> Text) -> Maybe Field -> Maybe Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> State
state State -> Getting (Maybe Field) State (Maybe Field) -> Maybe Field
forall s a. s -> Getting a s a -> a
^. Getting (Maybe Field) State (Maybe Field)
Lens' State (Maybe Field)
searchTerm
    Stateful
forall (f :: * -> *) a. Applicative f => a -> f a
pure Stateful -> Stateful
forall a b. (a -> b) -> a -> b
$ State -> Int -> State
setIndex State
state (Int -> Maybe Text -> List -> Int
fn Int
idx Maybe Text
term List
list)

next :: Stateful
next :: Stateful
next = (Int -> Maybe Text -> List -> Int) -> Stateful
changeTask Int -> Maybe Text -> List -> Int
L.nextTask

previous :: Stateful
previous :: Stateful
previous = (Int -> Maybe Text -> List -> Int) -> Stateful
changeTask Int -> Maybe Text -> List -> Int
L.prevTask

left :: Stateful
left :: Stateful
left State
state =
    Stateful
forall (f :: * -> *) a. Applicative f => a -> f a
pure Stateful -> (Int -> State) -> Int -> Maybe State
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. State -> State
fixIndex (State -> State) -> (Int -> State) -> Int -> State
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. State -> Int -> State
setCurrentList State
state (Int -> Maybe State) -> Int -> Maybe State
forall a b. (a -> b) -> a -> b
$
    if Int
list Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0
        then Int -> Int
forall a. Enum a => a -> a
pred Int
list
        else Int
0
  where
    list :: Int
list = State -> Int
getCurrentList State
state

right :: Stateful
right :: Stateful
right State
state =
    Stateful
forall (f :: * -> *) a. Applicative f => a -> f a
pure Stateful -> (Int -> State) -> Int -> Maybe State
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. State -> State
fixIndex (State -> State) -> (Int -> State) -> Int -> State
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. State -> Int -> State
setCurrentList State
state (Int -> Maybe State) -> Int -> Maybe State
forall a b. (a -> b) -> a -> b
$
    if Int
list Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< (Int
count Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
        then Int -> Int
forall a. Enum a => a -> a
succ Int
list
        else Int
list
  where
    list :: Int
list = State -> Int
getCurrentList State
state
    count :: Int
count = Lists -> Int
forall mono. MonoFoldable mono => mono -> Int
length (State
state State -> Getting Lists State Lists -> Lists
forall s a. s -> Getting a s a -> a
^. Getting Lists State Lists
Lens' State Lists
lists)

fixListIndex :: InternalStateful
fixListIndex :: State -> State
fixListIndex State
state =
    if Bool
listIdx
        then State
state
        else State -> Int -> State
setCurrentList State
state (Lists -> Int
forall mono. MonoFoldable mono => mono -> Int
length Lists
lists' Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
  where
    lists' :: Lists
lists' = State
state State -> Getting Lists State Lists -> Lists
forall s a. s -> Getting a s a -> a
^. Getting Lists State Lists
Lens' State Lists
lists
    listIdx :: Bool
listIdx = Int -> Lists -> Bool
Lists.exists (State -> Int
getCurrentList State
state) Lists
lists'

fixIndex :: InternalStateful
fixIndex :: State -> State
fixIndex State
state =
    case State -> Maybe List
getList State
state of
        Just List
list -> State -> Int -> State
setIndex State
state (Int -> Maybe Text -> List -> Int
L.nearest Int
idx Maybe Text
trm List
list)
        Maybe List
Nothing   -> State -> State
fixListIndex State
state
  where
    trm :: Maybe Text
trm = Field -> Text
getText (Field -> Text) -> Maybe Field -> Maybe Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> State
state State -> Getting (Maybe Field) State (Maybe Field) -> Maybe Field
forall s a. s -> Getting a s a -> a
^. Getting (Maybe Field) State (Maybe Field)
Lens' State (Maybe Field)
searchTerm
    idx :: Int
idx = State -> Int
getIndex State
state

-- tasks
getCurrentList :: State -> Int
getCurrentList :: State -> Int
getCurrentList = ListIndex -> Int
showListIndex (ListIndex -> Int) -> (State -> ListIndex) -> State -> Int
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Pointer -> ListIndex
forall a b. (a, b) -> a
fst (Pointer -> ListIndex) -> (State -> Pointer) -> State -> ListIndex
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (State -> Getting Pointer State Pointer -> Pointer
forall s a. s -> Getting a s a -> a
^. Getting Pointer State Pointer
Lens' State Pointer
current)

getList :: State -> Maybe L.List
getList :: State -> Maybe List
getList State
state = Lists -> Int -> Maybe List
Lists.get (State
state State -> Getting Lists State Lists -> Lists
forall s a. s -> Getting a s a -> a
^. Getting Lists State Lists
Lens' State Lists
lists) (State -> Int
getCurrentList State
state)

setList :: State -> L.List -> State
setList :: State -> List -> State
setList State
state List
list = State -> Lists -> State
setLists State
state (Int -> List -> Update
Lists.updateLists (State -> Int
getCurrentList State
state) List
list (State
state State -> Getting Lists State Lists -> Lists
forall s a. s -> Getting a s a -> a
^. Getting Lists State Lists
Lens' State Lists
lists))

setCurrentListTitle :: Text -> Stateful
setCurrentListTitle :: Text -> Stateful
setCurrentListTitle Text
text State
state = State -> List -> State
setList State
state (List -> State) -> (List -> List) -> List -> State
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. ((Text -> Identity Text) -> List -> Identity List
Lens' List Text
L.title ((Text -> Identity Text) -> List -> Identity List)
-> Text -> List -> List
forall s t a b. ASetter s t a b -> b -> s -> t
.~ Text
text) (List -> State) -> Maybe List -> Maybe State
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> State -> Maybe List
getList State
state

setLists :: State -> Lists.Lists -> State
setLists :: State -> Lists -> State
setLists State
state Lists
lists' = State
state State -> (State -> State) -> State
forall a b. a -> (a -> b) -> b
& (Lists -> Identity Lists) -> State -> Identity State
Lens' State Lists
lists ((Lists -> Identity Lists) -> State -> Identity State)
-> Lists -> State -> State
forall s t a b. ASetter s t a b -> b -> s -> t
.~ Lists
lists'

moveTo' :: Int -> Stateful
moveTo' :: Int -> Stateful
moveTo' Int
li State
state = do
    let cur :: Int
cur = State -> Int
getCurrentList State
state
    if Int
li Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
cur Bool -> Bool -> Bool
|| Int
li Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 Bool -> Bool -> Bool
|| Int
li Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Lists -> Int
forall mono. MonoFoldable mono => mono -> Int
length (State
state State -> Getting Lists State Lists -> Lists
forall s a. s -> Getting a s a -> a
^. Getting Lists State Lists
Lens' State Lists
lists)
        then Maybe State
forall a. Maybe a
Nothing
        else do
            State
s <- Int -> ListPosition -> Stateful
moveHorizontal (Int
li Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
cur) ListPosition
Lists.Bottom State
state
            Stateful
forall (f :: * -> *) a. Applicative f => a -> f a
pure Stateful -> (State -> State) -> Stateful
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. State -> State
selectLast Stateful -> Stateful
forall a b. (a -> b) -> a -> b
$ State -> Int -> State
setCurrentList State
s Int
li

moveTo :: Char -> Stateful
moveTo :: Char -> Stateful
moveTo Char
char = Int -> Stateful
moveTo' (Char -> Int
ord Char
char Int -> Int -> Int
forall a. Num a => a -> a -> a
- Char -> Int
ord Char
'a')

-- move lists
listMove :: Int -> Stateful
listMove :: Int -> Stateful
listMove Int
offset State
state = do
    let currentList :: Int
currentList = State -> Int
getCurrentList State
state
    let lists' :: Lists
lists' = State
state State -> Getting Lists State Lists -> Lists
forall s a. s -> Getting a s a -> a
^. Getting Lists State Lists
Lens' State Lists
lists
    if Int
currentList Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
offset Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 Bool -> Bool -> Bool
|| Int
currentList Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
offset Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Lists -> Int
forall mono. MonoFoldable mono => mono -> Int
length Lists
lists'
        then Maybe State
forall a. Maybe a
Nothing
        else do
            let state' :: State
state' = State -> State
fixIndex (State -> State) -> State -> State
forall a b. (a -> b) -> a -> b
$ State -> Int -> State
setCurrentList State
state (Int
currentList Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
offset)
            State -> Lists -> State
setLists State
state' (Lists -> State) -> Maybe Lists -> Maybe State
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Int -> Lists -> Maybe Lists
Lists.shiftBy Int
currentList Int
offset Lists
lists'

listLeft :: Stateful
listLeft :: Stateful
listLeft = Int -> Stateful
listMove (-Int
1)

listRight :: Stateful
listRight :: Stateful
listRight = Int -> Stateful
listMove Int
1

-- search
searchMode :: Stateful
searchMode :: Stateful
searchMode State
state = Stateful
forall (f :: * -> *) a. Applicative f => a -> f a
pure Stateful -> (State -> State) -> Stateful
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. State -> State
fixIndex Stateful -> Stateful
forall a b. (a -> b) -> a -> b
$ (State
state State -> (State -> State) -> State
forall a b. a -> (a -> b) -> b
& (Mode -> Identity Mode) -> State -> Identity State
Lens' State Mode
mode ((Mode -> Identity Mode) -> State -> Identity State)
-> Mode -> State -> State
forall s t a b. ASetter s t a b -> b -> s -> t
.~ Mode
Search) State -> (State -> State) -> State
forall a b. a -> (a -> b) -> b
& (Maybe Field -> Identity (Maybe Field)) -> State -> Identity State
Lens' State (Maybe Field)
searchTerm ((Maybe Field -> Identity (Maybe Field))
 -> State -> Identity State)
-> Maybe Field -> State -> State
forall s t a b. ASetter s t a b -> b -> s -> t
.~ Maybe Field
sTerm
  where
    sTerm :: Maybe Field
sTerm = Field -> Maybe Field
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Field -> Maybe Field -> Field
forall a. a -> Maybe a -> a
fromMaybe Field
blankField (State
state State -> Getting (Maybe Field) State (Maybe Field) -> Maybe Field
forall s a. s -> Getting a s a -> a
^. Getting (Maybe Field) State (Maybe Field)
Lens' State (Maybe Field)
searchTerm))

clearSearch :: Stateful
clearSearch :: Stateful
clearSearch State
state = Stateful
forall (f :: * -> *) a. Applicative f => a -> f a
pure Stateful -> Stateful
forall a b. (a -> b) -> a -> b
$ State
state State -> (State -> State) -> State
forall a b. a -> (a -> b) -> b
& (Maybe Field -> Identity (Maybe Field)) -> State -> Identity State
Lens' State (Maybe Field)
searchTerm ((Maybe Field -> Identity (Maybe Field))
 -> State -> Identity State)
-> Maybe Field -> State -> State
forall s t a b. ASetter s t a b -> b -> s -> t
.~ Maybe Field
forall a. Maybe a
Nothing

appendSearch :: (Field -> Field) -> Stateful
appendSearch :: (Field -> Field) -> Stateful
appendSearch Field -> Field
genField State
state = do
    let field :: Field
field = Field -> Maybe Field -> Field
forall a. a -> Maybe a -> a
fromMaybe Field
blankField (State
state State -> Getting (Maybe Field) State (Maybe Field) -> Maybe Field
forall s a. s -> Getting a s a -> a
^. Getting (Maybe Field) State (Maybe Field)
Lens' State (Maybe Field)
searchTerm)
    Stateful
forall (f :: * -> *) a. Applicative f => a -> f a
pure Stateful -> (State -> State) -> Stateful
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. State -> State
fixIndex Stateful -> Stateful
forall a b. (a -> b) -> a -> b
$ State
state State -> (State -> State) -> State
forall a b. a -> (a -> b) -> b
& (Maybe Field -> Identity (Maybe Field)) -> State -> Identity State
Lens' State (Maybe Field)
searchTerm ((Maybe Field -> Identity (Maybe Field))
 -> State -> Identity State)
-> Maybe Field -> State -> State
forall s t a b. ASetter s t a b -> b -> s -> t
.~ Field -> Maybe Field
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Field -> Field
genField Field
field)

-- help
showHelp :: Stateful
showHelp :: Stateful
showHelp = Stateful
forall (f :: * -> *) a. Applicative f => a -> f a
pure Stateful -> (State -> State) -> Stateful
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. ((Mode -> Identity Mode) -> State -> Identity State
Lens' State Mode
mode ((Mode -> Identity Mode) -> State -> Identity State)
-> Mode -> State -> State
forall s t a b. ASetter s t a b -> b -> s -> t
.~ ModalType -> Mode
Modal ModalType
Help)

showMoveTo :: Stateful
showMoveTo :: Stateful
showMoveTo State
state = State -> Task -> State
forall a b. a -> b -> a
const (State
state State -> (State -> State) -> State
forall a b. a -> (a -> b) -> b
& (Mode -> Identity Mode) -> State -> Identity State
Lens' State Mode
mode ((Mode -> Identity Mode) -> State -> Identity State)
-> Mode -> State -> State
forall s t a b. ASetter s t a b -> b -> s -> t
.~ ModalType -> Mode
Modal ModalType
MoveTo) (Task -> State) -> Maybe Task -> Maybe State
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> State -> Maybe Task
getCurrentTask State
state

-- view
setHeight :: Int -> State -> State
setHeight :: Int -> State -> State
setHeight = ASetter State State Int Int -> Int -> State -> State
forall s t a b. ASetter s t a b -> b -> s -> t
(.~) ASetter State State Int Int
Lens' State Int
height

-- more view - maybe shouldn't be in here...
newList :: State -> State
newList :: State -> State
newList State
state =
    case State
state State -> Getting Mode State Mode -> Mode
forall s a. s -> Getting a s a -> a
^. Getting Mode State Mode
Lens' State Mode
mode of
        Insert InsertType
IList InsertMode
ICreate Field
f ->
            let ls :: Lists
ls = State
state State -> Getting Lists State Lists -> Lists
forall s a. s -> Getting a s a -> a
^. Getting Lists State Lists
Lens' State Lists
lists
            in State -> State
fixIndex (State -> State) -> State -> State
forall a b. (a -> b) -> a -> b
$ State -> Int -> State
setCurrentList (State -> Lists -> State
setLists State
state (Text -> Update
Lists.newList (Field -> Text
getText Field
f) Lists
ls)) (Lists -> Int
forall mono. MonoFoldable mono => mono -> Int
length Lists
ls)
        Mode
_ -> State
state

normalise :: State -> State
normalise :: State -> State
normalise = State -> State
newList