-- | Defines units for use in Drasil. Often used in a unital-related chunk that has an associated symbol.
module Data.Drasil.SI_Units where

import Language.Drasil
import Language.Drasil.Display (Symbol(Special))
import Language.Drasil.ShortHands (cOmega)

-- * Lists of Units

fundamentals :: [UnitDefn]
fundamentals :: [UnitDefn]
fundamentals = [UnitDefn
metre, UnitDefn
kilogram, UnitDefn
second, UnitDefn
kelvin, UnitDefn
mole, UnitDefn
ampere, UnitDefn
candela]

derived :: [UnitDefn]
derived :: [UnitDefn]
derived = [UnitDefn
becquerel, UnitDefn
calorie, UnitDefn
centigrade, UnitDefn
coulomb, UnitDefn
farad, UnitDefn
gray, UnitDefn
henry, UnitDefn
hertz, UnitDefn
joule,
  UnitDefn
katal, UnitDefn
kilopascal, UnitDefn
kilowatt, UnitDefn
litre, UnitDefn
lumen, UnitDefn
lux,  UnitDefn
millimetre, UnitDefn
newton, UnitDefn
ohm,
  UnitDefn
pascal, UnitDefn
radian, UnitDefn
siemens, UnitDefn
sievert, UnitDefn
steradian, UnitDefn
tesla, UnitDefn
volt, UnitDefn
watt, UnitDefn
weber]

common :: [UnitDefn]
common :: [UnitDefn]
common = [UnitDefn
s_2, UnitDefn
m_2, UnitDefn
m_3]

siUnits :: [UnitDefn]
siUnits :: [UnitDefn]
siUnits = [UnitDefn]
fundamentals [UnitDefn] -> [UnitDefn] -> [UnitDefn]
forall a. Semigroup a => a -> a -> a
<> [UnitDefn]
derived [UnitDefn] -> [UnitDefn] -> [UnitDefn]
forall a. Semigroup a => a -> a -> a
<> [UnitDefn]
common

-- * Fundamental SI Units

metre, kilogram, second, kelvin, mole, ampere, candela :: UnitDefn
metre :: UnitDefn
metre    = String -> NP -> String -> Symbol -> UnitDefn
baseUnit String
"metre"    (String -> NP
forall a. String -> NPG a
cn' String
"metre")    String
"length"              (String -> Symbol
label String
"m")
kilogram :: UnitDefn
kilogram = String -> NP -> String -> Symbol -> UnitDefn
baseUnit String
"kilogram" (String -> NP
forall a. String -> NPG a
cn' String
"kilogram") String
"mass"                (String -> Symbol
label String
"kg")
second :: UnitDefn
second   = String -> NP -> String -> Symbol -> UnitDefn
baseUnit String
"second"   (String -> NP
forall a. String -> NPG a
cn' String
"second")   String
"time"                (String -> Symbol
label String
"s")
kelvin :: UnitDefn
kelvin   = String -> NP -> String -> Symbol -> UnitDefn
baseUnit String
"kelvin"   (String -> NP
forall a. String -> NPG a
cn' String
"kelvin")   String
"temperature"         (String -> Symbol
label String
"K")
mole :: UnitDefn
mole     = String -> NP -> String -> Symbol -> UnitDefn
baseUnit String
"mole"     (String -> NP
forall a. String -> NPG a
cn' String
"mole")     String
"amount of substance" (String -> Symbol
label String
"mol")
ampere :: UnitDefn
ampere   = String -> NP -> String -> Symbol -> UnitDefn
baseUnit String
"ampere"   (String -> NP
forall a. String -> NPG a
cn' String
"ampere")   String
"electric current"    (String -> Symbol
label String
"A")
candela :: UnitDefn
candela  = String -> NP -> String -> Symbol -> UnitDefn
baseUnit String
"candela"  (String -> NP
forall a. String -> NPG a
cn' String
"candela")  String
"luminous intensity"  (String -> Symbol
label String
"cd")

-- * Commonly Defined Units

degree :: UnitDefn --FIXME: define degree in terms of radians and pi
degree :: UnitDefn
degree = String -> NP -> String -> Symbol -> UnitDefn
baseUnit String
"degree" (String -> NP
forall a. String -> NPG a
cn' String
"degree") String
"angle" (Special -> Symbol
Special Special
Circle)

-- Some of these units are easiest to define via others less common names,
-- which we define first.
s_2 :: UnitDefn
s_2 :: UnitDefn
s_2 = String -> NP -> String -> UnitEquation -> UnitDefn
compoundUnit String
"seconds squared" (String -> NP
forall a. String -> NPG a
cn' String
"seconds squared") String
"seconds squared" (UnitEquation -> UnitDefn) -> UnitEquation -> UnitDefn
forall a b. (a -> b) -> a -> b
$ UnitDefn
second UnitDefn -> Integer -> UnitEquation
^: Integer
2

