{- |
Rich data type to describe data in a table.
This is the basis for ODS and HTML export.
-}
module Hledger.Write.Spreadsheet (
    Type(..),
    Style(..),
    Emphasis(..),
    Cell(..),
    defaultCell,
    emptyCell,
    ) where

import Hledger.Data.Types (Amount)


data Type =
      TypeString
    | TypeAmount !Amount
    | TypeMixedAmount
    | TypeDate
    deriving (Type -> Type -> Bool
(Type -> Type -> Bool) -> (Type -> Type -> Bool) -> Eq Type
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Type -> Type -> Bool
== :: Type -> Type -> Bool
$c/= :: Type -> Type -> Bool
/= :: Type -> Type -> Bool
Eq, Eq Type
Eq Type =>
(Type -> Type -> Ordering)
-> (Type -> Type -> Bool)
-> (Type -> Type -> Bool)
-> (Type -> Type -> Bool)
-> (Type -> Type -> Bool)
-> (Type -> Type -> Type)
-> (Type -> Type -> Type)
-> Ord Type
Type -> Type -> Bool
Type -> Type -> Ordering
Type -> Type -> Type
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Type -> Type -> Ordering
compare :: Type -> Type -> Ordering
$c< :: Type -> Type -> Bool
< :: Type -> Type -> Bool
$c<= :: Type -> Type -> Bool
<= :: Type -> Type -> Bool
$c> :: Type -> Type -> Bool
> :: Type -> Type -> Bool
$c>= :: Type -> Type -> Bool
>= :: Type -> Type -> Bool
$cmax :: Type -> Type -> Type
max :: Type -> Type -> Type
$cmin :: Type -> Type -> Type
min :: Type -> Type -> Type
Ord, Int -> Type -> ShowS
[Type] -> ShowS
Type -> String
(Int -> Type -> ShowS)
-> (Type -> String) -> ([Type] -> ShowS) -> Show Type
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Type -> ShowS
showsPrec :: Int -> Type -> ShowS
$cshow :: Type -> String
show :: Type -> String
$cshowList :: [Type] -> ShowS
showList :: [Type] -> ShowS
Show)

data Style = Body Emphasis | Head
    deriving (Style -> Style -> Bool
(Style -> Style -> Bool) -> (Style -> Style -> Bool) -> Eq Style
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Style -> Style -> Bool
== :: Style -> Style -> Bool
$c/= :: Style -> Style -> Bool
/= :: Style -> Style -> Bool
Eq, Eq Style
Eq Style =>
(Style -> Style -> Ordering)
-> (Style -> Style -> Bool)
-> (Style -> Style -> Bool)
-> (Style -> Style -> Bool)
-> (Style -> Style -> Bool)
-> (Style -> Style -> Style)
-> (Style -> Style -> Style)
-> Ord Style
Style -> Style -> Bool
Style -> Style -> Ordering
Style -> Style -> Style
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Style -> Style -> Ordering
compare :: Style -> Style -> Ordering
$c< :: Style -> Style -> Bool
< :: Style -> Style -> Bool
$c<= :: Style -> Style -> Bool
<= :: Style -> Style -> Bool
$c> :: Style -> Style -> Bool
> :: Style -> Style -> Bool
$c>= :: Style -> Style -> Bool
>= :: Style -> Style -> Bool
$cmax :: Style -> Style -> Style
max :: Style -> Style -> Style
$cmin :: Style -> Style -> Style
min :: Style -> Style -> Style
Ord, Int -> Style -> ShowS
[Style] -> ShowS
Style -> String
(Int -> Style -> ShowS)
-> (Style -> String) -> ([Style] -> ShowS) -> Show Style
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Style -> ShowS
showsPrec :: Int -> Style -> ShowS
$cshow :: Style -> String
show :: Style -> String
$cshowList :: [Style] -> ShowS
showList :: [Style] -> ShowS
Show)

data Emphasis = Item | Total
    deriving (Emphasis -> Emphasis -> Bool
(Emphasis -> Emphasis -> Bool)
-> (Emphasis -> Emphasis -> Bool) -> Eq Emphasis
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Emphasis -> Emphasis -> Bool
== :: Emphasis -> Emphasis -> Bool
$c/= :: Emphasis -> Emphasis -> Bool
/= :: Emphasis -> Emphasis -> Bool
Eq, Eq Emphasis
Eq Emphasis =>
(Emphasis -> Emphasis -> Ordering)
-> (Emphasis -> Emphasis -> Bool)
-> (Emphasis -> Emphasis -> Bool)
-> (Emphasis -> Emphasis -> Bool)
-> (Emphasis -> Emphasis -> Bool)
-> (Emphasis -> Emphasis -> Emphasis)
-> (Emphasis -> Emphasis -> Emphasis)
-> Ord Emphasis
Emphasis -> Emphasis -> Bool
Emphasis -> Emphasis -> Ordering
Emphasis -> Emphasis -> Emphasis
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Emphasis -> Emphasis -> Ordering
compare :: Emphasis -> Emphasis -> Ordering
$c< :: Emphasis -> Emphasis -> Bool
< :: Emphasis -> Emphasis -> Bool
$c<= :: Emphasis -> Emphasis -> Bool
<= :: Emphasis -> Emphasis -> Bool
$c> :: Emphasis -> Emphasis -> Bool
> :: Emphasis -> Emphasis -> Bool
$c>= :: Emphasis -> Emphasis -> Bool
>= :: Emphasis -> Emphasis -> Bool
$cmax :: Emphasis -> Emphasis -> Emphasis
max :: Emphasis -> Emphasis -> Emphasis
$cmin :: Emphasis -> Emphasis -> Emphasis
min :: Emphasis -> Emphasis -> Emphasis
Ord, Int -> Emphasis -> ShowS
[Emphasis] -> ShowS
Emphasis -> String
(Int -> Emphasis -> ShowS)
-> (Emphasis -> String) -> ([Emphasis] -> ShowS) -> Show Emphasis
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Emphasis -> ShowS
showsPrec :: Int -> Emphasis -> ShowS
$cshow :: Emphasis -> String
show :: Emphasis -> String
$cshowList :: [Emphasis] -> ShowS
showList :: [Emphasis] -> ShowS
Show)

data Cell text =
    Cell {
        forall text. Cell text -> Type
cellType :: Type,
        forall text. Cell text -> Style
cellStyle :: Style,
        forall text. Cell text -> text
cellContent :: text
    }

instance Functor Cell where
    fmap :: forall a b. (a -> b) -> Cell a -> Cell b
fmap a -> b
f (Cell Type
typ Style
style a
content) = Type -> Style -> b -> Cell b
forall text. Type -> Style -> text -> Cell text
Cell Type
typ Style
style (b -> Cell b) -> b -> Cell b
forall a b. (a -> b) -> a -> b
$ a -> b
f a
content

defaultCell :: text -> Cell text
defaultCell :: forall text. text -> Cell text
defaultCell text
text =
    Cell {
        cellType :: Type
cellType = Type
TypeString,
        cellStyle :: Style
cellStyle = Emphasis -> Style
Body Emphasis
Item,
        cellContent :: text
cellContent = text
text
    }

emptyCell :: (Monoid text) => Cell text
emptyCell :: forall text. Monoid text => Cell text
emptyCell = text -> Cell text
forall text. text -> Cell text
defaultCell text
forall a. Monoid a => a
mempty