{-
	Copyright (C) 2018 Dr. Alistair Ward

	This file is part of BishBosh.

	BishBosh is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	BishBosh is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with BishBosh.  If not, see <http://www.gnu.org/licenses/>.
-}
{- |
 [@AUTHOR@]	Dr. Alistair Ward

 [@DESCRIPTION@]

	* Defines configurable options for [Chess-engine Communications-protocol](https://en.wikipedia.org/wiki/Chess_Engine_Communication_Protocol),
	as used by [XBoard](https://www.gnu.org/software/xboard/engine-intf.html)
-}

module BishBosh.Input.CECPOptions(
-- * Types
-- ** Type-synonyms
--	Mode,
--	ProtocolVersion,
--	Transformation,
-- ** Data-types
	CECPOptions(
--		MkCECPOptions,
		getAnalyseMode,
		getDisplaySAN,
		getEditMode,
		getForceMode,
		getMaybePaused,
		getPonderMode,
		getPostMode,
		getProtocolVersion,
		getCECPFeatures
	),
-- * Constants
	tag,
	analyseModeTag,
	displaySANTag,
	editModeTag,
	forceModeTag,
--	pausedTag,
	ponderModeTag,
	postModeTag,
	protocolVersionTag,
-- * Functions
	getNamedModes,
-- ** Constructors
	mkCECPOptions,
-- ** Mutators
	setProtocolVersion,
	updateFeature,
	deleteFeature,
	resetModes,
	pause,
	resume
) where

import qualified	BishBosh.Data.Exception		as Data.Exception
import qualified	BishBosh.Input.CECPFeatures	as Input.CECPFeatures
import qualified	BishBosh.Property.Switchable	as Property.Switchable
import qualified	BishBosh.Text.ShowList		as Text.ShowList
import qualified	BishBosh.Time.StopWatch		as Time.StopWatch
import qualified	Control.DeepSeq
import qualified	Control.Exception
import qualified	Data.Default
import qualified	Data.Maybe
import qualified	Text.XML.HXT.Arrow.Pickle	as HXT

-- | Used to qualify XML.
tag :: String
tag :: String
tag			= String
"cecpOptions"

-- | Used to qualify XML.
analyseModeTag :: String
analyseModeTag :: String
analyseModeTag		= String
"analyseMode"

-- | Used to qualify XML.
displaySANTag :: String
displaySANTag :: String
displaySANTag		= String
"displaySAN"

-- | Used to qualify XML.
editModeTag :: String
editModeTag :: String
editModeTag		= String
"editMode"

-- | Used to qualify XML.
forceModeTag :: String
forceModeTag :: String
forceModeTag		= String
"forceMode"

-- | Used to qualify XML.
pausedTag :: String
pausedTag :: String
pausedTag		= String
"pause"

-- | Used to qualify XML.
ponderModeTag :: String
ponderModeTag :: String
ponderModeTag		= String
"ponderMode"

-- | Used to qualify XML.
postModeTag :: String
postModeTag :: String
postModeTag		= String
"postMode"

-- | Used to qualify XML.
protocolVersionTag :: String
protocolVersionTag :: String
protocolVersionTag	= String
"protocolVersion"

-- | Self-documentation.
type Mode	= Bool

-- | Self-documentation.
type ProtocolVersion	= Int

-- | Defines options related to CECP.
data CECPOptions	= MkCECPOptions {
	CECPOptions -> Mode
getAnalyseMode		:: Mode,				-- ^ TODO.
	CECPOptions -> Mode
getDisplaySAN		:: Bool,				-- ^ Whether to display moves in SAN or 'Input.UIOptions.getMoveNotation'.
	CECPOptions -> Mode
getEditMode		:: Mode,				-- ^ Whether the game should be placed in set-up mode.
	CECPOptions -> Mode
getForceMode		:: Mode,				-- ^ Neither player's moves are automated, allowing an arbitrary game to be configured.
	CECPOptions -> Maybe StopWatch
getMaybePaused		:: Maybe Time.StopWatch.StopWatch,	-- ^ Whether the engine was paused & a paused watch.
	CECPOptions -> Mode
getPonderMode		:: Mode,				-- ^ Whether to keep thinking while it's one's opponent's turn.
	CECPOptions -> Mode
getPostMode		:: Mode,				-- ^ Whether to show the details of deliberations.
	CECPOptions -> ProtocolVersion
getProtocolVersion	:: ProtocolVersion,			-- ^ The version of the CECP-protocol to use.
	CECPOptions -> CECPFeatures
getCECPFeatures		:: Input.CECPFeatures.CECPFeatures
} deriving CECPOptions -> CECPOptions -> Mode
(CECPOptions -> CECPOptions -> Mode)
-> (CECPOptions -> CECPOptions -> Mode) -> Eq CECPOptions
forall a. (a -> a -> Mode) -> (a -> a -> Mode) -> Eq a
/= :: CECPOptions -> CECPOptions -> Mode
$c/= :: CECPOptions -> CECPOptions -> Mode
== :: CECPOptions -> CECPOptions -> Mode
$c== :: CECPOptions -> CECPOptions -> Mode
Eq

instance Control.DeepSeq.NFData CECPOptions where
	rnf :: CECPOptions -> ()
rnf MkCECPOptions {
		getAnalyseMode :: CECPOptions -> Mode
getAnalyseMode		= Mode
analyseMode,
		getDisplaySAN :: CECPOptions -> Mode
getDisplaySAN		= Mode
displaySAN,
		getEditMode :: CECPOptions -> Mode
getEditMode		= Mode
editMode,
		getForceMode :: CECPOptions -> Mode
getForceMode		= Mode
forceMode,
		getMaybePaused :: CECPOptions -> Maybe StopWatch
getMaybePaused		= Maybe StopWatch
maybePaused,
		getPonderMode :: CECPOptions -> Mode
getPonderMode		= Mode
ponderMode,
		getPostMode :: CECPOptions -> Mode
getPostMode		= Mode
postMode,
		getProtocolVersion :: CECPOptions -> ProtocolVersion
getProtocolVersion	= ProtocolVersion
protocolVersion,
		getCECPFeatures :: CECPOptions -> CECPFeatures
getCECPFeatures		= CECPFeatures
cecpFeatures
	} = (Mode, Mode, Mode, Mode, Maybe StopWatch, Mode, Mode,
 ProtocolVersion, CECPFeatures)
-> ()
forall a. NFData a => a -> ()
Control.DeepSeq.rnf (Mode
analyseMode, Mode
displaySAN, Mode
editMode, Mode
forceMode, Maybe StopWatch
maybePaused, Mode
ponderMode, Mode
postMode, ProtocolVersion
protocolVersion, CECPFeatures
cecpFeatures)

instance Show CECPOptions where
	showsPrec :: ProtocolVersion -> CECPOptions -> ShowS
showsPrec ProtocolVersion
_ MkCECPOptions {
		getAnalyseMode :: CECPOptions -> Mode
getAnalyseMode		= Mode
analyseMode,
		getDisplaySAN :: CECPOptions -> Mode
getDisplaySAN		= Mode
displaySAN,
		getEditMode :: CECPOptions -> Mode
getEditMode		= Mode
editMode,
		getForceMode :: CECPOptions -> Mode
getForceMode		= Mode
forceMode,
		getMaybePaused :: CECPOptions -> Maybe StopWatch
getMaybePaused		= Maybe StopWatch
maybePaused,
		getPonderMode :: CECPOptions -> Mode
getPonderMode		= Mode
ponderMode,
		getPostMode :: CECPOptions -> Mode
getPostMode		= Mode
postMode,
		getProtocolVersion :: CECPOptions -> ProtocolVersion
getProtocolVersion	= ProtocolVersion
protocolVersion,
		getCECPFeatures :: CECPOptions -> CECPFeatures
getCECPFeatures		= CECPFeatures
cecpFeatures
	} = [(String, ShowS)] -> ShowS
Text.ShowList.showsAssociationList' [
		(
			String
analyseModeTag,
			Mode -> ShowS
forall a. Show a => a -> ShowS
shows Mode
analyseMode
		), (
			String
displaySANTag,
			Mode -> ShowS
forall a. Show a => a -> ShowS
shows Mode
displaySAN
		), (
			String
editModeTag,
			Mode -> ShowS
forall a. Show a => a -> ShowS
shows Mode
editMode
		), (
			String
forceModeTag,
			Mode -> ShowS
forall a. Show a => a -> ShowS
shows Mode
forceMode
		), (
			String
pausedTag,
			Maybe StopWatch -> ShowS
forall a. Show a => a -> ShowS
shows Maybe StopWatch
maybePaused
		), (
			String
ponderModeTag,
			Mode -> ShowS
forall a. Show a => a -> ShowS
shows Mode
ponderMode
		), (
			String
postModeTag,
			Mode -> ShowS
forall a. Show a => a -> ShowS
shows Mode
postMode
		), (
			String
protocolVersionTag,
			ProtocolVersion -> ShowS
forall a. Show a => a -> ShowS
shows ProtocolVersion
protocolVersion
		), (
			String
Input.CECPFeatures.tag,
			Char -> ShowS
showChar Char
'{' ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CECPFeatures -> ShowS
forall a. Show a => a -> ShowS
shows CECPFeatures
cecpFeatures ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> ShowS
showChar Char
'}'
		)
	 ]

instance Data.Default.Default CECPOptions where
	def :: CECPOptions
def = MkCECPOptions :: Mode
-> Mode
-> Mode
-> Mode
-> Maybe StopWatch
-> Mode
-> Mode
-> ProtocolVersion
-> CECPFeatures
-> CECPOptions
MkCECPOptions {
		getAnalyseMode :: Mode
getAnalyseMode		= Mode
False,
		getEditMode :: Mode
getEditMode		= Mode
False,
		getDisplaySAN :: Mode
getDisplaySAN		= Mode
True,
		getForceMode :: Mode
getForceMode		= Mode
False,
		getMaybePaused :: Maybe StopWatch
getMaybePaused		= Maybe StopWatch
forall a. Maybe a
Nothing,
		getPonderMode :: Mode
getPonderMode		= Mode
False,
		getPostMode :: Mode
getPostMode		= Mode
False,
		getProtocolVersion :: ProtocolVersion
getProtocolVersion	= ProtocolVersion
1,
		getCECPFeatures :: CECPFeatures
getCECPFeatures		= CECPFeatures
forall a. Default a => a
Data.Default.def
	}

instance HXT.XmlPickler CECPOptions where
	xpickle :: PU CECPOptions
xpickle	= String -> PU CECPOptions -> PU CECPOptions
forall a. String -> PU a -> PU a
HXT.xpElem String
tag (PU CECPOptions -> PU CECPOptions)
-> (PU
      (Mode, Mode, Mode, Mode, Mode, Mode, ProtocolVersion, CECPFeatures)
    -> PU CECPOptions)
-> PU
     (Mode, Mode, Mode, Mode, Mode, Mode, ProtocolVersion, CECPFeatures)
-> PU CECPOptions
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Mode, Mode, Mode, Mode, Mode, Mode, ProtocolVersion,
  CECPFeatures)
 -> CECPOptions,
 CECPOptions
 -> (Mode, Mode, Mode, Mode, Mode, Mode, ProtocolVersion,
     CECPFeatures))
