-- Copyright 2020 The Fuchsia Authors. All rights reserved.
-- Use of this source code is governed by a BSD-style license that can be
-- found in the LICENSE file.


module Window exposing
    ( Model
    , Msg(..)
    , init
    , isAbsent
    , subscriptions
    , update
    , view
    )

{-| This module implements modal windows.

A modal window is a window placed on top of the main app content (which is
dimmed and disabled). The user can dismiss the window by clicking anywhere
outside it, or pressing Escape or Return.

-}

import Browser.Events
import Html exposing (Html)
import Html.Attributes as Attributes
import Html.Events as Events
import Json.Decode as Decode



------------- MODEL ------------------------------------------------------------


type alias Model a =
    Maybe a


init : Model a
init =
    Nothing


isAbsent : Model a -> Bool
isAbsent model =
    case model of
        Just _ ->
            False

        Nothing ->
            True



------------- UPDATE -----------------------------------------------------------


type Msg a
    = NoOp
    | Show a
    | Hide


update : Msg a -> Model a -> Model a
update msg model =
    case msg of
        NoOp ->
            model

        Show window ->
            Just window

        Hide ->
            Nothing



------------- SUBSCRIPTIONS ----------------------------------------------------


subscriptions : Model a -> Sub (Msg a)
subscriptions model =
    case model of
        Just _ ->
            Browser.Events.onKeyDown keyDownEvent

        _ ->
            Sub.none


keyDownEvent : Decode.Decoder (Msg a)
keyDownEvent =
    Decode.field "key" Decode.string
        |> Decode.map
            (\key ->
                -- For the Help window, catching Enter here is redundant because
                -- the focus will still be on the button, and pressing enter
                -- again will click it and hide the window. But for the Settings
                -- window it is needed since focus might be on a form input. The
                -- toggle behavior on the button is still useful so that
                -- spacebar hides the window when the button is still focused.
                if key == "Enter" || key == "Escape" then
                    Hide

                else
                    NoOp
            )



------------- VIEW -------------------------------------------------------------


view : (a -> Html msg) -> (Msg a -> msg) -> Model a -> Html msg
view windowView toMsg model =
    case model of
        Nothing ->
            Html.text ""

        Just window ->
            Html.div
                [ Attributes.class "modal-container"
                , Events.onClick (toMsg Hide)
                ]
                [ Html.div
                    [ Attributes.id modalBoxId
                    , Attributes.class "modal-box"

                    -- Prevent clicking the box itself from hiding it.
                    , Events.stopPropagationOn "click"
                        (Decode.succeed ( toMsg NoOp, True ))
                    ]
                    [ windowView window ]
                ]


modalBoxId : String
modalBoxId =
    "ModalBox"
