module Taskell.Events.State.Modal.Due
    ( showDue
    , clearDate
    , previous
    , next
    , goto
    ) where

import ClassyPrelude

import Control.Lens  ((&), (.~), (^.))
import Data.Sequence ((!?))

import qualified Taskell.Data.Lists              as L (clearDue, due)
import           Taskell.Data.Seq                (bound)
import           Taskell.Data.Task               (Task)
import           Taskell.Events.State.Types      (Stateful, current, lists, mode)
import           Taskell.Events.State.Types.Mode (ModalType (Due), Mode (..))
import           Taskell.Types                   (Pointer)

type DueStateful = Seq (Pointer, Task) -> Int -> Stateful

λfilter :: DueStateful -> Stateful
λfilter :: DueStateful -> Stateful
λfilter DueStateful
fn 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
        Modal (Due Seq (Pointer, Task)
due Int
cur) -> DueStateful
fn Seq (Pointer, Task)
due Int
cur State
state
        Mode
_                   -> Stateful
forall (f :: * -> *) a. Applicative f => a -> f a
pure State
state

λsetMode :: DueStateful
λsetMode :: DueStateful
λsetMode Seq (Pointer, Task)
due Int
pos 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
.~ ModalType -> Mode
Modal (Seq (Pointer, Task) -> Int -> ModalType
Due Seq (Pointer, Task)
due Int
pos)

λprevious :: DueStateful
λprevious :: DueStateful
λprevious Seq (Pointer, Task)
due Int
cur = DueStateful
λsetMode Seq (Pointer, Task)
due (Seq (Pointer, Task) -> Int -> Int
forall a. Seq a -> Int -> Int
bound Seq (Pointer, Task)
due (Int
cur Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1))

λnext :: DueStateful
λnext :: DueStateful
λnext Seq (Pointer, Task)
due Int
cur = DueStateful
λsetMode Seq (Pointer, Task)
due (Seq (Pointer, Task) -> Int -> Int
forall a. Seq a -> Int -> Int
bound Seq (Pointer, Task)
due (Int
cur Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1))

λgoto :: DueStateful
λgoto :: DueStateful
λgoto Seq (Pointer, Task)
due Int
cur State
state =
    case Seq (Pointer, Task)
due Seq (Pointer, Task) -> Int -> Maybe (Pointer, Task)
forall a. Seq a -> Int -> Maybe a
!? Int
cur of
        Just (Pointer
pointer, Task
_) -> 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
& (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
.~ Pointer
pointer
        Maybe (Pointer, Task)
Nothing           -> Maybe State
forall a. Maybe a
Nothing

λclearDate :: DueStateful
λclearDate :: DueStateful
λclearDate Seq (Pointer, Task)
due Int
cur State
state =
    case Seq (Pointer, Task)
due Seq (Pointer, Task) -> Int -> Maybe (Pointer, Task)
forall a. Seq a -> Int -> Maybe a
!? Int
cur of
        Just (Pointer
pointer, Task
_) -> do
            let new :: Lists
new = Pointer -> Update
L.clearDue Pointer
pointer (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)
            let dues :: Seq (Pointer, Task)
dues = Lists -> Seq (Pointer, Task)
L.due Lists
new
            DueStateful
λsetMode Seq (Pointer, Task)
dues (Seq (Pointer, Task) -> Int -> Int
forall a. Seq a -> Int -> Int
bound Seq (Pointer, Task)
dues Int
cur) (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
new)
        Maybe (Pointer, Task)
Nothing -> Maybe State
forall a. Maybe a
Nothing

showDue :: Stateful
showDue :: Stateful
showDue State
state = DueStateful
λsetMode (Lists -> Seq (Pointer, Task)
L.due (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
0 State
state

previous :: Stateful
previous :: Stateful
previous = DueStateful -> Stateful
λfilter DueStateful
λprevious

next :: Stateful
next :: Stateful
next = DueStateful -> Stateful
λfilter DueStateful
λnext

goto :: Stateful
goto :: Stateful
goto = DueStateful -> Stateful
λfilter DueStateful
λgoto

clearDate :: Stateful
clearDate :: Stateful
clearDate = DueStateful -> Stateful
λfilter DueStateful
λclearDate