m_2, m_3 :: UnitDefn
m_2 :: UnitDefn
m_2 = String -> NP -> String -> UnitEquation -> UnitDefn
compoundUnit String
"square metres" (String -> NP
forall a. String -> NPG a
cn' String
"square metres") String
"square metres" (UnitEquation -> UnitDefn) -> UnitEquation -> UnitDefn
forall a b. (a -> b) -> a -> b
$ UnitDefn
metre UnitDefn -> Integer -> UnitEquation
^: Integer
2
m_3 :: UnitDefn
m_3 = String -> NP -> String -> UnitEquation -> UnitDefn
compoundUnit String
"cubic metres" (String -> NP
forall a. String -> NPG a
cn' String
"cubic metres") String
"cubic metres" (UnitEquation -> UnitDefn) -> UnitEquation -> UnitDefn
forall a b. (a -> b) -> a -> b
$ UnitDefn
metre UnitDefn -> Integer -> UnitEquation
^: Integer
3

-- And now for the ones with 'common' names

becquerel, calorie, centigrade, coulomb, farad, gray, henry, hertz, joule,
  katal, kilopascal, kilowatt, litre, lumen, lux,  millimetre, newton, ohm,
  pascal, radian, siemens, sievert, steradian, tesla, volt, watt, weber :: UnitDefn

becquerel :: UnitDefn
becquerel = String -> NP -> String -> Symbol -> UnitEquation -> UnitDefn
derivedUnit String
"becquerel"
  (String -> NP
forall a. String -> NPG a
cn' String
"becquerel") String
"activity" (String -> Symbol
label String
"Bq") --of a Radionuclide
  (UnitDefn
second UnitDefn -> Integer -> UnitEquation
^: (-Integer
1))

calorie :: UnitDefn
calorie = String -> NP -> String -> Symbol -> Double -> UnitDefn -> UnitDefn
compoundUnitScale String
"calorie"
  (String -> NP
forall a. String -> NPG a
cn' String
"calorie") String
"energy" (String -> Symbol
label String
"cal") Double
4.184 UnitDefn
joule

centigrade :: UnitDefn
centigrade = String -> NP -> String -> Symbol -> Double -> UnitDefn -> UnitDefn
derivedUnitShift String
"centigrade"
  (String -> NP
forall a. String -> NPG a
cn' String
"centigrade") String
"temperature" (Special -> Symbol
Special Special
Circle Symbol -> Symbol -> Symbol
forall a. Semigroup a => a -> a -> a
<> String -> Symbol
label String
"C")
  Double
273.15 UnitDefn
kelvin

coulomb :: UnitDefn
coulomb = String -> NP -> String -> Symbol -> UnitEquation -> UnitDefn
derivedUnit String
"coulomb"
  (String -> NP
forall a. String -> NPG a
cn' String
"coulomb") String
"electric charge" (String -> Symbol
label String
"C") (UnitDefn
ampere UnitDefn -> UnitDefn -> UnitEquation
*: UnitDefn
second)

farad :: UnitDefn
farad = String -> NP -> String -> Symbol -> UnitEquation -> UnitDefn
derivedUnit String
"farad"
  (String -> NP
forall a. String -> NPG a
cn' String
"farad") String
"capacitance" (String -> Symbol
label String
"F") (UnitDefn
coulomb UnitDefn -> UnitDefn -> UnitEquation
/: UnitDefn
volt)

gray :: UnitDefn
gray = String -> NP -> String -> Symbol -> UnitEquation -> UnitDefn
derivedUnit String
"gray"
  (String -> NP
forall a. String -> NPG a
cn' String
"gray") String
"absorbed dose" (String -> Symbol
label String
"Gy") (UnitDefn
joule UnitDefn -> UnitDefn -> UnitEquation
/: UnitDefn
kilogram)

henry :: UnitDefn
henry = String -> NP -> String -> Symbol -> UnitEquation -> UnitDefn
derivedUnit String
"henry"
  (String -> NP
forall a. String -> NPG a
cnIES String
"henry") String
"inductance" (String -> Symbol
label String
"H") (UnitDefn
weber UnitDefn -> UnitDefn -> UnitEquation
/: UnitDefn
ampere)

hertz :: UnitDefn
hertz = String -> NP -> String -> Symbol -> UnitEquation -> UnitDefn
derivedUnit String
"hertz"
  (String -> NP
forall a. String -> NPG a
cn String
"hertz") String
"frequency" (String -> Symbol
label String
"Hz") (UnitDefn
second UnitDefn -> Integer -> UnitEquation
^: (-Integer
1))

