-- | Lincoln - the Penny core
--
-- Penny's core types and classes are here. This module re-exports the
-- most useful things. For more details you will want to look at the
-- sub-modules. Also, not all types and functions are re-exported due
-- to naming conflicts. In particular, neither
-- "Penny.Lincoln.Predicates" nor "Penny.Lincoln.Queries" is exported
-- from here due to the blizzard of name conflicts that would result.
module Penny.Lincoln
  ( module Penny.Lincoln.Balance
  , module Penny.Lincoln.Bits
  , module Penny.Lincoln.Builders
  , module Penny.Lincoln.Ents
  , module Penny.Lincoln.Equivalent
  , module Penny.Lincoln.HasText
  , module Penny.Lincoln.Matchers
  , module Penny.Lincoln.Natural
  , module Penny.Lincoln.PriceDb
  , module Penny.Lincoln.Serial
  , display
  ) where

import Penny.Lincoln.Bits
import Penny.Lincoln.Ents
import Penny.Lincoln.Balance
import Penny.Lincoln.Builders
import Penny.Lincoln.Equivalent
import Penny.Lincoln.HasText
import Penny.Lincoln.Matchers
import Penny.Lincoln.Natural
import Penny.Lincoln.PriceDb
import Penny.Lincoln.Serial

import Data.List (intersperse)
import Data.Text (Text)
import qualified Data.Text as X
import qualified Penny.Lincoln.Queries as Q
import qualified Data.Time as Time
import System.Locale (defaultTimeLocale)

--
-- Display
--

-- | Displays a PostFam in a one line format.
--
-- Format:
--
-- File LineNo Date Payee Acct DrCr Cmdty Qty
display
  :: (Amount Qty -> X.Text)
  -- ^ How to format Qty that do not have a QtyRep
  -> Posting
  -> Text
display fmt p = X.pack $ concat (intersperse " " ls)
  where
    ls = [file, lineNo, dt, pye, acct, dc, cmdty, qt]
    file = maybe (labelNo "filename") (X.unpack . unFilename)
           (fmap tFilename . tlFileMeta . fst . unPosting $ p)
    lineNo = maybe (labelNo "line number")
             (show . unPostingLine)
             (Q.postingLine p)
    dateFormat = "%Y-%m-%d %T %z"
    dt = Time.formatTime defaultTimeLocale dateFormat
         . Time.utctDay
         . toUTC
         . Q.dateTime
         $ p
    pye = maybe (labelNo "payee")
            (X.unpack . text) (Q.payee p)
    acct = X.unpack . X.intercalate (X.singleton ':')
           . map unSubAccount . unAccount . Q.account $ p
    dc = case Q.drCr p of
      Debit -> "Dr"
      Credit -> "Cr"
    cmdty = X.unpack . unCommodity . Q.commodity $ p
    getFmt q = fmt $ Amount q (Q.commodity p)
    qt = X.unpack . either showQtyRep getFmt . Q.eiQty $ p
    labelNo s = "(no " ++ s ++ ")"