{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
module Codec.Xlsx.Types.Internal.FormulaData where

import Data.Monoid ((<>))
import Data.Text (Text)
import qualified Data.Text as T
import GHC.Generics (Generic)

import Codec.Xlsx.Parser.Internal
import Codec.Xlsx.Types.Cell
import Codec.Xlsx.Types.Common

data FormulaData = FormulaData
  { FormulaData -> CellFormula
frmdFormula :: CellFormula
  , FormulaData -> Maybe (SharedFormulaIndex, SharedFormulaOptions)
frmdShared :: Maybe (SharedFormulaIndex, SharedFormulaOptions)
  } deriving forall x. Rep FormulaData x -> FormulaData
forall x. FormulaData -> Rep FormulaData x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep FormulaData x -> FormulaData
$cfrom :: forall x. FormulaData -> Rep FormulaData x
Generic

defaultFormulaType :: Text
defaultFormulaType :: Text
defaultFormulaType = Text
"normal"

instance FromXenoNode FormulaData where
  fromXenoNode :: Node -> Either Text FormulaData
fromXenoNode Node
n = do
    (Bool
bx, Bool
ca, Text
t, Maybe SharedFormulaIndex
mSi, Maybe CellRef
mRef) <-
      forall a. Node -> AttrParser a -> Either Text a
parseAttributes Node
n forall a b. (a -> b) -> a -> b
$
      (,,,,) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. FromAttrBs a => ByteString -> a -> AttrParser a
fromAttrDef ByteString
"bx" Bool
False
             forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. FromAttrBs a => ByteString -> a -> AttrParser a
fromAttrDef ByteString
"ca" Bool
False
             forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. FromAttrBs a => ByteString -> a -> AttrParser a
fromAttrDef ByteString
"t" Text
defaultFormulaType
             forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. FromAttrBs a => ByteString -> AttrParser (Maybe a)
maybeAttr ByteString
"si"
             forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. FromAttrBs a => ByteString -> AttrParser (Maybe a)
maybeAttr ByteString
"ref"
    (FormulaExpression
expr, Maybe (SharedFormulaIndex, SharedFormulaOptions)
shared) <-
      case Text
t of
        Text
d | Text
d forall a. Eq a => a -> a -> Bool
== Text
defaultFormulaType -> do
            Text
formula <- Node -> Either Text Text
contentX Node
n
            forall (m :: * -> *) a. Monad m => a -> m a
return (Formula -> FormulaExpression
NormalFormula forall a b. (a -> b) -> a -> b
$ Text -> Formula
Formula Text
formula, forall a. Maybe a
Nothing)
        Text
"shared" -> do
          SharedFormulaIndex
si <-
            forall b a. b -> (a -> b) -> Maybe a -> b
maybe
              (forall a b. a -> Either a b
Left Text
"missing si attribute for shared formula")
              forall (m :: * -> *) a. Monad m => a -> m a
return
              Maybe SharedFormulaIndex
mSi
          Formula
formula <- Text -> Formula
Formula forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Node -> Either Text Text
contentX Node
n
          forall (m :: * -> *) a. Monad m => a -> m a
return
            ( SharedFormulaIndex -> FormulaExpression
SharedFormula SharedFormulaIndex
si
            , Maybe CellRef
mRef forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \CellRef
ref -> forall (m :: * -> *) a. Monad m => a -> m a
return (SharedFormulaIndex
si, (CellRef -> Formula -> SharedFormulaOptions
SharedFormulaOptions CellRef
ref Formula
formula)))
        Text
unexpected -> forall a b. a -> Either a b
Left forall a b. (a -> b) -> a -> b
$ Text
"Unexpected formula type" forall a. Semigroup a => a -> a -> a
<> String -> Text
T.pack (forall a. Show a => a -> String
show Text
unexpected)
    let f :: CellFormula
f =
          CellFormula
          { _cellfAssignsToName :: Bool
_cellfAssignsToName = Bool
bx
          , _cellfCalculate :: Bool
_cellfCalculate = Bool
ca
          , _cellfExpression :: FormulaExpression
_cellfExpression = FormulaExpression
expr
          }
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ CellFormula
-> Maybe (SharedFormulaIndex, SharedFormulaOptions) -> FormulaData
FormulaData CellFormula
f Maybe (SharedFormulaIndex, SharedFormulaOptions)
shared