{-# LANGUAGE NamedFieldPuns, OverloadedStrings #-}

module MusicPad.Model.Verse where

import MusicPad.Env
import Prelude ()
import qualified Prelude as P
import MusicPad.Model.Sample



mod_verse_at :: Game State -> Int -> (Verse -> Verse) -> IO ()
mod_verse_at g i f = do
  with_state g - \_state -> do
    let verse_index = _state.song.current_verse_index
        current_verse = _state.song.verses.at verse_index
        new_verse = f current_verse
    
    g.state $~ set (__song > __verses) (_state.song.verses.replace_at verse_index new_verse)

mod_current_verse :: Game State -> (Verse -> Verse) -> IO ()
mod_current_verse g f = do
  with_state g - \_state -> do
    let verse_index = _state.song.current_verse_index
  
    mod_verse_at g verse_index f

query_verse_at :: Game State -> Int -> (Verse -> a) -> IO a
query_verse_at g i f = do
  with_state g - \_state -> do
    let verse_index = _state.song.current_verse_index
        current_verse = _state.song.verses.at verse_index
        r = f current_verse
    
    return r

query_current_verse :: Game State -> (Verse -> a) -> IO a
query_current_verse g f = do
  with_state g - \_state -> do
    let verse_index = _state.song.current_verse_index
  
    query_verse_at g verse_index f

get_current_verse_index :: Game State -> IO Int
get_current_verse_index g = do
  with_state g - song > current_verse_index > return

get_current_verse :: Game State -> IO Verse
get_current_verse g = do
  with_state g - \_state -> do
    let verse_index = _state.song.current_verse_index
    
    return - _state.song.verses.at verse_index


set_active_verse_on_object :: Game State -> TVar (GameObject State) -> Int -> IO ()
set_active_verse_on_object g o i = do
  set_active_verse_only g i
  update_all_verse_color g
  
set_active_verse_only :: Game State -> Int ->  IO ()
set_active_verse_only g i = do
  g.state $~ set (__song > __current_verse_index) i



update_all_verse_color :: Game State -> IO ()
update_all_verse_color g = do
  _current_verse_index <- get_current_verse_index g
  
  _scene <- read - g.scene
  _scene.objects.filterT (tag > is (Just - Tag "verse")) >>= mapM_ (\x ->
    x.verse_data.wantM - \attr -> do
      let _verse_no = attr.verse_no
      
      if _current_verse_index == _verse_no
        then
          x $~ mod __renderer ( fmap - set (__materials) [ Linked - "VerseEnabled" ] )
        else
          x $~ mod __renderer ( fmap - set (__materials) [ Linked - "VerseDisabled" ] )
    )


verse_data :: TVar (GameObject State) -> IO (Maybe VerseObjectData)
verse_data = object_data  
