-- This file is part of Goatee.
--
-- Copyright 2014-2021 Bryan Gardiner
--
-- Goatee is free software: you can redistribute it and/or modify
-- it under the terms of the GNU Affero General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- Goatee 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 Affero General Public License for more details.
--
-- You should have received a copy of the GNU Affero General Public License
-- along with Goatee.  If not, see <http://www.gnu.org/licenses/>.

-- | Metadata about the types of property values.
--
-- This module is internal to "Game.Goatee.Lib.Property"; you should not need
-- these structures elsewhere.
module Game.Goatee.Lib.Property.Value (
  PropertyValueType, pvtParser, pvtRenderer, pvtRendererPretty,
  colorPvt,
  coordElistPvt,
  coordListPvt,
  coordPairListPvt,
  doublePvt,
  gameResultPvt,
  integralPvt,
  labelListPvt,
  lineListPvt,
  movePvt,
  nonePvt,
  realPvt,
  rulesetPvt,
  simpleTextPairPvt,
  simpleTextPvt,
  sizePvt,
  textPvt,
  unknownPropertyPvt,
  variationModePvt,
  ) where

import qualified Game.Goatee.Lib.Property.Parser as P
import qualified Game.Goatee.Lib.Property.Renderer as R
import Game.Goatee.Lib.Renderer
import Game.Goatee.Lib.Types
import Text.ParserCombinators.Parsec (Parser)

data PropertyValueType a = PropertyValueType
  { PropertyValueType a -> Parser a
pvtParser :: Parser a
  , PropertyValueType a -> a -> Render ()
pvtRenderer :: a -> Render ()
  , PropertyValueType a -> a -> Render ()
pvtRendererPretty :: a -> Render ()
  }

colorPvt :: PropertyValueType Color
colorPvt :: PropertyValueType Color
colorPvt = PropertyValueType :: forall a.
Parser a
-> (a -> Render ()) -> (a -> Render ()) -> PropertyValueType a
PropertyValueType
  { pvtParser :: Parser Color
pvtParser = Parser Color
P.colorParser
  , pvtRenderer :: Color -> Render ()
pvtRenderer = Color -> Render ()
R.renderColorBracketed
  , pvtRendererPretty :: Color -> Render ()
pvtRendererPretty = Color -> Render ()
R.renderColorPretty
  }

coordElistPvt :: PropertyValueType CoordList
coordElistPvt :: PropertyValueType CoordList
coordElistPvt = PropertyValueType :: forall a.
Parser a
-> (a -> Render ()) -> (a -> Render ()) -> PropertyValueType a
PropertyValueType
  { pvtParser :: Parser CoordList
pvtParser = Parser CoordList
P.coordElistParser
  , pvtRenderer :: CoordList -> Render ()
pvtRenderer = CoordList -> Render ()
R.renderCoordElistBracketed
  , pvtRendererPretty :: CoordList -> Render ()
pvtRendererPretty = CoordList -> Render ()
R.renderCoordElistPretty
  }

coordListPvt :: PropertyValueType CoordList
coordListPvt :: PropertyValueType CoordList
coordListPvt = PropertyValueType :: forall a.
Parser a
-> (a -> Render ()) -> (a -> Render ()) -> PropertyValueType a
PropertyValueType
  { pvtParser :: Parser CoordList
pvtParser = Parser CoordList
P.coordListParser
  , pvtRenderer :: CoordList -> Render ()
pvtRenderer = CoordList -> Render ()
R.renderCoordListBracketed
  , pvtRendererPretty :: CoordList -> Render ()
pvtRendererPretty = CoordList -> Render ()
R.renderCoordListPretty
  }

coordPairListPvt :: PropertyValueType [(Coord, Coord)]
coordPairListPvt :: PropertyValueType [(Coord, Coord)]
coordPairListPvt = PropertyValueType :: forall a.
Parser a
-> (a -> Render ()) -> (a -> Render ()) -> PropertyValueType a
PropertyValueType
  { pvtParser :: Parser [(Coord, Coord)]
pvtParser = Parser [(Coord, Coord)]
P.coordPairListParser
  , pvtRenderer :: [(Coord, Coord)] -> Render ()
pvtRenderer = [(Coord, Coord)] -> Render ()
R.renderCoordPairListBracketed
  , pvtRendererPretty :: [(Coord, Coord)] -> Render ()
pvtRendererPretty = [(Coord, Coord)] -> Render ()
R.renderCoordPairListPretty
  }

doublePvt :: PropertyValueType DoubleValue
doublePvt :: PropertyValueType DoubleValue
doublePvt = PropertyValueType :: forall a.
Parser a
-> (a -> Render ()) -> (a -> Render ()) -> PropertyValueType a
PropertyValueType
  { pvtParser :: Parser DoubleValue
pvtParser = Parser DoubleValue
P.doubleParser
  , pvtRenderer :: DoubleValue -> Render ()
pvtRenderer = DoubleValue -> Render ()
R.renderDoubleBracketed
  , pvtRendererPretty :: DoubleValue -> Render ()
pvtRendererPretty = DoubleValue -> Render ()
R.renderDoublePretty
  }

