module Dodge.Creature 
    ( module Dodge.Creature
    , module Dodge.Creature.Inanimate
    , launcherCrit
    , pistolCrit
    , ltAutoCrit
    , spreadGunCrit
    , autoCrit
    , chaseCrit
    , armourChaseCrit
    , smallChaseCrit
    )
  where
--import Dodge.Creature.Stance.Data
import Dodge.Creature.State.Data
import Dodge.Item.Weapon.Grenade
import Dodge.Item.Weapon.Booster
import Dodge.Item.Weapon.Utility
import Dodge.Item.Weapon.Drone
--import Dodge.Creature.ReaderUpdate
--import Dodge.Creature.AlertLevel
--import Dodge.Creature.SetTarget
import Dodge.Creature.Volition
import Dodge.Creature.Test
import Dodge.Creature.Impulse
import Dodge.Creature.SentinelAI
import Dodge.Creature.LauncherCrit
import Dodge.Creature.PistolCrit
import Dodge.Creature.LtAutoCrit
import Dodge.Creature.SpreadGunCrit
import Dodge.Creature.AutoCrit
import Dodge.Creature.ChaseCrit
import Dodge.Creature.ArmourChase
import Dodge.Data
import Dodge.Default
import Dodge.Item.Weapon
import Dodge.Item.Equipment
import Dodge.Item.Consumable
import Dodge.WorldEvent.Cloud
import Dodge.Creature.YourControl
import Dodge.Creature.Inanimate
import Dodge.Creature.State
import Dodge.Creature.Picture
--import Dodge.Creature.ChooseTarget
--import Dodge.Item
import Dodge.Picture.Layer
import Picture
import Geometry.Data
import qualified IntMapHelp as IM

--import Data.List
--import Data.Char
--import Data.Maybe
--import Data.Function
import Control.Lens
--import Control.Monad.Reader
--import System.Random
--import qualified Data.Set as S
--import qualified Data.Map as M

spawnerCrit :: Creature
spawnerCrit = defaultCreature
    { --_crUpdate = stateUpdate $ spawnerAI chaseCrit
     _crHP = 300
    , _crPict = basicCrPict blue
    , _crInv = IM.empty -- IM.fromList [(0,frontArmour)]
    }

miniGunCrit :: Creature
miniGunCrit = defaultCreature
    { _crPict = basicCrPict red
    , _crUpdate = stateUpdate $ impulsiveAIR $
        sentinelFireType (const shootTillEmpty)
    , _crActionPlan = ActionPlan
        { _crImpulse    = []
        , _crAction     = []
        , _crStrategy   = StrategyActions WatchAndWait [StartSentinelPost]
        , _crGoal       = []
        }
    , _crInv = IM.fromList [(0,miniGun)]
    , _crInvSel = 0
    , _crRad = 10
    , _crState = defaultState
    , _crHP = 500
    , _crMvType = defaultAimMvType
    }
longCrit :: Creature
longCrit = defaultCreature
    { _crPict = basicCrPict red
--    , _crUpdate = stateUpdate sniperAI
    , _crUpdate = stateUpdate $ impulsiveAIR $ sentinelFireType $ const shootTillEmpty
    , _crActionPlan = ActionPlan
        { _crImpulse    = []
        , _crAction     = []
        , _crStrategy   = StrategyActions WatchAndWait [StartSentinelPost]
        , _crGoal       = []
        }
    , _crInv = IM.fromList [(0,longGun),(1,medkit 100)]
    , _crInvSel = 0
    , _crRad = 10
    , _crHP = 300
    }
multGunCrit :: Creature
multGunCrit = defaultCreature
    { _crPict = basicCrPict red
--    , _crUpdate = stateUpdate (twitchMissAI 300 350)
    , _crInv = IM.fromList [(0,multGun),(1,medkit 100)]
    , _crInvSel = 0
    , _crRad = 10
    , _crHP = 300
    , _crUpdate = stateUpdate $ impulsiveAIR $ sentinelExtraWatchUpdate
            [ ( not . crHasAmmo
              , \_ _ -> StrategyActions Reload reloadActions
              )
            , (not . crSafeDistFromTarg 150 
              , \_ cr -> StrategyActions Flee 
                    [(not . crSafeDistFromTarg 150) `DoActionWhile` UseTarget (fleeFrom cr)
                        `DoActionThen` DoImpulses [ChangeStrategy WatchAndWait]  ]
              )
            , (crHasTargetLOS, \_ _ -> StrategyActions (ShootAt 0)
                [ drawwp `DoActionThen` shootFirstMiss `DoActionThen` DoImpulses [ChangeStrategy WatchAndWait] ]
              ) 
            ]
    , _crActionPlan = ActionPlan
        { _crImpulse    = []
        , _crAction     = []
        , _crStrategy   = WatchAndWait
        , _crGoal       = []
        }
    }
  where
    drawwp = DoActionIfElse NoAction crIsAiming (DoActionThen drawWeapon (WaitThen 50 NoAction))
    reloadActions = 
        [ holsterWeapon
        , WaitThen 1 $ DoActionWhileInterrupt NoAction crIsReloading (DoImpulses [ChangeStrategy WatchAndWait])
        ]

addArmour :: Creature -> Creature
addArmour = over crInv insarmour
  where 
    insarmour xs = IM.insert (IM.newKey xs) frontArmour xs
{- | The creature you control.
ID 0.  -}
startCr :: Creature
startCr = defaultCreature
    { _crPos = V2 20 0
    , _crOldPos = V2 20 0
    , _crDir = pi/2
    , _crMvDir  = pi/2
    , _crID = 0
    , _crPict = basicCrPict black
    , _crUpdate = stateUpdate yourControl
    , _crRad = 10
    , _crMass = 10
    , _crHP = 1000
    , _crMaxHP = 1500
    , _crInv = startInventory 
    , _crCorpse = onLayer CorpseLayer 
        $ color (greyN 0.5) $ pictures [color (greyN 0.8) $ circleSolid 10, circLine 10]
    , _crFaction = PlayerFaction
    , _crMvType = MvWalking yourDefaultSpeed
    }
{- | Items you start with.  -}
startInvList :: [Item]
startInvList =
    [
    ]
startInventory :: IM.IntMap Item
startInventory = IM.fromList $ zip [0..defaultInvSize -1] $ startInvList ++ repeat NoItem
stackedInventory :: IM.IntMap Item
stackedInventory = IM.fromList (zip [0..25] 
    (
    [spreadGun
    ,tractorGun
    ,longGun
    ,autoGun
    ,ltAutoGun
    ,hvAutoGun
    ,pistol
    ,teslaGun
    ,blinkGun
    ,miniGun
    ,bezierGun
--    ,multGun
    ,boosterGun
    ,remoteLauncher
    ,flatShield
    ,grenade
    ,spawnGun (lamp 5)
    ,lasGun
    ,flamer
    ,poisonSprayer
    ,launcher
    ,lasDrones
    --,lasGun
    --,grenade
    --,ltAutoGun,flamer,multGun,spreadGun,remoteLauncher
    --,longGun
    --,hvAutoGun
    --,teslaGun
    --,latchkey 0
    --,miniGun
    --,medkit 50
    --,bezierGun
    ] 
      ++ 
    repeat NoItem))
smokeGenGun :: Item
smokeGenGun = effectGun "smoke" $ const spawnSmokeAtCursor