-> PU
     (Mode, Mode, Mode, Mode, Mode, Mode, ProtocolVersion, CECPFeatures)
-> PU CECPOptions
forall a b. (a -> b, b -> a) -> PU a -> PU b
HXT.xpWrap (
		\(Mode
a, Mode
b, Mode
c, Mode
d, Mode
e, Mode
f, ProtocolVersion
g, CECPFeatures
h) -> Mode
-> Mode
-> Mode
-> Mode
-> Maybe StopWatch
-> Mode
-> Mode
-> ProtocolVersion
-> CECPFeatures
-> CECPOptions
mkCECPOptions Mode
a Mode
b Mode
c Mode
d (CECPOptions -> Maybe StopWatch
getMaybePaused CECPOptions
def) Mode
e Mode
f ProtocolVersion
g CECPFeatures
h,	-- Construct.
		\MkCECPOptions {
			getAnalyseMode :: CECPOptions -> Mode
getAnalyseMode		= Mode
analyseMode,
			getDisplaySAN :: CECPOptions -> Mode
getDisplaySAN		= Mode
displaySAN,
			getEditMode :: CECPOptions -> Mode
getEditMode		= Mode
editMode,
			getForceMode :: CECPOptions -> Mode
getForceMode		= Mode
forceMode,
			getPonderMode :: CECPOptions -> Mode
getPonderMode		= Mode
ponderMode,
			getPostMode :: CECPOptions -> Mode
getPostMode		= Mode
postMode,
			getProtocolVersion :: CECPOptions -> ProtocolVersion
getProtocolVersion	= ProtocolVersion
protocolVersion,
			getCECPFeatures :: CECPOptions -> CECPFeatures
getCECPFeatures		= CECPFeatures
cecpFeatures
		} -> (Mode
analyseMode, Mode
displaySAN, Mode
editMode, Mode
forceMode, Mode
ponderMode, Mode
postMode, ProtocolVersion
protocolVersion, CECPFeatures
cecpFeatures) -- Deconstruct.
	 ) (PU
   (Mode, Mode, Mode, Mode, Mode, Mode, ProtocolVersion, CECPFeatures)
 -> PU CECPOptions)
