module Select exposing (..)

import Html exposing (Attribute, Html, option, select, text)
import Html.Attributes exposing (selected, value)
import Html.Events exposing (onInput)

type alias Model a =
  { identify : a -> String
  , show : a -> String
  , selected : a
  , options : List a
  }

init : (a -> String) -> (a -> String) -> a -> List a -> Model a
init = Model

update : String -> Model a -> Model a
update key model =
  case find (\x -> key == model.identify x) model.options of
    Nothing -> model
    Just x -> { model | selected = x }

view : List (Attribute m) -> (String -> m) -> Model a -> Html m
view attributes msg model =
  let
    viewOption x =
      option
        [ selected <| model.identify model.selected == model.identify x, value <| model.identify x ]
        [ text <| model.show x ]
  in
    select ([ onInput msg ] ++ attributes) <| List.map viewOption model.options

get : Model a -> a
get = .selected

find pred xs = List.head <| List.filter pred xs