module Dodge.Item.Weapon.BulletGuns
    ( bangCone
    , blunderbuss
    , bigBlunderbuss
    , biggerBlunderbuss
    , biggestBlunderbuss
    , grenadeLauncher
    , autogunSpread
    , autoGun
    , autoGunPic
    , module Dodge.Item.Weapon.BulletGun.Stick
    , module Dodge.Item.Weapon.BulletGun.Cane
    , module Dodge.Item.Weapon.BulletGun.Rod
    ) where
import Dodge.Item.Weapon.BulletGun.Stick
import Dodge.Reloading.Action
import Dodge.Item.Weapon.BulletGun.Cane
import Dodge.Item.Weapon.BulletGun.Rod
--import Dodge.Item.Weapon.BulletGun.Clip
import Dodge.Data
--import Dodge.ChainEffect
import Dodge.Default.Weapon
import Dodge.Default
import Dodge.Item.Attachment
--import Dodge.Item.Weapon.InventoryDisplay
import Dodge.Item.Weapon.AmmoParams
import Dodge.Item.Draw
import Dodge.Item.Weapon.TriggerType
import Dodge.SoundLogic.LoadSound
import Picture
import Geometry
import ShapePicture
import Shape
--import Sound.Data
import LensHelp

import qualified Data.Sequence as Seq
--import Control.Lens
import Control.Monad.State
import System.Random

autoGun :: Item
autoGun = defaultAutoGun 
    { _itConsumption = defaultBulletLoadable 
        { _laMax = 30
        , _laLoaded = 30
        }
        & laCycle .~ [loadEject 30, loadInsert 30 , loadPrime 10]
    , _itUse   = ruseAmmoParamsRate 4 NoHammer
        [ ammoCheckI
        , charFiringStratI
            [('S', hammerCheckI)
            ]
        , useTimeCheck
        , charFiringStratI
            [('M', torqueBefore 0.08) 
            ,('S', torqueBefore 0.05) 
            ]
        , withSoundForI autoBS 5
        --, withSoundForI seagullChatterS 5
        , useAmmoAmount 1
        , applyInaccuracy
        , withMuzFlareI
        , withSmoke 1 black 20 200 5
        ]
        & useAim . aimWeight .~ 6
        & useAim . aimRange .~ 1
        & useAim . aimStance .~ TwoHandTwist
        & useAim . aimZoom .~ defaultItZoom {_itZoomFac = 1.5}
--    , _itFloorPict = autoGunPic
--    , _itZoom = defaultItZoom 
    , _itEquipPict = pictureWeaponOnAim
    , _itAttachment = AttachCharMode $ Seq.fromList "MS"
    , _itParams = BulletShooter
        { _muzVel = 1
        , _rifling = 0.9
        , _bore = 2
        , _gunBarrels = SingleBarrel 0.1
        , _recoil = 0
        , _torqueAfter = 0
        , _randomOffset = 0
        }
    }
    & itUse . heldScroll .~ scrollCharMode
    & itType . iyBase .~ AUTOGUN
autoGunPic :: Item -> SPic
autoGunPic it = noPic $
     colorSH red (prismPoly 
        (map (addZ 5) $ rectNESW 2 12 (-2) (-8))
        (map (addZ 0) $ rectNESW 4 12 (-4) (-12))
        )
    <> translateSHf 0 (-1) (rotateSHx (negate $ pi/4) . upperPrismPoly 2 $ rectNESW (negate $ 3 + 0.25 * x) 0 3 (-5))
  where
    x = fromIntegral $ _laLoaded $ _itConsumption it