-> PU
     (Mode, Mode, Mode, Mode, Mode, Mode, ProtocolVersion, CECPFeatures)
-> PU CECPOptions
forall a b. (a -> b) -> a -> b
$ PU Mode
-> PU Mode
-> PU Mode
-> PU Mode
-> PU Mode
-> PU Mode
-> PU ProtocolVersion
-> PU CECPFeatures
-> PU
     (Mode, Mode, Mode, Mode, Mode, Mode, ProtocolVersion, CECPFeatures)
forall a b c d e f g h.
PU a
-> PU b
-> PU c
-> PU d
-> PU e
-> PU f
-> PU g
-> PU h
-> PU (a, b, c, d, e, f, g, h)
HXT.xp8Tuple (
		CECPOptions -> Mode
getAnalyseMode CECPOptions
def Mode -> PU Mode -> PU Mode
forall a. Eq a => a -> PU a -> PU a
`HXT.xpDefault` String -> PU Mode -> PU Mode
forall a. String -> PU a -> PU a
HXT.xpAttr String
analyseModeTag PU Mode
forall a. XmlPickler a => PU a
HXT.xpickle
	 ) (
		CECPOptions -> Mode
getDisplaySAN CECPOptions
def Mode -> PU Mode -> PU Mode
forall a. Eq a => a -> PU a -> PU a
`HXT.xpDefault` String -> PU Mode -> PU Mode
forall a. String -> PU a -> PU a
HXT.xpAttr String
displaySANTag PU Mode
forall a. XmlPickler a => PU a
HXT.xpickle
	 ) (
		CECPOptions -> Mode
getEditMode CECPOptions
def Mode -> PU Mode -> PU Mode
forall a. Eq a => a -> PU a -> PU a
`HXT.xpDefault` String -> PU Mode -> PU Mode
forall a. String -> PU a -> PU a
HXT.xpAttr String
editModeTag PU Mode
forall a. XmlPickler a => PU a
HXT.xpickle
	 ) (
		CECPOptions -> Mode
getForceMode CECPOptions
def Mode -> PU Mode -> PU Mode
forall a. Eq a => a -> PU a -> PU a
`HXT.xpDefault` String -> PU Mode -> PU Mode
forall a. String -> PU a -> PU a
HXT.xpAttr String
forceModeTag PU Mode
forall a. XmlPickler a => PU a
HXT.xpickle
	 ) (
		CECPOptions -> Mode
getPonderMode CECPOptions
def Mode -> PU Mode -> PU Mode
forall a. Eq a => a -> PU a -> PU a
`HXT.xpDefault` String -> PU Mode -> PU Mode
forall a. String -> PU a -> PU a
HXT.xpAttr String
ponderModeTag PU Mode
forall a. XmlPickler a => PU a
HXT.xpickle
	 ) (
		CECPOptions -> Mode
getPostMode CECPOptions
def Mode -> PU Mode -> PU Mode
forall a. Eq a => a -> PU a -> PU a
`HXT.xpDefault` String -> PU Mode -> PU Mode
forall a. String -> PU a -> PU a
HXT.xpAttr String
postModeTag PU Mode
forall a. XmlPickler a => PU a
HXT.xpickle
	 ) (
		CECPOptions -> ProtocolVersion
getProtocolVersion CECPOptions
def ProtocolVersion -> PU ProtocolVersion -> PU ProtocolVersion
forall a. Eq a => a -> PU a -> PU a
`HXT.xpDefault` String -> PU ProtocolVersion -> PU ProtocolVersion
forall a. String -> PU a -> PU a
HXT.xpAttr String
protocolVersionTag PU ProtocolVersion
forall a. XmlPickler a => PU a
HXT.xpickle
	 ) PU CECPFeatures
