module Dodge.Creature.YourControl
  where
import Dodge.Data
--import Dodge.Base
import Dodge.Creature.Impulse.Movement
--import Dodge.Creature.State
--import Dodge.Creature.State.Data
import Dodge.Creature.Stance.Data
import Dodge.Update.UsingInput
import Dodge.Config.KeyConfig
import Dodge.Item.Attachment.Data
import Geometry

import Control.Lens
import qualified SDL
--import Data.Maybe
import qualified Data.Set as S
import qualified Data.IntMap.Strict as IM
--import System.Random
import Data.Monoid
{- | The AI equivalent for your control. -}
yourControl 
    :: Creature 
    -> World
    -> (Endo World, Maybe Creature)
yourControl cr w = 
    ( Endo updateUsingInput 
    , Just . mouseActionsCr (_mouseButtons w) $ wasdWithAiming w speed 0 cr
    )
  where 
    speed = 4
{- | Turn key presses into creature movement.  -}
wasdWithAiming 
    :: World 
    -> Float    -- ^ Base speed
    -> Int      -- ^ Creature id
    -> Creature 
    -> Creature
wasdWithAiming w speed i cr
    | isAiming  = set crDir mouseDir $ theMovement cr
    | otherwise = theMovement $ theTurn cr
  where 
    theMovement
        | movDir == V2 0 0 = id
        | otherwise = crMvAbsolute (speed *.* movAbs) . set crMvDir dir
    theTurn cr' = creatureTurnTowardDir (_crMvDir cr') 0.2 cr'
    movDir = wasdDir w
    dir = _cameraRot w + argV movDir
    movAbs   = rotateV (_cameraRot w) $ normalizeV movDir
    isAiming = _posture (_crStance cr) == Aiming
    mouseDir = case w ^? creatures . ix i . crInv . ix (_crInvSel (_creatures w IM.! i))
                              . itAttachment of
        Just ItScope{_scopePos = p} -> normalizeAngle $ argV
                                $ p +.+ 2 / _cameraZoom w 
                                    *.* rotateV (_cameraRot w) (_mousePos w)
        _ -> normalizeAngle $ argV (_mousePos w) + _cameraRot w

wasdM :: World -> SDL.Scancode -> Point2
wasdM w scancode 
 | scancode == moveUpKey    (_keyConfig w) = V2   0    1
 | scancode == moveDownKey  (_keyConfig w) = V2   0  (-1)
 | scancode == moveRightKey (_keyConfig w) = V2   1    0
 | scancode == moveLeftKey  (_keyConfig w) = V2 (-1)   0
wasdM _ _ = V2 0 0

wasdDir :: World -> Point2
wasdDir w = foldr ((+.+) . wasdM w) (V2 0 0) $ _keys w

wasdComp :: S.Set SDL.Scancode -> World -> (Point2,Maybe Float)
wasdComp ks w = f $ foldr ( (+.+) . wasdM w ) (V2 0 0) ks
  where
    f (V2 0 0) = (V2 0 0, Nothing)
    f p     = (errorNormalizeV 46 p, Just $ argV p)

{- | Set posture according to mouse presses. -}
mouseActionsCr :: S.Set SDL.MouseButton -> Creature -> Creature
mouseActionsCr pkeys 
    | rbPressed = crStance . posture .~ Aiming
    | otherwise = crStance . posture .~ AtEase
  where 
    --lbPressed = SDL.ButtonLeft  `S.member` pkeys
    rbPressed = SDL.ButtonRight `S.member` pkeys