bangCone :: Item
bangCone = defaultBulletWeapon 
        { _itUse = ruseAmmoParamsRate 20 upHammer
        [ ammoCheckI
        , hammerCheckI
        , useTimeCheck
        , withSoundStart bangEchoS
        , useAllAmmo
        , withTorqueAfter
        , withRecoil
        , duplicateLoaded
        , withMuzFlareI
        , applyInaccuracy
        , withRandomOffset
        , withRandomItemUpdate coneRandItemUpdate
        , withRandomItemParams coneRandItemParams
        ]
    , _itParams = BulletShooter
        { _muzVel = 0.7
        , _rifling = 0.8
        , _bore = 5
        , _gunBarrels = SingleBarrel 0.5
        , _recoil = 150
        , _torqueAfter = 0.1
        , _randomOffset = 12
        }
    , _itDimension = ItemDimension
        { _dimRad = 8
        , _dimCenter = V3 5 0 0
        , _dimPortage = HeldItem
            {_handlePos =  5
            ,_muzPos    = 15
            }
        , _dimSPic = const $ noPic $ colorSH cyan $ upperPrismPoly 3 (rectXH 5 2)
            <> upperPrismPoly 6 (reverse $ rectNSWE 4 (-4) 5 15)
        }
    }
    & itType . iyBase .~ BANGCONE
    & itConsumption . laMax .~ 5
    & itConsumption . laCycle .~ [loadEject 5, loadInsert 20 , loadPrime 5]
coneRandItemUpdate :: State StdGen (Item -> Item)
coneRandItemUpdate = do
    wth <- state $ randomR (1,5)
    return (\it -> it & itConsumption . laAmmoType . amBulWth .~ wth)
coneRandItemParams :: State StdGen (ItemParams -> ItemParams)
coneRandItemParams = do
    muzv <- state $ randomR (0.5,1)
    rifl <- state $ randomR (0.3,0.9)
    return $ \itparams -> itparams
        { _muzVel = muzv
        , _rifling = rifl
        }

blunderbuss :: Item
blunderbuss = bangCone
    {_itDimension = ItemDimension
        { _dimRad = 8
        , _dimCenter = V3 5 0 0
        , _dimPortage = HeldItem
            {_handlePos =  5
            ,_muzPos    = 30
            }
        , _dimSPic = const $ noPic $ colorSH cyan $ upperPrismPoly 3 (rectXH 20 2)
            <> upperPrismPoly 6 (reverse $ rectNSWE 4 (-4) 20 30)
        }
    }
    & itConsumption . laMax .~ 25
    & itConsumption . laCycle .~ [loadEject 5, loadInsert 30 , loadPrime 5]
    & itUse . useAim . aimStance .~ TwoHandTwist
    & itUse . useAim . aimWeight .~ 6
    & itType . iyBase .~ BLUNDERBUSS
bigBlunderbuss :: Item
bigBlunderbuss = blunderbuss
    & itType . iyBase .~ BIGBLUNDERBUSS
    & itConsumption . laMax .~ 50
    & itConsumption . laCycle .~ [loadEject 5, loadInsert 40 , loadPrime 5]
    & itParams . recoil .~ 200
    & itParams . torqueAfter .~ 0.3
    & itParams . randomOffset .~ 16
biggerBlunderbuss :: Item
biggerBlunderbuss = bigBlunderbuss
    & itType . iyBase .~ BIGGERBLUNDERBUSS
    & itConsumption . laMax .~ 75
    & itConsumption . laCycle .~ [loadEject 5, loadInsert 50 , loadPrime 5]
    & itParams . recoil .~ 250
    & itParams . torqueAfter .~ 0.5
    & itParams . randomOffset .~ 20
biggestBlunderbuss :: Item
biggestBlunderbuss = biggerBlunderbuss
    & itType . iyBase .~ BIGGESTBLUNDERBUSS
    & itConsumption . laMax .~ 100
    & itConsumption . laCycle .~ [loadEject 5, loadInsert 60 , loadPrime 5]
    & itParams . recoil .~ 300
    & itParams . torqueAfter .~ 0.7
    & itParams . randomOffset .~ 24

grenadeLauncher :: Int -> Item
grenadeLauncher _ = bangCone

autogunSpread :: Float
autogunSpread = 0.07
