module Dodge.Item.Weapon.BulletGun.Stick 
    ( bangStick
    , pistol
    , autoPistol
    , machinePistol
    , smg
    , revolver
    , revolverX
    ) where
import Dodge.Item.Weapon.BulletGun.Clip
import Dodge.Reloading.Action
import Dodge.Data
import Dodge.ChainEffect
import Dodge.Default.Weapon
--import Dodge.Item.Weapon.InventoryDisplay
import Dodge.Default
--import Dodge.Item.Attachment
--import Dodge.Item.Weapon.ExtraEffect
--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 Data.Maybe
--import qualified Data.Sequence as Seq
--import Control.Lens
--import Control.Monad.State
--import System.Random

bangStickSoundChoice :: Item -> SoundID
bangStickSoundChoice it
    | _laLoaded (_itConsumption it) < 2 = tap3S 
    | otherwise = shotgunS

bangStick :: Int -> Item
bangStick i = defaultBulletWeapon 
    { _itUse = ruseAmmoParamsRate 8 upHammer
        [ ammoHammerCheck
        , useTimeCheck
        , withSoundItemChoiceStart bangStickSoundChoice
        , useAllAmmo
        , withMuzFlareI
        , withTorqueAfter
        , spreadLoaded
--        , applyInaccuracy
        , withRecoil
        ]
    , _itParams = BulletShooter
        { _muzVel = 0.8
        , _rifling = 0.8
        , _bore = 2
        , _gunBarrels = MultiBarrel
            {_brlNum = i
            ,_brlSpread = SpreadBarrels baseStickSpread
            ,_brlInaccuracy = 0.01
            }
        , _recoil = 25
        , _torqueAfter = 0.18 + 0.02 * fromIntegral i
        , _randomOffset = 0
        }
    , _itInvSize = fromIntegral i / 3
    , _itDimension = ItemDimension
        { _dimRad = 5
        , _dimCenter = V3 5 0 0
        , _dimPortage = HeldItem
            {_handlePos =  5
            ,_muzPos    = 10
            }
        , _dimSPic = \it -> noPic $ baseStickShapeX i
            <> stickClip it
        }
    }
    & itType . iyBase .~ BANGSTICK i
    & itConsumption . laMax .~ i
    & itConsumption . laCycle .~ [loadPartialInsert 10 1]
baseStickShapeX :: Int -> Shape
baseStickShapeX i = foldMap f [0..i-1]
  where
    f j = rotateSH ang baseStickShape
      where
        ang = fromIntegral j * baseStickSpread - (fromIntegral i - 1) * baseStickSpread * 0.5
baseStickSpread :: Float
baseStickSpread = 0.2

baseSMGShape :: Shape
baseSMGShape = colorSH green $ upperPrismPoly 3 $ rectXH 20 2

baseStickShape :: Shape
baseStickShape = colorSH green $ upperPrismPoly 3 $ rectXH 10 2
stickClip :: Item -> Shape
stickClip it = case it ^? itConsumption . laLoaded of
    Just x | x > 0 -> foldMap f [0..x-1] 
    _ -> mempty
  where
    f i = rotateSH ang $ translateSH (V3 5 0 3) $ upperPrismPoly 2 $ square 1.5
      where
        ang = baseStickSpread * fromIntegral i 
                - 0.5 * baseStickSpread * fromIntegral (_brlNum (_gunBarrels (_itParams it))-1)

revolver :: Item
revolver = pistol
    & itConsumption .~ 
        (defaultBulletLoadable
            & laMax .~ 6
            & laCycle .~ [loadPartialInsert 10 1] )
    & itDimension . dimSPic .~ (\it -> noPic $ baseStickShape <> revolverClip it)
    & itType . iyBase .~ REVOLVER

revolverClip :: Item -> Shape
revolverClip it = case it ^? itConsumption . laLoaded of
    Just al | al > 0 -> translateSH (V3 5 0 1) $ foldMap f [1..al]
    _ -> mempty
  where
    f i = rotateSHx (fromIntegral i * pi / 3 + pi/6) . translateSH (V3 0 0 2) $ upperPrismPoly 1 $ square 1