forall a. XmlPickler a => PU a
HXT.xpickle {-CECPFeatures-} where
		def :: CECPOptions
def	= CECPOptions
forall a. Default a => a
Data.Default.def

-- | Smart constructor.
mkCECPOptions
	:: Mode					-- ^ Analyse-mode.
	-> Bool					-- ^ Display SAN.
	-> Mode					-- ^ Edit-mode.
	-> Mode					-- ^ Force-mode.
	-> Maybe Time.StopWatch.StopWatch	-- ^ Paused.
	-> Mode					-- ^ Ponder-mode.
	-> Mode					-- ^ Post-mode.
	-> ProtocolVersion
	-> Input.CECPFeatures.CECPFeatures
	-> CECPOptions
mkCECPOptions :: Mode
-> Mode
-> Mode
-> Mode
-> Maybe StopWatch
-> Mode
-> Mode
-> ProtocolVersion
-> CECPFeatures
-> CECPOptions
mkCECPOptions Mode
analyseMode Mode
displaySAN Mode
editMode Mode
forceMode Maybe StopWatch
maybePaused Mode
ponderMode Mode
postMode ProtocolVersion
protocolVersion CECPFeatures
cecpFeatures
	| ProtocolVersion
protocolVersion ProtocolVersion -> ProtocolVersion -> Mode
forall a. Ord a => a -> a -> Mode
< ProtocolVersion
1	= Exception -> CECPOptions
forall a e. Exception e => e -> a
Control.Exception.throw (Exception -> CECPOptions)
-> (String -> Exception) -> String -> CECPOptions
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Exception
Data.Exception.mkOutOfBounds (String -> Exception) -> ShowS -> String -> Exception
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ShowS
showString String
"BishBosh.UI.CECPOptions.mkCECPOptions:\t" (String -> CECPOptions) -> String -> CECPOptions
forall a b. (a -> b) -> a -> b
$ String -> ShowS
forall a. Show a => a -> ShowS
shows String
protocolVersionTag String
" must exceed zero."
	| Mode