joule :: UnitDefn
joule = String -> NP -> String -> Symbol -> UnitEquation -> UnitDefn
derivedUnit String
"joule"
  (String -> NP
forall a. String -> NPG a
cn' String
"joule") String
"energy" (String -> Symbol
label String
"J")
 (UnitDefn
kilogram UnitDefn -> UnitEquation -> UnitEquation
*$ (UnitDefn
m_2 UnitDefn -> UnitEquation -> UnitEquation
*$ (UnitDefn
second UnitDefn -> Integer -> UnitEquation
^: (-Integer
2))))

katal :: UnitDefn
katal = String -> NP -> String -> Symbol -> UnitEquation -> UnitDefn
derivedUnit String
"katal"
  (String -> NP
forall a. String -> NPG a
cn' String
"katal") String
"catalytic activity" (String -> Symbol
label String
"kat") (UnitDefn
mole UnitDefn -> UnitDefn -> UnitEquation
/: UnitDefn
second)

kilopascal :: UnitDefn
kilopascal = String -> NP -> String -> Symbol -> Double -> UnitDefn -> UnitDefn
compoundUnitScale String
"kilopascal"
  (String -> NP
forall a. String -> NPG a
cn' String
"kilopascal") String
"pressure"
  (String -> Symbol
label String
"k" Symbol -> Symbol -> Symbol
forall a. Semigroup a => a -> a -> a
<> String -> Symbol
label String
"Pa") Double
1000 UnitDefn
pascal

kilowatt :: UnitDefn
kilowatt = String -> NP -> String -> Symbol -> Double -> UnitDefn -> UnitDefn
compoundUnitScale String
"kilowatt"
  (String -> NP
forall a. String -> NPG a
cn' String
"kilowatt") String
"power" (String -> Symbol
label String
"k" Symbol -> Symbol -> Symbol
forall a. Semigroup a => a -> a -> a
<> String -> Symbol
label String
"W") Double
1000 UnitDefn
watt

litre :: UnitDefn
litre = String -> NP -> String -> Symbol -> Double -> UnitDefn -> UnitDefn
compoundUnitScale String
"litre"
  (String -> NP
forall a. String -> NPG a
cn' String
"litre") String
"volume" (String -> Symbol
label String
"L") Double
0.001 UnitDefn
m_3

lumen :: UnitDefn
lumen = String -> NP -> String -> Symbol -> UnitEquation -> UnitDefn
derivedUnit String
"lumen"
  (String -> NP
forall a. String -> NPG a
cn' String
"lumen") String
"luminous flux" (String -> Symbol
label String
"lm") (UnitDefn
candela UnitDefn -> UnitDefn -> UnitEquation
*: UnitDefn
steradian)

lux :: UnitDefn
lux = String -> NP -> String -> Symbol -> UnitEquation -> UnitDefn
derivedUnit String
"lux"
  (String -> NP
forall a. String -> NPG a
cn String
"lux") String
"illuminance" (String -> Symbol
label String
"lx") (UnitDefn
lumen UnitDefn -> UnitDefn -> UnitEquation
/: UnitDefn
m_2)

millimetre :: UnitDefn
millimetre = String -> NP -> String -> Symbol -> Double -> UnitDefn -> UnitDefn
compoundUnitScale String
"millimetre"
  (String -> NP
forall a. String -> NPG a
cn' String
"millimetre") String
"length" (String -> Symbol
label String
"mm") Double
0.001 UnitDefn
metre

newton :: UnitDefn
newton = String -> NP -> String -> Symbol -> UnitEquation -> UnitDefn
derivedUnit String
"newton"
  (String -> NP
forall a. String -> NPG a
cn' String
"newton") String
"force" (String -> Symbol
label String
"N") (UnitDefn
kilogram UnitDefn -> UnitEquation -> UnitEquation
*$ (UnitDefn
metre UnitDefn -> UnitEquation -> UnitEquation
*$ (UnitDefn
second UnitDefn -> Integer -> UnitEquation
^: (-Integer
2))))

ohm :: UnitDefn
ohm = String -> NP -> String -> Symbol -> UnitEquation -> UnitDefn
derivedUnit String
"ohm"
  (String -> NP
forall a. String -> NPG a
cn' String
"ohm") String
"resistance" Symbol
cOmega (UnitDefn
volt UnitDefn -> UnitDefn -> UnitEquation
/: UnitDefn
ampere)

pascal :: UnitDefn
pascal = String -> NP -> String -> Symbol -> UnitEquation -> UnitDefn
derivedUnit String
"pascal"
  (String -> NP
forall a. String -> NPG a
cn' String
"pascal") String
"pressure" (String -> Symbol
label String
"Pa")
  (UnitDefn
kilogram UnitDefn -> UnitEquation -> UnitEquation
/$ (UnitDefn
metre UnitDefn -> UnitEquation -> UnitEquation
*$ (UnitDefn
second UnitDefn -> Integer -> UnitEquation
^: Integer
2)))

