{-|
Module      : Pakoras.Base
Description : Provides base types for the engine.
Stability   : stable

The purpose of this Base module is to define types that are used
all throughout the engine. This also defines utilities for using
the types.
-}
module Pakoras.Base where

import Data.ByteString.Lazy
import FRP.Sodium

-- * Types

{-|
  Provides a structure to store config
  information about the game, which can then be given to
  'Pakoras.start' to start an instance of the engine.
-}
data Configuration = Configuration { -- | The desired title of the window.
                                     windowTitle :: String,
                                     -- | The desired resolution of the window.
                                     screenSize  :: (Int, Int),
                                     -- | Chooses whether the window is fullscreen or not.
                                     fullScreen  :: Bool
                                   } deriving (Show)

{-|
  Type that designates a signal's purpose.
-}
data SignalType
  = NullType        -- ^ Dummy type. Shouldn't be used in normal cases.
  | NewClock        -- ^ Activates new clock in "Pakoras.EngineSignals". Data slot contains time between new clock signals.
  | ClockSignal     -- ^ Triggered by "Pakoras.EngineSignals" regularly. Data slot contains time between clock signals.
  deriving (Eq, Show)

{-|
  Represents the various destinations available to signals.
  Signals are routed to their intended destinations by 'Pakoras.Conduit'.
-}
data SignalTarget
  = NullTarget    -- ^ Dummy target. Shouldn't be used in normal cases.
  | All           -- ^ Signal goes to user-code and the entire engine
  | Conduit       -- ^ Signal goes to user-code.
  | EngineSignals -- ^ Signal goes to the EngineSignals module
  deriving (Eq, Show, Ord)

data Signal = Signal { -- | The type of the signal. Should describe signal purpose.
                       signalType   :: SignalType,
                       -- | The signal target (destination of signal).
                       signalTarget :: SignalTarget,
                       -- | Data the signal is carrying.
                       signalData   :: ByteString
                     } deriving (Show)

-- * Utilities

filterType :: SignalType -> Event Signal -> Event Signal
{-|
  Only keep event occurences with a specific 'SignalType'.
-}
filterType t e = filterE (\sig -> signalType sig == t) e

filterTarget :: SignalTarget -> Event Signal -> Event Signal
{-|
  Only keep event occurences with a specific 'SignalTarget'.
-}
filterTarget t e = filterE (\sig -> signalTarget sig == t) e
