diff --git a/ChangeLog.md b/ChangeLog.md
index abd105b..2216817 100644
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -3,6 +3,7 @@
## current
- Ask for database to load on start-up
- Add page break to report file
+- Implemented player/goalie deletion
## 0.14.0
- Fixed a bug that was causing shutouts to not be recorded
diff --git a/src/Mtlstats/Control/EditGoalie.hs b/src/Mtlstats/Control/EditGoalie.hs
index 595b35a..7632084 100644
--- a/src/Mtlstats/Control/EditGoalie.hs
+++ b/src/Mtlstats/Control/EditGoalie.hs
@@ -23,10 +23,13 @@ along with this program. If not, see .
module Mtlstats.Control.EditGoalie (editGoalieC) where
+import Control.Monad.Trans.State (gets, modify)
import Data.Maybe (fromMaybe)
-import Lens.Micro ((^.))
+import Lens.Micro ((^.), (.~), (%~))
import UI.NCurses as C
+import Mtlstats.Actions
+import Mtlstats.Handlers
import Mtlstats.Helpers.Goalie
import Mtlstats.Menu
import Mtlstats.Menu.EditGoalie
@@ -52,6 +55,7 @@ editC cb =
EGName -> nameC
EGYtd -> ytdMenuC
EGLifetime -> lifetimeMenuC
+ EGDelete -> deleteC
EGYtdGames b -> ytdGamesC b
EGYtdMins b -> ytdMinsC b
EGYtdGoals b -> ytdGoalsC b
@@ -83,6 +87,38 @@ ytdMenuC _ = menuControllerWith header editGoalieYtdMenu
lifetimeMenuC :: Action () -> Controller
lifetimeMenuC _ = menuControllerWith header editGoalieLtMenu
+deleteC :: Action () -> Controller
+deleteC _ = Controller
+
+ { drawController = \s -> do
+
+ C.drawString $ let
+
+ hdr = fromMaybe [] $ do
+ gid <- s^.progMode.editGoalieStateL.egsSelectedGoalie
+ goalie <- nth gid $ s^.database.dbGoalies
+ Just $ "Goalie: " ++ goalieDetails goalie ++ "\n\n"
+
+ in hdr ++ "Are you sure you want to delete this goalie? (Y/N)"
+
+ return C.CursorInvisible
+
+ , handleController = \e -> do
+
+ case ynHandler e of
+
+ Just True -> do
+ gets (^.progMode.editGoalieStateL.egsSelectedGoalie) >>= mapM_
+ (\gid -> modify $ database.dbGoalies %~ dropNth gid)
+ modify edit
+
+ Just False -> modify $ progMode.editGoalieStateL.egsMode .~ EGMenu
+ Nothing -> return ()
+
+ return True
+
+ }
+
ytdGamesC :: Bool -> Action () -> Controller
ytdGamesC = curry $ promptController .
uncurry editGoalieYtdGamesPrompt
diff --git a/src/Mtlstats/Control/EditPlayer.hs b/src/Mtlstats/Control/EditPlayer.hs
index c31340b..5fe1d96 100644
--- a/src/Mtlstats/Control/EditPlayer.hs
+++ b/src/Mtlstats/Control/EditPlayer.hs
@@ -21,10 +21,13 @@ along with this program. If not, see .
module Mtlstats.Control.EditPlayer (editPlayerC) where
+import Control.Monad.Trans.State (gets, modify)
import Data.Maybe (fromMaybe)
-import Lens.Micro ((^.))
+import Lens.Micro ((^.), (.~), (%~))
import qualified UI.NCurses as C
+import Mtlstats.Actions
+import Mtlstats.Handlers
import Mtlstats.Helpers.Player
import Mtlstats.Menu
import Mtlstats.Menu.EditPlayer
@@ -45,6 +48,7 @@ editPlayerC eps
EPPosition -> positionC
EPYtd -> ytdC
EPLifetime -> lifetimeC
+ EPDelete -> deleteC
EPYtdGoals b -> ytdGoalsC b
EPYtdAssists b -> ytdAssistsC b
EPYtdPMin -> ytdPMinC
@@ -74,6 +78,38 @@ ytdC _ = menuControllerWith header editPlayerYtdMenu
lifetimeC :: Action () -> Controller
lifetimeC _ = menuControllerWith header editPlayerLtMenu
+deleteC :: Action () -> Controller
+deleteC _ = Controller
+
+ { drawController = \s -> do
+
+ C.drawString $ let
+
+ hdr = fromMaybe [] $ do
+ pid <- s^.progMode.editPlayerStateL.epsSelectedPlayer
+ player <- nth pid $ s^.database.dbPlayers
+ Just $ "Player: " ++ playerDetails player ++ "\n\n"
+
+ in hdr ++ "Are you sure you want to delete this player? (Y/N)"
+
+ return C.CursorInvisible
+
+ , handleController = \e -> do
+
+ case ynHandler e of
+
+ Just True -> do
+ gets (^.progMode.editPlayerStateL.epsSelectedPlayer) >>= mapM_
+ (\pid -> modify $ database.dbPlayers %~ dropNth pid)
+ modify edit
+
+ Just False -> modify $ progMode.editPlayerStateL.epsMode .~ EPMenu
+ Nothing -> return ()
+
+ return True
+
+ }
+
ytdGoalsC :: Bool -> Action () -> Controller
ytdGoalsC batchMode callback = promptController $
editPlayerYtdGoalsPrompt batchMode callback
diff --git a/src/Mtlstats/Menu/EditGoalie.hs b/src/Mtlstats/Menu/EditGoalie.hs
index 0859b83..f8bec65 100644
--- a/src/Mtlstats/Menu/EditGoalie.hs
+++ b/src/Mtlstats/Menu/EditGoalie.hs
@@ -44,6 +44,7 @@ editGoalieMenu = Menu "EDIT GOALTENDER" () $ map
, ( 'D', "ACTIVE FLAG", toggleActive )
, ( 'E', "YTD STATS", set EGYtd )
, ( 'F', "LIFETIME STATS", set EGLifetime )
+ , ( 'G', "DELETE RECORD", set EGDelete )
, ( 'R', "RETURN TO EDIT MENU", edit )
]
diff --git a/src/Mtlstats/Menu/EditPlayer.hs b/src/Mtlstats/Menu/EditPlayer.hs
index 0a5f8cc..42512ee 100644
--- a/src/Mtlstats/Menu/EditPlayer.hs
+++ b/src/Mtlstats/Menu/EditPlayer.hs
@@ -45,6 +45,7 @@ editPlayerMenu = Menu "EDIT PLAYER" () $ map
, ( 'E', "ACTIVE FLAG", toggleActive )
, ( 'F', "YTD STATS", set EPYtd )
, ( 'G', "LIFETIME STATS", set EPLifetime )
+ , ( 'H', "DELETE RECORD", set EPDelete )
, ( 'R', "RETURN TO EDIT MENU", edit )
]
diff --git a/src/Mtlstats/Types.hs b/src/Mtlstats/Types.hs
index 6185a8c..b64f46a 100644
--- a/src/Mtlstats/Types.hs
+++ b/src/Mtlstats/Types.hs
@@ -378,6 +378,7 @@ data EditPlayerMode
| EPPosition
| EPYtd
| EPLifetime
+ | EPDelete
| EPYtdGoals Bool
| EPYtdAssists Bool
| EPYtdPMin
@@ -403,6 +404,7 @@ data EditGoalieMode
| EGName
| EGYtd
| EGLifetime
+ | EGDelete
| EGYtdGames Bool
| EGYtdMins Bool
| EGYtdGoals Bool
diff --git a/src/Mtlstats/Util.hs b/src/Mtlstats/Util.hs
index 951859c..02249f9 100644
--- a/src/Mtlstats/Util.hs
+++ b/src/Mtlstats/Util.hs
@@ -22,6 +22,7 @@ along with this program. If not, see .
module Mtlstats.Util
( nth
, modifyNth
+ , dropNth
, updateMap
, slice
, capitalizeName
@@ -56,6 +57,18 @@ modifyNth n f = zipWith
(\i x -> if i == n then f x else x)
[0..]
+-- | Attempt to drop the nth element from a list
+dropNth
+ :: Int
+ -- ^ The index of the element to drop
+ -> [a]
+ -- ^ The list to be modified
+ -> [a]
+ -- ^ The modified list
+dropNth n = foldr
+ (\(i, x) acc -> if i == n then acc else x : acc)
+ [] . zip [0..]
+
-- | Modify a value indexed by a given key in a map using a default
-- initial value if not present
updateMap
diff --git a/test/UtilSpec.hs b/test/UtilSpec.hs
index 13d9a39..b0c49f1 100644
--- a/test/UtilSpec.hs
+++ b/test/UtilSpec.hs
@@ -30,6 +30,7 @@ spec :: Spec
spec = describe "Mtlstats.Util" $ do
nthSpec
modifyNthSpec
+ dropNthSpec
updateMapSpec
sliceSpec
capitalizeNameSpec
@@ -64,6 +65,20 @@ modifyNthSpec = describe "modifyNth" $ do
it "should not modify the value" $
modifyNth (-1) succ list `shouldBe` [1, 2, 3]
+dropNthSpec :: Spec
+dropNthSpec = describe "dropNth" $ mapM_
+
+ (\(label, n, expected) ->
+ context label $
+ it ("should be " ++ show expected) $
+ dropNth n list `shouldBe` expected)
+
+ [ ( "out of bounds", 1, ["foo", "baz"] )
+ , ( "in bounds", 3, list )
+ ]
+
+ where list = ["foo", "bar", "baz"]
+
updateMapSpec :: Spec
updateMapSpec = describe "updateMap" $ do
let