-- 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 Editors exposing
    ( Editor(..)
    , Model
    , Msg
    , decode
    , encode
    , init
    , initCmd
    , update
    , view
    )

{-| This module implements the input/output editors.

Input and output editors are not independent. Anything to do with an output mode
-- its active/nonactive state, its content, its options -- is always relative to
an input mode. For example, FIDL Text -> Bytes and Bytes -> Bytes have distinct
output state even though both are Bytes.

This module does not keep track of the Ace editor state. That is done in
JavaScript-land because it's easier there.

-}

import Form exposing (Form)
import Html exposing (Html)
import Html.Attributes as Attributes
import Html.Events as Events
import Json.Decode as Decode
import Json.Encode as Encode
import Mode exposing (Mode)
import Ports



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


type alias Model =
    { activeInput : Mode
    , inputMap : Mode.Map InputState
    }


type alias InputState =
    { activeOutput : Mode
    , outputMap : Mode.Map OutputState
    }


type alias OutputState =
    { options : Options
    }


type alias Options =
    Form.Model


type alias Active =
    { input : Mode
    , output : Mode
    , options : Options
    }


init : Model
init =
    let
        input =
            Mode.defaultInput

        inputState =
            defaultInputState input
    in
    { activeInput = input
    , inputMap = Mode.singleton input inputState
    }


initCmd : Model -> Cmd msg
initCmd model =
    updateEditors (getActive model)


defaultInputState : Mode -> InputState
defaultInputState input =
    let
        output =
            Mode.defaultOutput input

        outputState =
            defaultOutputState input output
    in
    { activeOutput = output
    , outputMap = Mode.singleton output outputState
    }


defaultOutputState : Mode -> Mode -> OutputState
defaultOutputState input output =
    { options = Form.empty }


getInputState : Mode -> Model -> InputState
getInputState input model =
    Maybe.withDefault
        (defaultInputState input)
        (Mode.get input model.inputMap)


getOutputState : Mode -> Mode -> InputState -> OutputState
getOutputState input output inputState =
    Maybe.withDefault
        (defaultOutputState input output)
        (Mode.get output inputState.outputMap)


getActive : Model -> Active
getActive model =
    let
        input =
            model.activeInput

        inputState =
            getInputState input model

        output =
            inputState.activeOutput

        outputState =
            getOutputState input output inputState

        options =
            outputState.options
    in
    Active input output options



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


type Msg
    = NoOp
    | -- Switch to this input mode. This also implies switching to a new output
      -- mode (the one that was most recently used for that input).
      ActivateInput Mode
      -- Switch to this output mode, keeping the same input mode.
    | ActivateOutput Mode
      -- Update options for the current input/output mode combination.
    | UpdateOptions Form.Msg


update : Msg -> Model -> ( Model, Cmd msg )
update msg model =
    let
        newModel =
            case msg of
                NoOp ->
                    model

                ActivateInput input ->
                    activateInput input model

                ActivateOutput output ->
                    activateOutput output model

                UpdateOptions formMsg ->
                    updateOptions (Form.update formMsg) model

        cmd =
            case msg of
                NoOp ->
                    Cmd.none

                _ ->
                    updateEditors (getActive newModel)
    in
    ( newModel, cmd )


activateInput : Mode -> Model -> Model
activateInput input model =
    let
        inputState =
            getInputState input model

        newInputMap =
            model.inputMap |> Mode.insert input inputState
    in
    { model | activeInput = input, inputMap = newInputMap }


activateOutput : Mode -> Model -> Model
activateOutput output model =
    let
        input =
            model.activeInput

        inputState =
            getInputState input model

        outputState =
            getOutputState input output inputState

        newOutputMap =
            inputState.outputMap |> Mode.insert output outputState

        newInputState =
            { inputState | activeOutput = output, outputMap = newOutputMap }

        newInputMap =
            model.inputMap |> Mode.insert input newInputState
    in
    { model | inputMap = newInputMap }


updateOptions : (Options -> Options) -> Model -> Model
updateOptions alter model =
    let
        input =
            model.activeInput

        inputState =
            getInputState input model

        output =
            inputState.activeOutput

        outputState =
            getOutputState input output inputState

        newOutputState =
            { options = alter outputState.options }

        newOutputMap =
            inputState.outputMap |> Mode.insert output newOutputState

        newInputState =
            { inputState | outputMap = newOutputMap }

        newInputMap =
            model.inputMap |> Mode.insert input newInputState
    in
    { model | inputMap = newInputMap }


