{-
	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@]	Qualifies a /move/ with a /move-type/.
-}

module BishBosh.Component.QualifiedMove(
-- * Types
-- ** Data-types
	QualifiedMove(
--		MkQualifiedMove,
		getMove,
		getMoveType
	),
-- * Functions
-- ** Constructors
	mkQualifiedMove
) where

import qualified	BishBosh.Attribute.MoveType	as Attribute.MoveType
import qualified	BishBosh.Component.Move		as Component.Move
import qualified	BishBosh.Property.Reflectable	as Property.Reflectable
import qualified	Control.Arrow
import qualified	Control.DeepSeq

-- | A move qualified by its /movetype/.
data QualifiedMove x y	= MkQualifiedMove {
	QualifiedMove x y -> Move x y
getMove		:: Component.Move.Move x y,
	QualifiedMove x y -> MoveType
getMoveType	:: Attribute.MoveType.MoveType
} deriving QualifiedMove x y -> QualifiedMove x y -> Bool
(QualifiedMove x y -> QualifiedMove x y -> Bool)
-> (QualifiedMove x y -> QualifiedMove x y -> Bool)
-> Eq (QualifiedMove x y)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall x y.
(Eq x, Eq y) =>
QualifiedMove x y -> QualifiedMove x y -> Bool
/= :: QualifiedMove x y -> QualifiedMove x y -> Bool
$c/= :: forall x y.
(Eq x, Eq y) =>
QualifiedMove x y -> QualifiedMove x y -> Bool
== :: QualifiedMove x y -> QualifiedMove x y -> Bool
$c== :: forall x y.
(Eq x, Eq y) =>
QualifiedMove x y -> QualifiedMove x y -> Bool
Eq

instance (Show x, Show y) => Show (QualifiedMove x y) where
	showsPrec :: Int -> QualifiedMove x y -> ShowS
showsPrec Int
precedence MkQualifiedMove {
		getMove :: forall x y. QualifiedMove x y -> Move x y
getMove		= Move x y
move,
		getMoveType :: forall x y. QualifiedMove x y -> MoveType
getMoveType	= MoveType
moveType
	} = Int -> (Move x y, MoveType) -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
precedence (Move x y
move, MoveType
moveType)

instance (
	Enum	x,
	Enum	y,
	Ord	x,
	Ord	y,
	Read	x,
	Read	y
 ) => Read (QualifiedMove x y) where
	readsPrec :: Int -> ReadS (QualifiedMove x y)
readsPrec Int
precedence	= (((Move x y, MoveType), String) -> (QualifiedMove x y, String))
-> [((Move x y, MoveType), String)]
-> [(QualifiedMove x y, String)]
forall a b. (a -> b) -> [a] -> [b]
map (((Move x y, MoveType) -> QualifiedMove x y)
-> ((Move x y, MoveType), String) -> (QualifiedMove x y, String)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
Control.Arrow.first (((Move x y, MoveType) -> QualifiedMove x y)
 -> ((Move x y, MoveType), String) -> (QualifiedMove x y, String))
-> ((Move x y, MoveType) -> QualifiedMove x y)
-> ((Move x y, MoveType), String)
-> (QualifiedMove x y, String)
forall a b. (a -> b) -> a -> b
$ (Move x y -> MoveType -> QualifiedMove x y)
-> (Move x y, MoveType) -> QualifiedMove x y
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Move x y -> MoveType -> QualifiedMove x y
forall x y. Move x y -> MoveType -> QualifiedMove x y
MkQualifiedMove) ([((Move x y, MoveType), String)] -> [(QualifiedMove x y, String)])
-> (String -> [((Move x y, MoveType), String)])
-> ReadS (QualifiedMove x y)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> String -> [((Move x y, MoveType), String)]
forall a. Read a => Int -> ReadS a
readsPrec Int
precedence

instance (Control.DeepSeq.NFData x, Control.DeepSeq.NFData y) => Control.DeepSeq.NFData (QualifiedMove x y) where
	rnf :: QualifiedMove x y -> ()
rnf MkQualifiedMove {
		getMove :: forall x y. QualifiedMove x y -> Move x y
getMove		= Move x y
move,
		getMoveType :: forall x y. QualifiedMove x y -> MoveType
getMoveType	= MoveType
moveType
	} = (Move x y, MoveType) -> ()
forall a. NFData a => a -> ()
Control.DeepSeq.rnf (Move x y
move, MoveType
moveType)

instance Enum y => Property.Reflectable.ReflectableOnX (QualifiedMove x y) where
	reflectOnX :: QualifiedMove x y -> QualifiedMove x y
reflectOnX qualifiedMove :: QualifiedMove x y
qualifiedMove@MkQualifiedMove { getMove :: forall x y. QualifiedMove x y -> Move x y
getMove = Move x y
move }	= QualifiedMove x y
qualifiedMove { getMove :: Move x y
getMove = Move x y -> Move x y
forall a. ReflectableOnX a => a -> a
Property.Reflectable.reflectOnX Move x y
move }

-- | Constructor.
mkQualifiedMove	:: Component.Move.Move x y -> Attribute.MoveType.MoveType -> QualifiedMove x y
mkQualifiedMove :: Move x y -> MoveType -> QualifiedMove x y
mkQualifiedMove	= Move x y -> MoveType -> QualifiedMove x y
forall x y. Move x y -> MoveType -> QualifiedMove x y
MkQualifiedMove