otherwise		= MkCECPOptions :: Mode
-> Mode
-> Mode
-> Mode
-> Maybe StopWatch
-> Mode
-> Mode
-> ProtocolVersion
-> CECPFeatures
-> CECPOptions
MkCECPOptions {
		getAnalyseMode :: Mode
getAnalyseMode		= Mode
analyseMode,
		getDisplaySAN :: Mode
getDisplaySAN		= Mode
displaySAN,
		getEditMode :: Mode
getEditMode		= Mode
editMode,
		getForceMode :: Mode
getForceMode		= Mode
forceMode,
		getMaybePaused :: Maybe StopWatch
getMaybePaused		= Maybe StopWatch
maybePaused,
		getPonderMode :: Mode
getPonderMode		= Mode
ponderMode,
		getPostMode :: Mode
getPostMode		= Mode
postMode,
		getProtocolVersion :: ProtocolVersion
getProtocolVersion	= ProtocolVersion
protocolVersion,
		getCECPFeatures :: CECPFeatures
getCECPFeatures		= CECPFeatures
cecpFeatures
	}

-- | Self-documentation.
type Transformation	= CECPOptions -> CECPOptions

-- | Mutator.
setProtocolVersion :: ProtocolVersion -> Transformation
setProtocolVersion :: ProtocolVersion -> Transformation
setProtocolVersion ProtocolVersion
protocolVersion CECPOptions
cecpOptions
	| ProtocolVersion
