module Dodge.Placement.Instance.Sensor
    ( lightSensor
    ) where
import Color
import Dodge.Data
import Dodge.LevelGen.Data
import Dodge.Default
import Geometry
import ShapePicture
import Shape

import Control.Lens
import Data.Either

damageSensor 
    :: (DamageType -> Either Int Int) -- Left gets sensed, Right does damage
    -> Float
    -> (Machine -> World -> World)
    -> PlacementSpot -> Placement
damageSensor damF wdth upf ps = pContID ps ( PutLS theLS)
    $ \lsid -> Just $ spNoID ps $ PutMachine yellow (reverse $ square wdth) defaultMachine
        { _mcDraw = sensorSPic wdth
        , _mcUpdate = \mc w -> upf mc $ sensorUpdate damF mc w
        , _mcLSs = [lsid]
        }
  where
    theLS = defaultLS { _lsPos = V3 0 0 30 , _lsIntensity = 0.1 }

lightSensor :: Float -> (Machine -> World -> World) -> PlacementSpot -> Placement
lightSensor = damageSensor senseLasering

senseLasering :: DamageType -> Either Int Int
senseLasering Lasering {_dmAmount = x} = Left x
senseLasering _ = Right 0

sensorUpdate :: (DamageType -> Either Int Int) -> Machine -> World -> World
sensorUpdate damF mc w = w & machines . ix mcid %~ upmc
    & lightSources . ix lsid %~ upls
  where
    upmc = ( mcSensor %~ \x' -> min 1000 (max 0 (x' - 5 + newSense)) )
        . ( mcHP -~ sum dam )
        . (mcDamage .~ [])
    x = _mcSensor mc
    mcid = _mcID mc
    lsid = head (_mcLSs mc)
    (senseData,dam) = partitionEithers $ map damF $ _mcDamage mc
    newSense = sum senseData
    ni = fromIntegral x / 1000
    upls = lsIntensity .~ V3 ni ni ni

sensorSPic :: Float -> Machine -> SPic
sensorSPic wdth _ = ( colorSH yellow $ upperPrismPoly 25 (square wdth)
    , mempty )
