module Dodge.Creature 
    ( module Dodge.Creature
    , module Dodge.Creature.ChaseCrit
    , module Dodge.Creature.Inanimate
    , launcherCrit
    , pistolCrit
    , ltAutoCrit
    , spreadGunCrit
    , autoCrit
    , armourChaseCrit
    ) where
import Dodge.Creature.State.Data
import Dodge.Creature.Update
import Dodge.Prop.Gib
--import Dodge.Item.Weapon.Grenade
import Dodge.Item.Equipment.Booster
import Dodge.Item.Weapon.Utility
import Dodge.Item.Weapon.Drone
import Dodge.Item.Craftable
--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 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 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
    , _crInv = IM.empty -- IM.fromList [(0,frontArmour)]
    }
    & crSkin . skinUpper .~ light4 blue

miniGunCrit :: Creature
miniGunCrit = defaultCreature
    { _crPict = basicCrPict
    , _crUpdate = defaultImpulsive [sentinelFireType (const shootTillEmpty)]
--    , _crInv = IM.fromList [(0,autoRifle & itConsumption . ammoLoaded .~ 1000)]
    , _crInv = IM.fromList [(0,miniGunX 3)]
--    , _crInv = IM.fromList [(0,autoRifle)]
    , _crRad = 10
    , _crState = defaultState
    , _crHP = 500
    , _crMvType = defaultAimMvType
    }
    & crSkin . skinUpper .~ light4 red
longCrit :: Creature
longCrit = defaultCreature
    { _crPict = basicCrPict
--    , _crUpdate = stateUpdate sniperAI
    , _crUpdate = defaultImpulsive [sentinelFireType $ const shootTillEmpty]
    , _crActionPlan = ActionPlan
        { _apImpulse    = []
        , _apAction     = []
        , _apStrategy   = StrategyActions WatchAndWait [StartSentinelPost]
        , _apGoal       = []
        }
    , _crInv = IM.fromList [(0,sniperRifle),(1,medkit 100)]
    , _crRad = 10
    , _crHP = 150
    }
    & crSkin . skinUpper .~ light4 red
