module Language.Drasil.Printing.Import.Literal (literal) where


import Language.Drasil hiding (neg, sec, symbol, isIn)
import Language.Drasil.Literal.Development (Literal(..))

import qualified Language.Drasil.Printing.AST as P
import Language.Drasil.Printing.PrintingInformation (HasPrintingOptions(..),
  PrintingInformation, Notation(Scientific, Engineering))

import Control.Lens ((^.))
import Numeric (floatToDigits)

import Language.Drasil.Printing.Import.Helpers
    (digitsProcess, processExpo)

literal :: Literal -> PrintingInformation -> P.Expr
literal :: Literal -> PrintingInformation -> Expr
literal (Dbl Double
d)                  PrintingInformation
sm = case PrintingInformation
sm PrintingInformation
-> Getting Notation PrintingInformation Notation -> Notation
forall s a. s -> Getting a s a -> a
^. Getting Notation PrintingInformation Notation
forall c. HasPrintingOptions c => Lens' c Notation
Lens' PrintingInformation Notation
getSetting of
  Notation
Engineering -> [Expr] -> Expr
P.Row ([Expr] -> Expr) -> [Expr] -> Expr
forall a b. (a -> b) -> a -> b
$ [Integer] -> Int -> Int -> Integer -> [Expr]
digitsProcess ((Int -> Integer) -> [Int] -> [Integer]
forall a b. (a -> b) -> [a] -> [b]
map Int -> Integer
forall a. Integral a => a -> Integer
toInteger ([Int] -> [Integer]) -> [Int] -> [Integer]
forall a b. (a -> b) -> a -> b
$ ([Int], Int) -> [Int]
forall a b. (a, b) -> a
fst (([Int], Int) -> [Int]) -> ([Int], Int) -> [Int]
forall a b. (a -> b) -> a -> b
$ Integer -> Double -> ([Int], Int)
forall a. RealFloat a => Integer -> a -> ([Int], Int)
floatToDigits Integer
10 Double
d)
     ((Int, Int) -> Int
forall a b. (a, b) -> a
fst ((Int, Int) -> Int) -> (Int, Int) -> Int
forall a b. (a -> b) -> a -> b
$ Int -> (Int, Int)
processExpo (Int -> (Int, Int)) -> Int -> (Int, Int)
forall a b. (a -> b) -> a -> b
$ ([Int], Int) -> Int
forall a b. (a, b) -> b
snd (([Int], Int) -> Int) -> ([Int], Int) -> Int
forall a b. (a -> b) -> a -> b
$ Integer -> Double -> ([Int], Int)
forall a. RealFloat a => Integer -> a -> ([Int], Int)
floatToDigits Integer
10 Double
d) Int
0
     (Int -> Integer
forall a. Integral a => a -> Integer
toInteger (Int -> Integer) -> Int -> Integer
forall a b. (a -> b) -> a -> b
$ (Int, Int) -> Int
forall a b. (a, b) -> b
snd ((Int, Int) -> Int) -> (Int, Int) -> Int
forall a b. (a -> b) -> a -> b
$ Int -> (Int, Int)
processExpo (Int -> (Int, Int)) -> Int -> (Int, Int)
forall a b. (a -> b) -> a -> b
$ ([Int], Int) -> Int
forall a b. (a, b) -> b
snd (([Int], Int) -> Int) -> ([Int], Int) -> Int
forall a b. (a -> b) -> a -> b
$ Integer -> Double -> ([Int], Int)
forall a. RealFloat a => Integer -> a -> ([Int], Int)
floatToDigits Integer
10 Double
d)
  Notation
Scientific  ->  Double -> Expr
P.Dbl Double
d
literal (Int Integer
i)                   PrintingInformation
_ = Integer -> Expr
P.Int Integer
i
literal (ExactDbl Integer
d)              PrintingInformation
_ = Integer -> Expr
P.Int Integer
d
literal (Str String
s)                   PrintingInformation
_ = String -> Expr
P.Str String
s
literal (Perc Integer
a Integer
b)               PrintingInformation
sm = [Expr] -> Expr
P.Row [Literal -> PrintingInformation -> Expr
literal (Double -> Literal
forall r. LiteralC r => Double -> r
dbl Double
val) PrintingInformation
sm, Ops -> Expr
P.MO Ops
P.Perc]
  where
    val :: Double
val = Integer -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Integer
a Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ (Double
10 Double -> Double -> Double
forall a. Floating a => a -> a -> a
** Integer -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer
b Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
2))