{-
	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	= MkQualifiedMove {
	QualifiedMove -> Move
getMove		:: Component.Move.Move,
	QualifiedMove -> MoveType
getMoveType	:: Attribute.MoveType.MoveType
} deriving QualifiedMove -> QualifiedMove -> Bool
(QualifiedMove -> QualifiedMove -> Bool)
-> (QualifiedMove -> QualifiedMove -> Bool) -> Eq QualifiedMove
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: QualifiedMove -> QualifiedMove -> Bool
$c/= :: QualifiedMove -> QualifiedMove -> Bool
== :: QualifiedMove -> QualifiedMove -> Bool
$c== :: QualifiedMove -> QualifiedMove -> Bool
Eq

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

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

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

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

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