updateEditors : Active -> Cmd msg
updateEditors active =
    Ports.updateEditors
        (Mode.encode active.input)
        (Mode.encode active.output)
        (Form.encodeEffective
            (Mode.options active.input active.output)
            active.options
        )



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


type Editor
    = Input
    | Output


view : Editor -> (Msg -> msg) -> String -> Model -> Html msg
view editor toMsg themeClass model =
    let
        active =
            getActive model

        { modes, activeMode, msg, id, optionsPart } =
            case editor of
                Input ->
                    { modes = Mode.inputs
                    , activeMode = active.input
                    , msg = ActivateInput
                    , id = "InputEditor"
                    , optionsPart = []
                    }

                Output ->
                    let
                        form =
                            Mode.options active.input active.output
                    in
                    { modes = Mode.outputs active.input
                    , activeMode = active.output
                    , msg = ActivateOutput
                    , id = "OutputEditor"
                    , optionsPart =
                        if List.isEmpty form.inputs then
                            []

                        else
                            [ optionsView form active.options toMsg ]
                    }

        navbarPart =
            navbarView modes activeMode (toMsg << msg) themeClass

        editorPart =
            Html.div
                [ Attributes.id id
                , Attributes.class "editor"
                ]
                []
    in
    Html.div
        [ Attributes.class "editor-wrapper"
        , Events.on "keydown" (keyDownEvent editor active toMsg)
        ]
        (navbarPart :: editorPart :: optionsPart)


navbarView : List Mode -> Mode -> (Mode -> msg) -> String -> Html msg
navbarView modes activeMode msg themeClass =
    let
        navItem mode =
            -- We provide keyboard shortcuts on the parent div to navigate
            -- between modes. This replaces tab navigation, hence tabindex -1.
            -- We need to use button tags so that they can be focused and the
            -- parent div will receive keyboard events.
            Html.button
                [ Attributes.type_ "button"
                , Attributes.tabindex -1
                , Attributes.class "navbar-item"
                , if mode == activeMode then
                    Attributes.class ("navbar-item--active " ++ themeClass)

                  else
                    Events.onClick (msg mode)
                ]
                [ Html.text (Mode.title mode) ]
    in
    Html.div
        [ Attributes.class "navbar" ]
        (List.map navItem modes)


optionsView : Form -> Form.Model -> (Msg -> msg) -> Html msg
optionsView form options toMsg =
    Html.div
        [ Attributes.class "editor-options" ]
        [ Form.view
            form
            []
            (toMsg << UpdateOptions)
            options
        ]


keyDownEvent : Editor -> Active -> (Msg -> msg) -> Decode.Decoder msg
keyDownEvent editor active toMsg =
    let
        ( activate, previous, next ) =
            case editor of
                Input ->
                    ( ActivateInput
                    , Mode.previousInput active.input
                    , Mode.nextInput active.input
                    )

                Output ->
                    ( ActivateOutput
                    , Mode.previousOutput active.input active.output
                    , Mode.nextOutput active.input active.output
                    )

        chooseMsg ctrl key =
            if ctrl && key == "[" then
                activate previous

            else if ctrl && key == "]" then
                activate next

            else
                NoOp
    in
    Decode.map toMsg <|
        Decode.map2 chooseMsg
            (Decode.field "ctrlKey" Decode.bool)
            (Decode.field "key" Decode.string)



------------- ENCODE / DECODE --------------------------------------------------


encode : Model -> Encode.Value
encode model =
    Encode.object
        [ ( "activeInput", Mode.encode model.activeInput )
        , ( "inputMap", Mode.encodeMap encodeInputState model.inputMap )
        ]


encodeInputState : InputState -> Encode.Value
encodeInputState inputState =
    Encode.object
        [ ( "activeOutput", Mode.encode inputState.activeOutput )
        , ( "outputMap", Mode.encodeMap encodeOutputState inputState.outputMap )
        ]


encodeOutputState : OutputState -> Encode.Value
encodeOutputState outputState =
    Encode.object
        [ ( "options", Form.encode outputState.options ) ]


decode : Decode.Decoder Model
decode =
    Decode.map2 Model
        (Decode.field "activeInput" Mode.decode)
        (Decode.field "inputMap" (Mode.decodeMap decodeInputState))


decodeInputState : Decode.Decoder InputState
decodeInputState =
    Decode.map2 InputState
        (Decode.field "activeOutput" Mode.decode)
        (Decode.field "outputMap" (Mode.decodeMap decodeOutputState))


decodeOutputState : Decode.Decoder OutputState
decodeOutputState =
    Decode.map OutputState
        (Decode.field "options" Form.decode)
