module Dodge.Item.Display 
    ( itemDisplay
    , selectedItemDisplay
    , itemString
    )
    where
import Dodge.Module
import Dodge.Data
import Dodge.Inventory.ItemSpace
import Padding
import LensHelp

import Data.Maybe
import Data.Sequence

itemString :: Item -> String
itemString = head . itemDisplay

itemDisplayWithNumber :: String -> Item -> [String]
itemDisplayWithNumber numberstr it = Prelude.take (itSlotsTaken it) $
    (midPadL 15 ' ' thename (' ' : numberstr) ++ theparam)
    : catMaybes [maybeWarmupStatus it,maybeRateStatus it]
    ++ moduleStrings it ++ repeat "*"
  where 
    thename  = show . _iyBase $ _itType it
    theparam = fromMaybe []
        . listToMaybe 
        $ mapMaybe ($ it) 
        [ maybeModeStatus
        ]

selectedItemDisplay :: Creature -> Item -> [String]
selectedItemDisplay cr it = itemDisplayWithNumber (showSelectedConsumption cr (_itConsumption it)) it

{- | Displays the item name, ammo if loaded, and any selected '_itCharMode'.  -}
-- TODO make work on remote launchers
itemDisplay :: Item -> [String]
itemDisplay it = itemDisplayWithNumber (showConsumption (_itConsumption it)) it

showSelectedConsumption :: Creature -> ItemConsumption -> String
showSelectedConsumption cr ic = case ic of
    LoadableAmmo{} -> showReloadProgress cr ic
    AutoRecharging {} -> showAutoRechargeProgress ic
    ChargeableAmmo{} -> show $ _wpCharge ic
    ItemItselfConsumable{} -> show (_icAmount ic)
    NoConsumption -> ""

showAutoRechargeProgress :: ItemConsumption -> String
showAutoRechargeProgress ic
    | l < _arMax ic = show (_arProgress ic) ++ "C" ++ show l
    | otherwise    = show l
  where
    l = _arLoaded ic

showReloadProgress :: Creature -> ItemConsumption -> String
showReloadProgress cr ic = case cr ^?! crInvSel . iselAction of
    ReloadAction i la _ -> show i ++ showLoadActionType la (_laLoaded ic)
    _ -> case ic ^? laProgress . _Just . ix 0 of
        Nothing -> show $ _laLoaded ic
        Just la -> show (_actionTime la) ++ showLoadActionType la (_laLoaded ic)

showLoadProgress :: Int -> Maybe [LoadAction] -> String
showLoadProgress x mlas = case mlas ^? _Just . ix 0 of
    Just la -> show (_actionTime la) ++ showLoadActionType la x
    Nothing -> show x

showConsumption :: ItemConsumption -> String
showConsumption ic = case ic of
    LoadableAmmo{} -> showLoadProgress (_laLoaded ic) (_laProgress ic)
    AutoRecharging {} -> showAutoRechargeProgress ic
    ChargeableAmmo{} -> show $ _wpCharge ic
    ItemItselfConsumable{} -> show (_icAmount ic)
    NoConsumption -> ""

showLoadActionType :: LoadAction -> Int -> String
showLoadActionType la x = case la of
    LoadEject   {}  -> "E"
    LoadInsert  {}  -> "L"
    LoadAdd     {}  -> "A" ++ show x
    LoadPrime   {}  -> "P"

maybeWarmupStatus :: Item -> Maybe String
maybeWarmupStatus it = case it ^? itUse . useDelay . warmMax of
    Nothing -> Nothing
    Just m  -> case m - (_warmTime . _useDelay $ _itUse it) of
        x | x <= 1      -> Just "*WARM"
          | otherwise   -> let n = show x
                in Just $ Prelude.take (5 - Prelude.length n) "*WARM" ++ n

maybeModeStatus :: Item -> Maybe String
maybeModeStatus it = case it ^? itAttachment of
    Just AttachCharMode {_atCharMode = (c :<| _)} -> Just [' ',c]
    Just AttachMode {_atMode = i} -> Just $ show i
    _   -> Nothing

maybeRateStatus :: Item -> Maybe String
maybeRateStatus it = case it ^? itUse . useDelay . rateMaxMax of
    Nothing -> Nothing
    _ -> Just $ leftPad 3 ' ' (show (_rateMax . _useDelay $ _itUse it))
