<commit_before>module Main where

import Control.Monad.Aff (delay)
import Control.Monad.Aff.Console (CONSOLE, logShow)
import Control.Monad.Eff (Eff)
import Control.Monad.Eff.Class (liftEff)
import Control.Monad.Eff.Random (RANDOM)
import Data.Helpers (generateSequence, convertToColors)
import Data.List (List(..), snoc)
import Data.Maybe (Maybe(..))
import Data.Styles (buttonStyled)
import Data.Time.Duration (Milliseconds(..))
import Data.Sounds (play, SOUND)
import DOM (DOM)
import Prelude hiding (div, id)
import Pux (CoreEffects, EffModel, noEffects, start)
import Pux.DOM.Events (DOMEvent, onChange, onClick)
import Pux.DOM.HTML (HTML)
import Pux.Renderer.React (renderToDOM)
import Text.Smolder.HTML (button, div, input, label)
import Text.Smolder.HTML.Attributes (type', checked)
import Text.Smolder.Markup (text, (#!), (!), (!?))


data Event 
  = Start 
  | NewSequence (List String) 
  | UserClick String 
  | ResetColor 
  | Strict DOMEvent

type AppEffects = (random :: RANDOM, console :: CONSOLE, dom :: DOM, sound :: SOUND)

type State = 
  { sequence :: List String
  , userInput :: List String
  , currentColor :: String
  , count :: Int
  , strict :: Boolean
  }

init :: State
init = 
  { sequence: Nil
  , userInput: Nil
  , currentColor: ""
  , count : 0
  , strict: false
  }

foldp :: Event -> State -> EffModel State Event AppEffects
foldp Start state = 
  { state: state
  , effects: [ do
      result <- liftEff generateSequence
      let colors = convertToColors result
      pure $ Just $ NewSequence colors
    ]
  }
foldp (NewSequence list) state = 
  { state: state { sequence = list }
  , effects: [ logShow list *> pure Nothing ]
  }
foldp (UserClick color) state = 
  { state: state { userInput = snoc state.userInput color, currentColor = color }
  , effects: 
      [ logShow (snoc state.userInput color) *> pure Nothing
      , liftEff $ play color *> pure Nothing
      , (delay $ Milliseconds 300.0) *> (pure $ Just $ ResetColor)
    ]
  }
foldp ResetColor state = noEffects $ state { currentColor = "" } 
foldp (Strict e) state = noEffects $ state { strict = not state.strict }


view :: State -> HTML Event
view state =
  div do
    div do
      div
        ! buttonStyled "red" state.currentColor 
        #! onClick (const $ UserClick "red")
        $ text ""
      div 
        ! buttonStyled "green" state.currentColor
        #! onClick (const $ UserClick "green")
        $ text ""
      div 
        ! buttonStyled "yellow" state.currentColor
        #! onClick (const $ UserClick "yellow")
        $ text ""
      div 
        ! buttonStyled "blue" state.currentColor
        #! onClick (const $ UserClick "blue")
        $ text ""
    div do
      label $ text "Strict"
      (input !? state.strict) (checked "checked") ! type' "checkbox" #! onChange Strict 
    button #! onClick (const Start) $ text "Start"

main :: Eff (CoreEffects AppEffects) Unit
main = do
  app <- start
    { initialState: init
    , view
    , foldp
    , inputs: []
    }<commit_msg>Still figuring out how to do a setTimeout<commit_after>module Main where

import Control.Monad.Aff (delay)
import Control.Monad.Aff.Console (CONSOLE)
import Control.Monad.Eff (Eff)
import Control.Monad.Eff.Class (liftEff)
import Control.Monad.Eff.Random (RANDOM)
import DOM (DOM)
import Data.Array (fromFoldable)
import Data.Helpers (generateSequence, convertToColors)
import Data.List (List(..), snoc, index, range)
import Data.Maybe (Maybe(..), fromMaybe)
import Data.Sounds (play, SOUND)
import Data.Styles (buttonStyled)
import Data.Time.Duration (Milliseconds(..))
import Prelude hiding (div,id)
import Pux (CoreEffects, EffModel, noEffects, onlyEffects, start)
import Pux.DOM.Events (DOMEvent, onChange, onClick)
import Pux.DOM.HTML (HTML)
import Pux.Renderer.React (renderToDOM)
import Text.Smolder.HTML (button, div, input, label)
import Text.Smolder.HTML.Attributes (type', checked)
import Text.Smolder.Markup (text, (#!), (!), (!?))


data Event 
  = Start
  | AnimateColor Number String
  | NewSequence (List String)
  | PlaySequence
  | UserClick String
  | ResetColor
  | Strict DOMEvent

type AppEffects = (random :: RANDOM, console :: CONSOLE, dom :: DOM, sound :: SOUND)

type State = 
  { sequence :: List String
  , userInput :: List String
  , currentColor :: String
  , count :: Int
  , strict :: Boolean
  }

init :: State
init = 
  { sequence: Nil
  , userInput: Nil
  , currentColor: ""
  , count : 0
  , strict: false
  }

generatePlaySequence :: forall e. Applicative e => Int -> List String -> Array (e (Maybe Event))
generatePlaySequence count sequence =
  range 0 (count - 1) #
  map (\v -> pure $ Just $ AnimateColor 300.0 (fromMaybe "" $ index sequence v) ) #
  fromFoldable

foldp :: Event -> State -> EffModel State Event AppEffects
foldp Start state = 
  if state.count > 0 then
    noEffects $ state
  else 
  { state: state { count = state.count + 1 }
  , effects: 
      [ do
          result <- liftEff generateSequence
          let colors = convertToColors result
          pure $ Just $ NewSequence colors
      ]
  }

foldp (NewSequence list) state =
  { state: state { sequence = list }
  , effects: [pure $ Just $ PlaySequence]
  }

foldp (UserClick color) state =
  { state: state { userInput = snoc state.userInput color, currentColor = color }
  , effects: [ pure $ Just $ AnimateColor 300.0 color ]
  }
foldp ResetColor state = noEffects $ state { currentColor = "" }

foldp (AnimateColor time color) state =
  { state: state { currentColor = color },
    effects: 
      [ liftEff $ play color *> pure Nothing
      , do 
        delay $ Milliseconds time
        pure $ Just $ ResetColor
      ]
  }

foldp PlaySequence state =
  onlyEffects state $ generatePlaySequence state.count state.sequence

foldp (Strict e) state = noEffects $ state { strict = not state.strict }


view :: State -> HTML Event
view state =
  div do
    div do
      div
        ! buttonStyled "red" state.currentColor 
        #! onClick (const $ UserClick "red")
        $ text ""
      div 
        ! buttonStyled "green" state.currentColor
        #! onClick (const $ UserClick "green")
        $ text ""
      div 
        ! buttonStyled "yellow" state.currentColor
        #! onClick (const $ UserClick "yellow")
        $ text ""
      div 
        ! buttonStyled "blue" state.currentColor
        #! onClick (const $ UserClick "blue")
        $ text ""
    div do
      text $ "Count" <> show state.count
    div do
      label $ text "Strict"
      (input !? state.strict) (checked "checked") ! type' "checkbox" #! onChange Strict 
    button #! onClick (const Start) $ text "Start"

main :: Eff (CoreEffects AppEffects) Unit
main = do
  app <- start
    { initialState: init
    , view
    , foldp
    , inputs: []
    }
{'fraction_non_alphanumeric': 0.11483890038427431, 'fraction_numerical': 0.0026603606266627253, 'mean_word_length': 2.961943793911007, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 20, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '292733', 'n_tokens_mistral': 2134, 'n_tokens_neox': 2073, 'n_words': 653}