pistolAfterHamMods :: [ChainEffect]
pistolAfterHamMods = 
    [ useTimeCheck
    , useAmmoAmount 1
    , withSoundStart tap3S 
    , applyInaccuracy
    , withTorqueAfter
    , withRecoil
    , withSidePushI 50
    , withMuzFlareI
    ]
machinePistolAfterHamMods :: [ChainEffect]
machinePistolAfterHamMods = 
    [ useTimeCheck
    , useAmmoAmount 1
    , withSoundStart tap1S 
    , applyInaccuracy
    , withTorqueAfter
    , withSidePushI 50
    , withRecoil
    , withMuzFlareI
    ]
smgAfterHamMods :: [ChainEffect]
smgAfterHamMods = 
    [ useTimeCheck
    , useAmmoAmount 1
    , withSoundStart tap3S 
    , applyInaccuracy
    , withTorqueAfter
    , withRecoil
    , withSidePushI 30
    , withMuzFlareI
    ]

pistol :: Item
pistol = bangStick 1
    & itConsumption .~ ( defaultBulletLoadable
        & laMax .~ 15
        & laCycle .~ [loadEject 5, loadInsert 5 , loadPrime 5] )
    & itUse .~ ruseAmmoParamsRate 6 upHammer (ammoHammerCheck : pistolAfterHamMods)
    & itDimension . dimSPic .~ (\it -> noPic $ baseStickShape <> makeTinClipAt pi (V3 5 2 0) it)
    & itParams %~
        ( ( muzVel .~ 0.8 )
        . ( rifling .~ 0.8 )
        . ( bore .~ 2 )
        . ( gunBarrels .~ SingleBarrel 0.05 )
        . ( recoil .~ 10 )
        . ( torqueAfter .~ 0.2 )
        )
    & itType . iyBase .~ PISTOL
autoPistol :: Item
autoPistol = pistol 
    & itUse . useMods .~ (ammoCheckI : pistolAfterHamMods)
    & itType . iyBase .~ AUTOPISTOL
    & itType . iyModules . at ModAutoMag ?~ EMPTYMODULE
machinePistol :: Item
machinePistol = autoPistol 
    & itUse . useDelay . rateMax .~ 2
    & itUse . useMods .~ (ammoCheckI : machinePistolAfterHamMods)
    & itType . iyBase .~ MACHINEPISTOL
    & itType . iyModules . at ModAutoMag .~ Nothing
    & itParams . recoil .~ 20
smg :: Item
smg = autoPistol -- & some parameter affecting stability
    & itUse . useMods .~ (ammoCheckI : smgAfterHamMods)
    & itType . iyBase .~ SMG
    & itUse . useAim . aimStance .~ TwoHandTwist
    & itDimension . dimPortage . handlePos .~ 2
    & itParams . torqueAfter .~ 0.05
    & itDimension . dimSPic .~ \it -> noPic (baseSMGShape
        <> makeTinClipAt 0 (V3 7 (-2) 0) it)
revolverX :: Int -> Item
revolverX i = revolver
    { _itUse = ruseAmmoParamsRate 8 upHammer
        [ ammoHammerCheck
        , useTimeCheck
        -- rather than locking the inventory, a better solution may be to check
        -- that the weapon is still in your hands in the repeated frames
        , lockInvFor 10
        , \f it -> repeatOnFrames (take (_laLoaded (_itConsumption it) - 1) [2,4,6,8,10]) f it
        , withSoundStart tap3S 
        , useAmmoUpTo 1
        , applyInaccuracy
        , withMuzFlareI
--        , spreadLoaded
        , withTorqueAfter
        , withRecoil
        ]
    }   & itConsumption . laMax .~ i * 6
    & itType . iyBase .~ REVOLVERX i