gameResultPvt :: PropertyValueType GameResult
gameResultPvt :: PropertyValueType GameResult
gameResultPvt = PropertyValueType :: forall a.
Parser a
-> (a -> Render ()) -> (a -> Render ()) -> PropertyValueType a
PropertyValueType
  { pvtParser :: Parser GameResult
pvtParser = Parser GameResult
P.gameResultParser
  , pvtRenderer :: GameResult -> Render ()
pvtRenderer = GameResult -> Render ()
R.renderGameResultBracketed
  , pvtRendererPretty :: GameResult -> Render ()
pvtRendererPretty = GameResult -> Render ()
R.renderGameResultPretty
  }

integralPvt :: (Integral a, Read a, Show a) => PropertyValueType a
integralPvt :: PropertyValueType a
integralPvt = PropertyValueType :: forall a.
Parser a
-> (a -> Render ()) -> (a -> Render ()) -> PropertyValueType a
PropertyValueType
  { pvtParser :: Parser a
pvtParser = Parser a
forall a. (Integral a, Read a) => Parser a
P.integralParser
  , pvtRenderer :: a -> Render ()
pvtRenderer = a -> Render ()
forall a. (Integral a, Show a) => a -> Render ()
R.renderIntegralBracketed
  , pvtRendererPretty :: a -> Render ()
pvtRendererPretty = a -> Render ()
forall a. (Integral a, Show a) => a -> Render ()
R.renderIntegralPretty
  }

labelListPvt :: PropertyValueType [(Coord, SimpleText)]
labelListPvt :: PropertyValueType [(Coord, SimpleText)]
labelListPvt = PropertyValueType :: forall a.
Parser a
-> (a -> Render ()) -> (a -> Render ()) -> PropertyValueType a
PropertyValueType
  { pvtParser :: Parser [(Coord, SimpleText)]
pvtParser = Parser [(Coord, SimpleText)]
P.labelListParser
  , pvtRenderer :: [(Coord, SimpleText)] -> Render ()
pvtRenderer = [(Coord, SimpleText)] -> Render ()
R.renderLabelListBracketed
  , pvtRendererPretty :: [(Coord, SimpleText)] -> Render ()
pvtRendererPretty = [(Coord, SimpleText)] -> Render ()
R.renderLabelListPretty
  }

lineListPvt :: PropertyValueType [Line]
lineListPvt :: PropertyValueType [Line]
lineListPvt = PropertyValueType :: forall a.
Parser a
-> (a -> Render ()) -> (a -> Render ()) -> PropertyValueType a
PropertyValueType
  { pvtParser :: Parser [Line]
pvtParser = Parser [Line]
P.lineListParser
  , pvtRenderer :: [Line] -> Render ()
pvtRenderer = [Line] -> Render ()
R.renderLineListBracketed
  , pvtRendererPretty :: [Line] -> Render ()
pvtRendererPretty = [Line] -> Render ()
R.renderLineListPretty
  }

movePvt :: PropertyValueType (Maybe Coord)
movePvt :: PropertyValueType (Maybe Coord)
movePvt = PropertyValueType :: forall a.
Parser a
-> (a -> Render ()) -> (a -> Render ()) -> PropertyValueType a
PropertyValueType
  { pvtParser :: Parser (Maybe Coord)
pvtParser = Parser (Maybe Coord)
P.moveParser
  , pvtRenderer :: Maybe Coord -> Render ()
pvtRenderer = Maybe Coord -> Render ()
R.renderMoveBracketed
  , pvtRendererPretty :: Maybe Coord -> Render ()
pvtRendererPretty = Maybe Coord -> Render ()
R.renderMovePretty
  }

nonePvt :: PropertyValueType ()
nonePvt :: PropertyValueType ()
nonePvt = PropertyValueType :: forall a.
Parser a
-> (a -> Render ()) -> (a -> Render ()) -> PropertyValueType a
PropertyValueType
  { pvtParser :: Parser ()
pvtParser = Parser ()
P.noneParser
  , pvtRenderer :: () -> Render ()
pvtRenderer = () -> Render ()
R.renderNoneBracketed
  , pvtRendererPretty :: () -> Render ()
pvtRendererPretty = () -> Render ()
R.renderNonePretty
  }

realPvt :: PropertyValueType RealValue
realPvt :: PropertyValueType RealValue
realPvt = PropertyValueType :: forall a.
Parser a
-> (a -> Render ()) -> (a -> Render ()) -> PropertyValueType a
PropertyValueType
  { pvtParser :: Parser RealValue
pvtParser = Parser RealValue
P.realParser
  , pvtRenderer :: RealValue -> Render ()
pvtRenderer = RealValue -> Render ()
R.renderRealBracketed
  , pvtRendererPretty :: RealValue -> Render ()
pvtRendererPretty = RealValue -> Render ()
R.renderRealPretty
  }