protocolVersion ProtocolVersion -> ProtocolVersion -> Mode
forall a. Ord a => a -> a -> Mode
< ProtocolVersion
1	= Exception -> CECPOptions
forall a e. Exception e => e -> a
Control.Exception.throw (Exception -> CECPOptions) -> Exception -> CECPOptions
forall a b. (a -> b) -> a -> b
$ String -> Exception
Data.Exception.mkOutOfBounds (String -> Exception) -> ShowS -> String -> Exception
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ShowS
showString String
"BishBosh.UI.CECPOptions.setProtocolVersion:\t" (String -> Exception) -> String -> Exception
forall a b. (a -> b) -> a -> b
$ ProtocolVersion -> ShowS
forall a. Show a => a -> ShowS
shows ProtocolVersion
protocolVersion String
" must exceed zero."
	| Mode
otherwise		= CECPOptions
cecpOptions {
		getProtocolVersion :: ProtocolVersion
getProtocolVersion	= ProtocolVersion
protocolVersion
	}

-- | Mutator.
updateFeature :: Input.CECPFeatures.Feature -> Transformation
updateFeature :: Feature -> Transformation
updateFeature Feature
feature cecpOptions :: CECPOptions
cecpOptions@MkCECPOptions { getCECPFeatures :: CECPOptions -> CECPFeatures
getCECPFeatures = CECPFeatures
cecpFeatures }	= CECPOptions
cecpOptions {
	getCECPFeatures :: CECPFeatures
getCECPFeatures	= Feature -> Transformation
Input.CECPFeatures.updateFeature Feature
feature CECPFeatures
cecpFeatures
}

-- | Mutator.
deleteFeature :: Input.CECPFeatures.Feature -> Transformation
deleteFeature :: Feature -> Transformation
deleteFeature Feature
feature cecpOptions :: CECPOptions
cecpOptions@MkCECPOptions { getCECPFeatures :: CECPOptions -> CECPFeatures
getCECPFeatures = CECPFeatures
cecpFeatures }	= CECPOptions
cecpOptions {
	getCECPFeatures :: CECPFeatures
getCECPFeatures	= Feature -> Transformation
Input.CECPFeatures.deleteFeature Feature
feature CECPFeatures
cecpFeatures
}

-- | Reset all modes but leave the remaining fields unaltered.
resetModes :: Transformation
resetModes :: Transformation
resetModes CECPOptions
cecpOptions	= CECPOptions
cecpOptions {
	getAnalyseMode :: Mode
getAnalyseMode	= Mode
False,
	getEditMode :: Mode
getEditMode	= Mode
False,
	getForceMode :: Mode
getForceMode	= Mode
False,
	getMaybePaused :: Maybe StopWatch
getMaybePaused	= Maybe StopWatch
forall a. Maybe a
Nothing,
	getPonderMode :: Mode
getPonderMode	= Mode
False,
	getPostMode :: Mode
getPostMode	= Mode
False
}

