module Mischief.ECS.App.SystemConfig where

import Mischief.ECS.World

data SystemConfigData = SystemConfigData
  { SystemConfigData -> [System ()]
systems :: [System ()],
    SystemConfigData -> [(System (), System ())]
edges :: [(System (), System ())]
  }

-- | First type will be a SystemConfig. Second type will be a System ().
data SystemConfigModifier s1 s2 = ModAfter s1 s2 | ModBefore s1 s2

after :: s1 -> System () -> SystemConfigModifier s1 (System ())
after :: forall s1. s1 -> System () -> SystemConfigModifier s1 (System ())
after = s1 -> System () -> SystemConfigModifier s1 (System ())
forall s1 s2. s1 -> s2 -> SystemConfigModifier s1 s2
ModAfter

before :: s1 -> System () -> SystemConfigModifier s1 (System ())
before :: forall s1. s1 -> System () -> SystemConfigModifier s1 (System ())
before = s1 -> System () -> SystemConfigModifier s1 (System ())
forall s1 s2. s1 -> s2 -> SystemConfigModifier s1 s2
ModBefore

class SystemConfig s where
  systemConfigData :: s -> SystemConfigData

instance SystemConfig (System ()) where
  systemConfigData :: System () -> SystemConfigData
  systemConfigData :: System () -> SystemConfigData
systemConfigData System ()
system = SystemConfigData {systems :: [System ()]
systems = [System ()
system], edges :: [(System (), System ())]
edges = []}

instance (SystemConfig s1) => SystemConfig (SystemConfigModifier s1 (System ())) where
  systemConfigData :: SystemConfigModifier s1 (System ()) -> SystemConfigData
  systemConfigData :: SystemConfigModifier s1 (System ()) -> SystemConfigData
systemConfigData (ModAfter s1
s1 System ()
s2) =
    let SystemConfigData {[System ()]
systems :: SystemConfigData -> [System ()]
systems :: [System ()]
systems, [(System (), System ())]
edges :: SystemConfigData -> [(System (), System ())]
edges :: [(System (), System ())]
edges} = s1 -> SystemConfigData
forall s. SystemConfig s => s -> SystemConfigData
systemConfigData s1
s1
        newEdges :: [(System (), System ())]
newEdges = [(System ()
s2, System ()
system) | System ()
system <- [System ()]
systems]
     in SystemConfigData {[System ()]
systems :: [System ()]
systems :: [System ()]
systems, edges :: [(System (), System ())]
edges = [(System (), System ())]
newEdges [(System (), System ())]
-> [(System (), System ())] -> [(System (), System ())]
forall a. [a] -> [a] -> [a]
++ [(System (), System ())]
edges}
  systemConfigData (ModBefore s1
s1 System ()
s2) =
    let SystemConfigData {[System ()]
systems :: SystemConfigData -> [System ()]
systems :: [System ()]
systems, [(System (), System ())]
edges :: SystemConfigData -> [(System (), System ())]
edges :: [(System (), System ())]
edges} = s1 -> SystemConfigData
forall s. SystemConfig s => s -> SystemConfigData
systemConfigData s1
s1
        newEdges :: [(System (), System ())]
newEdges = [(System ()
system, System ()
s2) | System ()
system <- [System ()]
systems]
     in SystemConfigData {[System ()]
systems :: [System ()]
systems :: [System ()]
systems, edges :: [(System (), System ())]
edges = [(System (), System ())]
newEdges [(System (), System ())]
-> [(System (), System ())] -> [(System (), System ())]
forall a. [a] -> [a] -> [a]
++ [(System (), System ())]
edges}

instance (SystemConfig s0, SystemConfig s1) => SystemConfig (s0, s1) where
  systemConfigData :: (s0, s1) -> SystemConfigData
  systemConfigData :: (s0, s1) -> SystemConfigData
systemConfigData (s0
s0, s1
s1) =
    let SystemConfigData {systems :: SystemConfigData -> [System ()]
systems = [System ()]
systems0, edges :: SystemConfigData -> [(System (), System ())]
edges = [(System (), System ())]
edges0} = s0 -> SystemConfigData
forall s. SystemConfig s => s -> SystemConfigData
systemConfigData s0
s0
        SystemConfigData {systems :: SystemConfigData -> [System ()]
systems = [System ()]
systems1, edges :: SystemConfigData -> [(System (), System ())]
edges = [(System (), System ())]
edges1} = s1 -> SystemConfigData
forall s. SystemConfig s => s -> SystemConfigData
systemConfigData s1
s1
     in SystemConfigData {systems :: [System ()]
systems = [System ()]
systems0 [System ()] -> [System ()] -> [System ()]
forall a. [a] -> [a] -> [a]
++ [System ()]
systems1, edges :: [(System (), System ())]
edges = [(System (), System ())]
edges0 [(System (), System ())]
-> [(System (), System ())] -> [(System (), System ())]
forall a. [a] -> [a] -> [a]
++ [(System (), System ())]
edges1}