rulesetPvt :: PropertyValueType Ruleset
rulesetPvt :: PropertyValueType Ruleset
rulesetPvt = PropertyValueType :: forall a.
Parser a
-> (a -> Render ()) -> (a -> Render ()) -> PropertyValueType a
PropertyValueType
  { pvtParser :: Parser Ruleset
pvtParser = Parser Ruleset
P.rulesetParser
  , pvtRenderer :: Ruleset -> Render ()
pvtRenderer = Ruleset -> Render ()
R.renderRulesetBracketed
  , pvtRendererPretty :: Ruleset -> Render ()
pvtRendererPretty = Ruleset -> Render ()
R.renderRulesetPretty
  }

simpleTextPairPvt :: PropertyValueType (SimpleText, SimpleText)
simpleTextPairPvt :: PropertyValueType (SimpleText, SimpleText)
simpleTextPairPvt = PropertyValueType :: forall a.
Parser a
-> (a -> Render ()) -> (a -> Render ()) -> PropertyValueType a
PropertyValueType
  { pvtParser :: Parser (SimpleText, SimpleText)
pvtParser = Parser (SimpleText, SimpleText)
P.simpleTextPairParser
  , pvtRenderer :: (SimpleText, SimpleText) -> Render ()
pvtRenderer = (SimpleText, SimpleText) -> Render ()
R.renderSimpleTextPairBracketed
  , pvtRendererPretty :: (SimpleText, SimpleText) -> Render ()
pvtRendererPretty = (SimpleText, SimpleText) -> Render ()
R.renderSimpleTextPairPretty
  }

simpleTextPvt :: PropertyValueType SimpleText
simpleTextPvt :: PropertyValueType SimpleText
simpleTextPvt = PropertyValueType :: forall a.
Parser a
-> (a -> Render ()) -> (a -> Render ()) -> PropertyValueType a
PropertyValueType
  { pvtParser :: Parser SimpleText
pvtParser = Parser SimpleText
P.simpleTextParser
  , pvtRenderer :: SimpleText -> Render ()
pvtRenderer = SimpleText -> Render ()
R.renderSimpleTextBracketed
  , pvtRendererPretty :: SimpleText -> Render ()
pvtRendererPretty = SimpleText -> Render ()
R.renderSimpleTextPretty
  }

sizePvt :: PropertyValueType (Int, Int)
sizePvt :: PropertyValueType Coord
sizePvt = PropertyValueType :: forall a.
Parser a
-> (a -> Render ()) -> (a -> Render ()) -> PropertyValueType a
PropertyValueType
  { pvtParser :: Parser Coord
pvtParser = Parser Coord
P.sizeParser
  , pvtRenderer :: Coord -> Render ()
pvtRenderer = Coord -> Render ()
R.renderSizeBracketed
  , pvtRendererPretty :: Coord -> Render ()
pvtRendererPretty = Coord -> Render ()
R.renderSizePretty
  }

textPvt :: PropertyValueType Text
textPvt :: PropertyValueType Text
textPvt = PropertyValueType :: forall a.
Parser a
-> (a -> Render ()) -> (a -> Render ()) -> PropertyValueType a
PropertyValueType
  { pvtParser :: Parser Text
pvtParser = Parser Text
P.textParser
  , pvtRenderer :: Text -> Render ()
pvtRenderer = Text -> Render ()
R.renderTextBracketed
  , pvtRendererPretty :: Text -> Render ()
pvtRendererPretty = Text -> Render ()
R.renderTextPretty
  }

unknownPropertyPvt :: PropertyValueType UnknownPropertyValue
unknownPropertyPvt :: PropertyValueType UnknownPropertyValue
unknownPropertyPvt = PropertyValueType :: forall a.
Parser a
-> (a -> Render ()) -> (a -> Render ()) -> PropertyValueType a
PropertyValueType
  { pvtParser :: Parser UnknownPropertyValue
pvtParser = Parser UnknownPropertyValue
P.unknownPropertyParser
  , pvtRenderer :: UnknownPropertyValue -> Render ()
pvtRenderer = UnknownPropertyValue -> Render ()
R.renderUnknownPropertyBracketed
  , pvtRendererPretty :: UnknownPropertyValue -> Render ()
pvtRendererPretty = UnknownPropertyValue -> Render ()
R.renderUnknownPropertyPretty
  }

variationModePvt :: PropertyValueType VariationMode
variationModePvt :: PropertyValueType VariationMode
variationModePvt = PropertyValueType :: forall a.
Parser a
-> (a -> Render ()) -> (a -> Render ()) -> PropertyValueType a
PropertyValueType
  { pvtParser :: Parser VariationMode
pvtParser = Parser VariationMode
P.variationModeParser
  , pvtRenderer :: VariationMode -> Render ()
pvtRenderer = VariationMode -> Render ()
R.renderVariationModeBracketed
  , pvtRendererPretty :: VariationMode -> Render ()
pvtRendererPretty = VariationMode -> Render ()
R.renderVariationModePretty
  }