multGunCrit :: Creature
multGunCrit = defaultCreature
    { _crPict = basicCrPict
--    , _crUpdate = stateUpdate (twitchMissAI 300 350)
    , _crInv = IM.fromList [(0,bangCaneX 4),(1,medkit 100)]
    , _crRad = 10
    , _crHP = 300
    , _crUpdate = defaultImpulsive [sentinelExtraWatchUpdate
            [ ( const $ not . crWeaponReady
              , \_ _ -> StrategyActions Reload reloadActions
              )
            , (const $ not . crSafeDistFromTarg 150 
              , \_ cr -> StrategyActions Flee 
                    [const (not . crSafeDistFromTarg 150) `DoActionWhile` UseTarget (fleeFrom cr)
                        `DoActionThen` DoImpulses [ChangeStrategy WatchAndWait]  ]
              )
            , (crHasTargetLOS, \_ _ -> StrategyActions (ShootAt 0)
                [ drawwp `DoActionThen` shootFirstMiss `DoActionThen` DoImpulses [ChangeStrategy WatchAndWait] ]
              ) 
            ]
        ]
    }
    & crSkin . skinUpper .~ light4 red
  where
    drawwp = DoActionIfElse NoAction (const crIsAiming) (DoActionThen drawWeapon (WaitThen 50 NoAction))
    reloadActions = 
        [ holsterWeapon
        , WaitThen 1 $ DoActionWhileInterrupt NoAction (const 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
    , _crUpdate = stateUpdate yourControl
    , _crRad = 10
    , _crMass = 10
    , _crHP = 1000
    , _crMaxHP = 1500
    , _crInv = startInventory 
    , _crCorpse = basicCrCorpse
    , _crFaction = PlayerFaction
    , _crMvType = MvWalking yourDefaultSpeed
    }
    & crSkin . skinUpper .~ light4 black
{- | Items you start with.  -}
startInvList :: [Item]
startInvList = [ ]
startInventory :: IM.IntMap Item
startInventory = IM.fromList $ zip [0..] startInvList

inventoryX :: Char -> [Item]
inventoryX c = case c of
    'A' -> 
        [ clickDetector ITEMDETECTOR
        , makeTypeCraftNum 1 TRANSFORMER
        , makeTypeCraftNum 2 CAN
        , makeTypeCraftNum 2 PIPE
        ]
    'B' -> 
        [ forceFieldGun
        , wristArmour
        , wristArmour
        , autoRifle
        , smg
        , machinePistol
        , makeTypeCraftNum 4 MICROCHIP
        , makeTypeCraftNum 2 TIN
        , makeTypeCraftNum 2 HARDWARE
        , makeTypeCraftNum 2 CAN
        , makeTypeCraftNum 2 PIPE
        , makeTypeCraftNum 1 CREATURESENSOR
        ]
    'C' ->
        [ autoDetector CREATUREDETECTOR
        , autoDetector WALLDETECTOR
        , autoDetector ITEMDETECTOR
        , wristInvisibility
        ]
    'D' ->
        [ blinkGun
        , unsafeBlinkGun
        , autoDetector WALLDETECTOR
        , effectGun "GIBBER" addCrGibs
        ]
    'E' ->
        [ makeTypeCraftNum 3 PIPE
        , makeTypeCraftNum 5 HARDWARE
        , makeTypeCraftNum 1 TIN
        , makeTypeCraftNum 1 SPRING
        , makeTypeCraftNum 1 PLANK
        , makeTypeCraftNum 1 PLATE
        , makeTypeCraftNum 1 DRUM
        , makeTypeCraftNum 1 MOTOR
        ]
    'F' ->
        [ makeTypeCraftNum 5 PIPE
        , makeTypeCraftNum 5 TUBE
        , makeTypeCraftNum 5 HARDWARE
        , makeTypeCraftNum 5 TIN
        , makeTypeCraftNum 5 CAN
        , makeTypeCraftNum 5 SPRING
        , makeTypeCraftNum 5 PUMP
        , makeTypeCraftNum 5 MAGNET
        , makeTypeCraftNum 5 PLANK
        , makeTypeCraftNum 5 PLATE
        , makeTypeCraftNum 5 DRUM
        , makeTypeCraftNum 5 MOTOR
        , makeTypeCraftNum 5 TRANSFORMER
        , makeTypeCraftNum 5 PRISM
        , makeTypeCraftNum 5 LIGHTER
        , makeTypeCraftNum 5 INCENDIARYMODULE
        ]
    'G' ->
        [ autoPistol
        , makeTypeCraftNum 2 HARDWARE
        , makeTypeCraftNum 2 MAGNET
        , makeTypeCraftNum 5 INCENDIARYMODULE
        , makeTypeCraftNum 5 STATICMODULE
        ]
    'H' -> [ shatterGun ]
    'I' -> [ makeTypeCraft TELEPORTMODULE
           , makeTypeCraftNum 2 MICROCHIP 
           ]
    _ -> []

testInventory :: IM.IntMap Item
testInventory = IM.fromList $ zip [0..] 
    [ makeTypeCraftNum 9 PIPE
    , autoAmr
    , brainHat
    , headLamp
    , autoDetector WALLDETECTOR
    , magShield
    , frontArmour
    , wristArmour
    , flatShield
    , sniperRifle
    , makeTypeCraftNum 1 MOTOR
    , makeTypeCraft INCENDIARYMODULE
    , makeTypeCraft STATICMODULE
    , makeTypeCraft CONCUSSMODULE
--    , bounceModule
--    , medkit 50 & itConsumption . itAmount .~ 3
    , teleportModule
--    , makeTypeCraftNum 1 LIGHTER
--    , makeTypeCraftNum 15 TUBE
--    , makeTypeCraftNum 9 TRANSFORMER
--    , makeTypeCraftNum 5 CREATURESENSOR
--    , makeTypeCraftNum 9 PRISM
--    , makeTypeCraftNum 3 DRUM
--    , makeTypeCraftNum 3 PUMP
--    , makeTypeCraftNum 3 BATTERY
--    , makeTypeCraftNum 1 MAGNET
--    , makeTypeCraftNum 1 TRANSMITTER
    , makeTypeCraftNum 10 HARDWARE
    , makeTypeCraftNum 3 SPRING
    , makeTypeCraftNum 10 CAN
--    , makeTypeCraftNum 3 TIN
    , makeTypeCraftNum 3 PLANK
--    , makeTypeCraftNum 1 MOTOR
--    , makeTypeCraftNum 5 MICROCHIP
--    , makeTypeCraftNum 5 AIUNIT
    ]
stackedInventory :: IM.IntMap Item
stackedInventory = IM.fromList $ zip [0..] 
    [sonicGun
    ,burstRifle
    , pipe
    ,rewindGun
    ,tractorGun
    ,autoGun
    ,autoPistol
    ,pistol
    ,teslaGun
    ,blinkGun
    ,miniGunX 3
--    ,multGun
    ,boosterGun
    ,remoteLauncher
    ,flatShield
--    ,grenade
    ,spawnGun (lamp 5)
    ,lasGun
    ,flameThrower
    ,poisonSprayer
    ,launcher
    ,droneLauncher
    --,lasGun
    --,grenade
    --,ltAutoGun,flamer,multGun,spreadGun,remoteLauncher
    --,longGun
    --,hvAutoGun
    --,teslaGun
    --,latchkey 0
    --,miniGun
    --,medkit 50
    --,bezierGun
    ]
smokeGenGun :: Item
smokeGenGun = effectGun "smoke" $ const spawnSmokeAtCursor