radian :: UnitDefn
radian = String -> NP -> String -> Symbol -> UnitEquation -> UnitDefn
derivedUnit String
"radian"
  (String -> NP
forall a. String -> NPG a
cn' String
"radian") String
"angle" (String -> Symbol
label String
"rad") (UnitDefn
metre UnitDefn -> UnitDefn -> UnitEquation
/: UnitDefn
metre)

siemens :: UnitDefn
siemens = String -> NP -> String -> Symbol -> UnitEquation -> UnitDefn
derivedUnit String
"siemens"
  (String -> NP
forall a. String -> NPG a
cn String
"siemens") String
"conductance" (String -> Symbol
label String
"S") (UnitDefn
ohm UnitDefn -> Integer -> UnitEquation
^: (-Integer
1))

sievert :: UnitDefn
sievert = String -> NP -> String -> Symbol -> UnitEquation -> UnitDefn
derivedUnit String
"sievert"
  (String -> NP
forall a. String -> NPG a
cn' String
"sievert") String
"dose equivalent" (String -> Symbol
label String
"Sv")
  (UnitDefn
joule UnitDefn -> UnitDefn -> UnitEquation
/: UnitDefn
kilogram)

steradian :: UnitDefn
steradian = String -> NP -> String -> Symbol -> UnitEquation -> UnitDefn
derivedUnit String
"steradian"
  (String -> NP
forall a. String -> NPG a
cn' String
"steradian") String
"solid angle" (String -> Symbol
label String
"sr") (UnitDefn
m_2 UnitDefn -> UnitDefn -> UnitEquation
/: UnitDefn
m_2 )

tesla :: UnitDefn
tesla = String -> NP -> String -> Symbol -> UnitEquation -> UnitDefn
derivedUnit String
"tesla"
  (String -> NP
forall a. String -> NPG a
cn String
"tesla") String
"magnetic flux density" (String -> Symbol
label String
"T") (UnitDefn
weber UnitDefn -> UnitDefn -> UnitEquation
/: UnitDefn
m_2)

volt :: UnitDefn
volt = String -> NP -> String -> Symbol -> UnitEquation -> UnitDefn
derivedUnit String
"volt"
  (String -> NP
forall a. String -> NPG a
cn' String
"volt") String
"voltage" (String -> Symbol
label String
"V") (UnitDefn
watt UnitDefn -> UnitDefn -> UnitEquation
/: UnitDefn
ampere)

watt :: UnitDefn
watt = String -> NP -> String -> Symbol -> UnitEquation -> UnitDefn
derivedUnit String
"watt" (String -> NP
forall a. String -> NPG a
cn' String
"watt") String
"power" (String -> Symbol
label String
"W")
  (UnitDefn
kilogram UnitDefn -> UnitEquation -> UnitEquation
*$ (UnitDefn
m_2 UnitDefn -> UnitEquation -> UnitEquation
*$ (UnitDefn
second UnitDefn -> Integer -> UnitEquation
^: (-Integer
3))))

weber :: UnitDefn
weber = String -> NP -> String -> Symbol -> UnitEquation -> UnitDefn
derivedUnit String
"weber"
  (String -> NP
forall a. String -> NPG a
cn' String
"weber") String
"magnetic flux" (String -> Symbol
label String
"Wb") (UnitDefn
volt UnitDefn -> UnitDefn -> UnitEquation
*: UnitDefn
second)

specificE :: UnitDefn
specificE :: UnitDefn
specificE = String -> NP -> String -> UnitEquation -> UnitDefn
compoundUnit String
"specificE" (String -> NP
forall a. String -> NPG a
cnIES String
"specific energy")
  String
"energy per unit mass" (UnitDefn
joule UnitDefn -> UnitDefn -> UnitEquation
/: UnitDefn
kilogram)

specificWeight :: UnitDefn
specificWeight :: UnitDefn
specificWeight = String -> NP -> String -> UnitEquation -> UnitDefn
compoundUnit String
"specificWeight" (String -> NP
forall a. String -> NPG a
cn' String
"specific weight")
  String
"weight per unit volume" (UnitDefn
newton UnitDefn -> UnitEquation -> UnitEquation
*$ (UnitDefn
metre UnitDefn -> Integer -> UnitEquation
^: (-Integer
3)))

-- FIXME: Need to add pi
--degrees = DUC
  --  (UD (dcc "Degrees" "angle") (UName (Special Circle)))
  --  Equiv to pi/180 rad.