module Panes.Controller exposing (..)

import Triple exposing (Triple)
import Panes exposing (..)
import Panes.Home
import Panes.Search
import Panes.Interview
import Panes.Person
import PaneMeta exposing (PaneMeta)

type Pane
    = Home Panes.Home.Model
    | Search Panes.Search.Model
    | Interview Panes.Interview.Model
    | Person Panes.Person.Model

type Msg
    = HomeMsg Panes.Home.Msg
    | SearchMsg Panes.Search.Msg
    | InterviewMsg Panes.Interview.Msg
    | PersonMsg Panes.Person.Msg

paneHome = Panes.map Home HomeMsg Panes.Home.component
paneSearch = Panes.map Search SearchMsg Panes.Search.component
paneInterview = Panes.map Interview InterviewMsg Panes.Interview.component
panePerson = Panes.map Person PersonMsg Panes.Person.component

initHome : PaneMeta -> Triple Pane (Cmd Msg) (List Event)
initHome meta =
    paneHome.init meta ()

initSearch : PaneMeta -> String -> Triple Pane (Cmd Msg) (List Event)
initSearch meta query =
    paneSearch.init meta query

initInterview : PaneMeta -> String -> Triple Pane (Cmd Msg) (List Event)
initInterview meta query =
    paneInterview.init meta query

initPerson : PaneMeta -> String -> Triple Pane (Cmd Msg) (List Event)
initPerson meta query =
    panePerson.init meta query

getCompModel : Pane -> ComponentWithModel Pane Msg
getCompModel pane =
    case pane of
        Home model ->
            attachModel model paneHome
        Search model ->
            attachModel model paneSearch
        Interview model ->
            attachModel model paneInterview
        Person model ->
            attachModel model panePerson

view : View Pane Msg
view { meta, state } =
    getCompModel state
    |> \comp -> comp.view meta

update : Update Pane Msg
update msg data =
    case (msg, data.state) of
        (HomeMsg sub, Home model) ->
            paneHome.update sub
            <| PaneData data.meta model
        (SearchMsg sub, Search model) ->
            paneSearch.update sub
            <| PaneData data.meta model
        (InterviewMsg sub, Interview model) ->
            paneInterview.update sub
            <| PaneData data.meta model
        (PersonMsg sub, Person model) ->
            panePerson.update sub
            <| PaneData data.meta model
        _ -> Triple.triple data.state Cmd.none []

apply : Apply Pane Msg
apply event { meta, state } =
    getCompModel state
    |> \comp -> comp.apply event meta

save : Save Pane
save pane =
    getCompModel pane
    |> \comp -> comp.save ()

subscription : Subscription Pane Msg
subscription { meta, state } =
    getCompModel state
    |> \comp -> comp.subscription meta
