-- Copyright (c) 2016-present, Facebook, Inc.
-- All rights reserved.
--
-- This source code is licensed under the BSD-style license found in the
-- LICENSE file in the root directory of this source tree.


{-# LANGUAGE GADTs #-}


module Duckling.Volume.Helpers
  ( isSimpleVolume
  , isUnitOnly
  , volume
  , unitOnly
  , valueOnly
  , withUnit
  , withValue
  , withInterval
  , withMin
  , withMax
  ) where

import Data.Text (Text)
import Prelude

import Duckling.Dimensions.Types
import Duckling.Volume.Types (Unit(..), VolumeData(..))
import Duckling.Types
import qualified Duckling.Volume.Types as TVolume

-- -----------------------------------------------------------------
-- Patterns

isSimpleVolume :: Predicate
isSimpleVolume :: Predicate
isSimpleVolume (Token Dimension a
Volume VolumeData {TVolume.value = Just _
                                        , TVolume.minValue = Nothing
                                        , TVolume.maxValue = Nothing}) = Bool
True
isSimpleVolume Token
_ = Bool
False

isUnitOnly :: Predicate
isUnitOnly :: Predicate
isUnitOnly (Token Dimension a
Volume VolumeData {TVolume.value = Nothing
                                    , TVolume.unit = Just _
                                    , TVolume.minValue = Nothing
                                    , TVolume.maxValue = Nothing}) = Bool
True
isUnitOnly Token
_ = Bool
False

-- -----------------------------------------------------------------
-- Production

volume :: Unit -> Double -> VolumeData
volume :: Unit -> Double -> VolumeData
volume Unit
u Double
v = VolumeData :: Maybe Double
-> Maybe Unit -> Maybe Double -> Maybe Double -> VolumeData
VolumeData {unit :: Maybe Unit
TVolume.unit = Unit -> Maybe Unit
forall a. a -> Maybe a
Just Unit
u
                        , value :: Maybe Double
TVolume.value = Double -> Maybe Double
forall a. a -> Maybe a
Just Double
v
                        , minValue :: Maybe Double
TVolume.minValue = Maybe Double
forall a. Maybe a
Nothing
                        , maxValue :: Maybe Double
TVolume.maxValue = Maybe Double
forall a. Maybe a
Nothing}

unitOnly :: Unit -> VolumeData
unitOnly :: Unit -> VolumeData
unitOnly Unit
u = VolumeData :: Maybe Double
-> Maybe Unit -> Maybe Double -> Maybe Double -> VolumeData
VolumeData {unit :: Maybe Unit
TVolume.unit = Unit -> Maybe Unit
forall a. a -> Maybe a
Just Unit
u
                        , value :: Maybe Double
TVolume.value = Maybe Double
forall a. Maybe a
Nothing
                        , minValue :: Maybe Double
TVolume.minValue = Maybe Double
forall a. Maybe a
Nothing
                        , maxValue :: Maybe Double
TVolume.maxValue = Maybe Double
forall a. Maybe a
Nothing}

valueOnly :: Double -> VolumeData
valueOnly :: Double -> VolumeData
valueOnly Double
v = VolumeData :: Maybe Double
-> Maybe Unit -> Maybe Double -> Maybe Double -> VolumeData
VolumeData {unit :: Maybe Unit
TVolume.unit = Maybe Unit
forall a. Maybe a
Nothing
                        , value :: Maybe Double
TVolume.value = Double -> Maybe Double
forall a. a -> Maybe a
Just Double
v
                        , minValue :: Maybe Double
TVolume.minValue = Maybe Double
forall a. Maybe a
Nothing
                        , maxValue :: Maybe Double
TVolume.maxValue = Maybe Double
forall a. Maybe a
Nothing}

withUnit :: Unit -> VolumeData -> VolumeData
withUnit :: Unit -> VolumeData -> VolumeData
withUnit Unit
u VolumeData
vd = VolumeData
vd {unit :: Maybe Unit
TVolume.unit = Unit -> Maybe Unit
forall a. a -> Maybe a
Just Unit
u}

withValue :: Double -> VolumeData -> VolumeData
withValue :: Double -> VolumeData -> VolumeData
withValue Double
v VolumeData
vd = VolumeData
vd {value :: Maybe Double
TVolume.value = Double -> Maybe Double
forall a. a -> Maybe a
Just Double
v}

withInterval :: (Double, Double) -> VolumeData -> VolumeData
withInterval :: (Double, Double) -> VolumeData -> VolumeData
withInterval (Double
from, Double
to) VolumeData
vd = VolumeData
vd {value :: Maybe Double
TVolume.value = Maybe Double
forall a. Maybe a
Nothing
                                , minValue :: Maybe Double
TVolume.minValue = Double -> Maybe Double
forall a. a -> Maybe a
Just Double
from
                                , maxValue :: Maybe Double
TVolume.maxValue = Double -> Maybe Double
forall a. a -> Maybe a
Just Double
to}

withMin :: Double -> VolumeData -> VolumeData
withMin :: Double -> VolumeData -> VolumeData
withMin Double
from VolumeData
vd = VolumeData
vd {minValue :: Maybe Double
TVolume.minValue = Double -> Maybe Double
forall a. a -> Maybe a
Just Double
from}

withMax :: Double -> VolumeData -> VolumeData
withMax :: Double -> VolumeData -> VolumeData
withMax Double
to VolumeData
vd = VolumeData
vd {maxValue :: Maybe Double
TVolume.maxValue = Double -> Maybe Double
forall a. a -> Maybe a
Just Double
to}