about summary refs log tree commit diff
path: root/users/wpcarro/website/sandbox/learnpianochords/src/State.elm
diff options
context:
space:
mode:
Diffstat (limited to 'users/wpcarro/website/sandbox/learnpianochords/src/State.elm')
-rw-r--r--users/wpcarro/website/sandbox/learnpianochords/src/State.elm179
1 files changed, 179 insertions, 0 deletions
diff --git a/users/wpcarro/website/sandbox/learnpianochords/src/State.elm b/users/wpcarro/website/sandbox/learnpianochords/src/State.elm
new file mode 100644
index 0000000000..678fb0f9aa
--- /dev/null
+++ b/users/wpcarro/website/sandbox/learnpianochords/src/State.elm
@@ -0,0 +1,179 @@
+module State exposing (..)
+
+import Random
+import Random.List
+import Theory
+
+
+type Msg
+    = NextChord
+    | NewChord Theory.Chord
+    | Play
+    | Pause
+    | SetTempo String
+    | ToggleInversion Theory.ChordInversion
+    | ToggleKey Theory.Key
+    | DoNothing
+    | SetView View
+    | ToggleFlashCard
+
+
+type View
+    = Preferences
+    | Practice
+    | Overview
+
+
+type alias Model =
+    { whitelistedChords : List Theory.Chord
+    , whitelistedChordTypes : List Theory.ChordType
+    , whitelistedInversions : List Theory.ChordInversion
+    , whitelistedPitchClasses : List Theory.PitchClass
+    , whitelistedKeys : List Theory.Key
+    , selectedChord : Maybe Theory.Chord
+    , isPaused : Bool
+    , tempo : Int
+    , firstNote : Theory.Note
+    , lastNote : Theory.Note
+    , view : View
+    , showFlashCard : Bool
+    }
+
+
+{-| The initial state for the application.
+-}
+init : Model
+init =
+    let
+        ( firstNote, lastNote ) =
+            ( Theory.C3, Theory.C6 )
+
+        inversions =
+            [ Theory.Root ]
+
+        chordTypes =
+            Theory.allChordTypes
+
+        pitchClasses =
+            Theory.allPitchClasses
+
+        keys =
+            [ { pitchClass = Theory.C, mode = Theory.MajorMode } ]
+    in
+    { whitelistedChords =
+        keys
+            |> List.concatMap Theory.chordsForKey
+            |> List.filter (\chord -> List.member chord.chordInversion inversions)
+    , whitelistedChordTypes = chordTypes
+    , whitelistedInversions = inversions
+    , whitelistedPitchClasses = pitchClasses
+    , whitelistedKeys = keys
+    , selectedChord = Nothing
+    , isPaused = True
+    , tempo = 10
+    , firstNote = firstNote
+    , lastNote = lastNote
+    , view = Overview
+    , showFlashCard = True
+    }
+
+
+{-| Now that we have state, we need a function to change the state.
+-}
+update : Msg -> Model -> ( Model, Cmd Msg )
+update msg model =
+    case msg of
+        DoNothing ->
+            ( model, Cmd.none )
+
+        SetView x ->
+            ( { model
+                | view = x
+                , isPaused = True
+              }
+            , Cmd.none
+            )
+
+        NewChord chord ->
+            ( { model | selectedChord = Just chord }
+            , Cmd.none
+            )
+
+        NextChord ->
+            ( model
+            , Random.generate
+                (\x ->
+                    case x of
+                        ( Just chord, _ ) ->
+                            NewChord chord
+
+                        ( Nothing, _ ) ->
+                            DoNothing
+                )
+                (Random.List.choose model.whitelistedChords)
+            )
+
+        Play ->
+            ( { model | isPaused = False }
+            , Cmd.none
+            )
+
+        Pause ->
+            ( { model | isPaused = True }
+            , Cmd.none
+            )
+
+        ToggleInversion inversion ->
+            let
+                inversions =
+                    if List.member inversion model.whitelistedInversions then
+                        List.filter ((/=) inversion) model.whitelistedInversions
+
+                    else
+                        inversion :: model.whitelistedInversions
+            in
+            ( { model
+                | whitelistedInversions = inversions
+                , whitelistedChords =
+                    model.whitelistedKeys
+                        |> List.concatMap Theory.chordsForKey
+                        |> List.filter (\chord -> List.member chord.chordInversion inversions)
+              }
+            , Cmd.none
+            )
+
+        ToggleKey key ->
+            let
+                keys =
+                    if List.member key model.whitelistedKeys then
+                        List.filter ((/=) key) model.whitelistedKeys
+
+                    else
+                        key :: model.whitelistedKeys
+            in
+            ( { model
+                | whitelistedKeys = keys
+                , whitelistedChords =
+                    keys
+                        |> List.concatMap Theory.chordsForKey
+                        |> List.filter (\chord -> List.member chord.chordInversion model.whitelistedInversions)
+                , selectedChord = Nothing
+              }
+            , Cmd.none
+            )
+
+        SetTempo tempo ->
+            ( { model
+                | tempo =
+                    case String.toInt tempo of
+                        Just x ->
+                            x
+
+                        Nothing ->
+                            model.tempo
+              }
+            , Cmd.none
+            )
+
+        ToggleFlashCard ->
+            ( { model | showFlashCard = not model.showFlashCard }, Cmd.none )