module Main exposing (main)

import Browser exposing (Document)
import Html exposing (Html)
import Html.Attributes exposing (style)
import Html.Events exposing (onClick)
import Particle exposing (Particle)
import Particle.System as System exposing (System)
import Random exposing (Generator)
import Random.Extra
import Random.Float exposing (normal)
import Svg exposing (Svg)
import Svg.Attributes as SAttrs


type Firework
    = Dot
    | Line Int


firework : Generator Firework
firework =
    Random.Extra.frequency
        ( 1 / 8, Random.map (Line << max 3 << floor) (normal 15 6) )
        [ ( 7 / 8, Random.constant Dot ) ]


type alias Model =
    System Firework


type Msg
    = ParticleMsg (System.Msg Firework)
    | Detonate


update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        ParticleMsg inner ->
            ( System.update inner model, Cmd.none )

        Detonate ->
            ( System.burst
                (Particle.init firework
                    |> Particle.withLocation (Random.constant { x = 150, y = 300 })
                    |> Particle.withDirection (normal 0 (degrees 15))
                    |> Particle.withSpeed (normal 500 100)
                    |> Particle.withLifetime (Random.constant 1)
                    |> Particle.withGravity 100
                    |> Particle.withDrag
                        (\_ ->
                            { coefficient = 1
                            , density = 0.001226
                            , area = 3
                            }
                        )
                    |> Random.list 100
                )
                model
            , Cmd.none
            )


view : Model -> Html Msg
view model =
    Html.main_ []
        [ Html.button
            [ onClick Detonate
            , style "display" "block"
            ]
            [ Html.text "Detonate!" ]
        , System.view fireworkView
            [ style "width" "300px"
            , style "height" "300px"
            , style "background-color" "#000000"
            ]
            model
        ]


fireworkView : Particle Firework -> Svg msg
fireworkView particle =
    case Particle.data particle of
        Dot ->
            Svg.circle
                [ SAttrs.r "1"
                , SAttrs.fill "#FFF176"
                ]
                []

        Line length ->
            Svg.rect
                [ SAttrs.height "2"
                , SAttrs.width (String.fromInt length)
                , SAttrs.fill "#FFF176"
                , SAttrs.transform <|
                    "rotate("
                        ++ String.fromFloat (Particle.directionDegrees particle)
                        ++ ")"
                ]
                []


main : Program () (System Firework) Msg
main =
    Browser.element
        { init = \_ -> ( System.init (Random.initialSeed 0), Cmd.none )
        , update = update
        , view = view
        , subscriptions = \model -> System.sub [] ParticleMsg model
        }