module Dodge.LevelGen.Switch
    ( makeSwitch
    , makeButton
    , makeSwitchSPic
    , drawSwitchWire
    ) where
import Dodge.Data
import Dodge.Default
import Dodge.SoundLogic
import Picture
import ShapePicture
import Shape
import Geometry

import qualified Data.IntMap.Strict as IM
import Control.Lens
makeButton 
    :: Color 
    -> (World -> World) -- ^ Effect when pressed
    -> Button
makeButton col eff = defaultButton
    { _btPict = defaultDrawButton col
    , _btEvent = \b w -> eff 
        . over buttons (IM.adjust turnOn (_btID b))
        . soundFromGeneral (LeverSound 0) (btpos b) click1S Nothing $ w
    , _btText = "Button"
    , _btState = BtOff
    }
  where
    turnOn bt = bt {_btState = BtNoLabel, _btEvent = const id}
    btpos b w' = _btPos $ _buttons w' IM.! _btID b

drawSwitch :: Color -> Color -> Button -> SPic
drawSwitch col1 col2 bt
    | _btState bt == BtOff 
                = flick $ pi/4
    | otherwise = flick (negate (pi/4))
  where
    flick a = ( mconcat
        [ colorSH col1 . upperPrismPoly 20 $ reverse $ rectNSWE (-2) (-5) (-10) 10
        , colorSH col2 . translateSH (V3 0 (-2) 20) . rotateSH a . upperPrismPoly 2 $ reverse
            $ rectNSWE 10 0 (-2) 2
        ]   
        , mempty)

drawSwitchWire :: Color -> Color -> Button -> SPic
drawSwitchWire col1 col2 bt
    | _btState bt == BtOff = flick $ pi/4
    | otherwise = flick (negate (pi/4))
  where
    flick a = ( mconcat
        [ colorSH col1 . translateSHz 10 . upperPrismPoly 10 $ reverse $ rectNSWE (-2) (-5) (-10) 10
        , colorSH col2 . translateSH (V3 0 (-2) 15) . rotateSH a . upperPrismPoly 2 . reverse 
            $ rectNSWE 10 0 (-2) 2
        ]   
        , mempty)

makeSwitchSPic
    :: (Button -> SPic)
    -> (World -> World) -- ^ Switch on effect
    -> (World -> World) -- ^ Switch off effect
    -> Button
makeSwitchSPic dswitch effOn effOff = defaultButton
    { _btPict = dswitch
    , _btEvent = flipSwitch
    , _btText = "SWITCH/"
    , _btState = BtOff
    }
  where 
    flipSwitch b = switchEffect b . soundFromGeneral (LeverSound 0) (bpos b) click1S Nothing
    bpos b w = _btPos $ _buttons w IM.! _btID b
    switchEffect b = case _btState b of
        BtOff -> effOn  . (buttons . ix (_btID b) %~ turnOn )
        BtOn  -> effOff . (buttons . ix (_btID b) %~ turnOff)
        _ -> error "Trying to switch a button with no label"
    turnOn  = (btState .~ BtOn ) .  (btText .~ "SWITCH\\")
    turnOff = (btState .~ BtOff) .  (btText .~ "SWITCH/")
    
makeSwitch
    :: Color
    -> Color
    -> (World -> World) -- ^ Switch on effect
    -> (World -> World) -- ^ Switch off effect
    -> Button
makeSwitch col1 col2 f1 = (btColor .~ col1) . makeSwitchSPic (drawSwitch col1 col2) f1
