--{-# LANGUAGE FlexibleInstances #-}
--{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE StrictData #-}
module Dodge.Config.Data where
import Data.Aeson
import qualified Data.Set as S
import GHC.Generics
import Control.Lens
--import Data.Enum.Set.Base
{-# ANN module "HLint: ignore Use camelCase" #-}
data Configuration = Configuration
    { _volume_master        :: Float
    , _volume_sound         :: Float
    , _volume_music         :: Float
    , _graphics_wall_textured        :: Bool
    , _graphics_cloud_shadows        :: Bool
    , _graphics_object_shadows       :: Bool
    , _graphics_resolution_factor    :: ResFactor
    , _windowX              :: Float
    , _windowY              :: Float
    , _windowPosX           :: Int
    , _windowPosY           :: Int
    , _gameplay_rotate_to_wall :: Bool
    , _debug_view_clip_bounds :: RoomClipping
    , _debug_booleans       :: S.Set DebugBool  -- consider using Data.BitSet
    }
  deriving (Generic, Show)
data DebugBool
    = Show_ms_frame
    | Show_debug
    | Show_sound
    | Noclip
    | Cr_status
    | Cr_awareness
    | Mouse_position
    | View_boundaries
    | Walls_info
    | Pathing        
    | Remove_LOS    
    | Cull_more_lights
    | Close_shape_culling
    | Show_bound_box
    | Bound_box_screen
    | Show_wall_search_rays
    | Show_dda_test
    | Show_far_wall_detect
    | Show_select
    | Inspect_wall
    | Show_nodes_near_select
    | Show_path_between
  deriving (Generic, Eq,Ord,Bounded, Enum, Show)
data ResFactor = FullRes | HalfRes | QuarterRes
  deriving (Generic, Show, Eq, Ord, Enum, Bounded)
instance ToJSON ResFactor where
  toEncoding = genericToEncoding defaultOptions
instance FromJSON ResFactor
data RoomClipping = NoRoomClipBoundaries | AllRoomClipBoundaries | IntersectingRoomClipBoundaries
  deriving (Generic, Show, Eq, Ord, Enum, Bounded)
instance ToJSON RoomClipping where
  toEncoding = genericToEncoding defaultOptions
instance FromJSON RoomClipping
resFactorNum :: ResFactor -> Int
resFactorNum rf = case rf of
    FullRes     -> 1
    HalfRes     -> 2
    QuarterRes  -> 4

makeLenses ''Configuration
instance ToJSON DebugBool where
  toEncoding = genericToEncoding defaultOptions

instance ToJSON Configuration where
  toEncoding = genericToEncoding defaultOptions

--deriving instance Generic a => Generic (EnumSet Word a)
--instance FromJSON (EnumSet Word a)

instance FromJSON DebugBool
instance FromJSON Configuration

defaultConfig  :: Configuration
defaultConfig = Configuration
    { _volume_master        = 1
    , _volume_sound         = 1
    , _volume_music         = 1
    , _graphics_wall_textured        = True
    , _graphics_cloud_shadows        = True
    , _graphics_object_shadows       = True
    , _graphics_resolution_factor    = FullRes
    , _windowX              = 800
    , _windowY              = 600
    , _windowPosX           = 0
    , _windowPosY           = 0
    , _gameplay_rotate_to_wall       = True
    , _debug_booleans = S.singleton Show_ms_frame
    , _debug_view_clip_bounds = NoRoomClipBoundaries
--    , _debug_show_sound           = False
--    , _debug_seconds_frame  = True
--    , _debug_noclip         = False
--    , _debug_mouse_position = False
--    , _debug_cr_status      = False
--    , _debug_cr_awareness   = False
--    , _debug_view_boundaries = False
--    , _debug_pathing    = False
--    , _debug_walls    = False
--    , _debug_remove_LOS      = False
--    , _debug_cull_more_lights     = False
    }
debugOn :: DebugBool -> Configuration -> Bool
debugOn db = S.member db . _debug_booleans