-- | Get an association-list of named modes.
getNamedModes :: CECPOptions -> [(String, Mode)]
getNamedModes :: CECPOptions -> [(String, Mode)]
getNamedModes MkCECPOptions {
	getAnalyseMode :: CECPOptions -> Mode
getAnalyseMode	= Mode
analyseMode,
	getEditMode :: CECPOptions -> Mode
getEditMode	= Mode
editMode,
	getForceMode :: CECPOptions -> Mode
getForceMode	= Mode
forceMode,
	getMaybePaused :: CECPOptions -> Maybe StopWatch
getMaybePaused	= Maybe StopWatch
maybePaused,
	getPonderMode :: CECPOptions -> Mode
getPonderMode	= Mode
ponderMode,
	getPostMode :: CECPOptions -> Mode
getPostMode	= Mode
postMode
} = [
	(
		String
analyseModeTag,
		Mode
analyseMode
	), (
		String
editModeTag,
		Mode
editMode
	), (
		String
forceModeTag,
		Mode
forceMode
	), (
		String
pausedTag,
		Maybe StopWatch -> Mode
forall a. Maybe a -> Mode
Data.Maybe.isJust Maybe StopWatch
maybePaused
	), (
		String
ponderModeTag,
		Mode
ponderMode
	), (
		String
postModeTag,
		Mode
postMode
	)
 ]

-- | Mutator.
pause :: Time.StopWatch.StopWatch -> CECPOptions -> CECPOptions
pause :: StopWatch -> Transformation
pause StopWatch
_ MkCECPOptions { getMaybePaused :: CECPOptions -> Maybe StopWatch
getMaybePaused = Just StopWatch
_ }	= Exception -> CECPOptions
forall a e. Exception e => e -> a
Control.Exception.throw (Exception -> CECPOptions) -> Exception -> CECPOptions
forall a b. (a -> b) -> a -> b
$ String -> Exception
Data.Exception.mkRequestFailure String
"BishBosh.Input.CECPOptions.pause:\talready paused."
pause StopWatch
stopWatch CECPOptions
cecpOptions
	| StopWatch -> Mode
forall a. Switchable a => a -> Mode
Property.Switchable.isOn StopWatch
stopWatch	= Exception -> CECPOptions
forall a e. Exception e => e -> a
Control.Exception.throw (Exception -> CECPOptions) -> Exception -> CECPOptions
forall a b. (a -> b) -> a -> b
$ String -> Exception
Data.Exception.mkRequestFailure String
"BishBosh.Input.CECPOptions.pause:\tthe stop-watch is still running."
	| Mode
otherwise				= CECPOptions
cecpOptions { getMaybePaused :: Maybe StopWatch
getMaybePaused = StopWatch -> Maybe StopWatch
forall a. a -> Maybe a
Just StopWatch
stopWatch }

-- | Mutator.
resume :: CECPOptions -> CECPOptions
resume :: Transformation
resume MkCECPOptions { getMaybePaused :: CECPOptions -> Maybe StopWatch
getMaybePaused = Maybe StopWatch
Nothing }	= Exception -> CECPOptions
forall a e. Exception e => e -> a
Control.Exception.throw (Exception -> CECPOptions) -> Exception -> CECPOptions
forall a b. (a -> b) -> a -> b
$ String -> Exception
Data.Exception.mkRequestFailure String
"BishBosh.Input.CECPOptions.resume:\talready resumed."
resume CECPOptions
cecpOptions					= CECPOptions
cecpOptions { getMaybePaused :: Maybe StopWatch
getMaybePaused = Maybe StopWatch
forall a. Maybe a
Nothing }