{-# LANGUAGE Safe #-}

-- |
-- Module      : Data.Char.Number.Egyptian
-- Description : A module to generate ancient Egyptian numerals.
-- Maintainer  : hapytexeu+gh@gmail.com
-- Stability   : experimental
-- Portability : POSIX
--
-- One can make use of a <http://unicode.org/charts/PDF/U13000.pdf.pdf block of Unicode characters> to typeset ancient /Egyptian/ hieroglyphs. This module aims to make it more convenient
-- to work with ancient Egyptian numerals.
--
-- Ancient Egyptian numerals use a /sign-value system/ with radix 10. This means that there are hieroglyphs for 1 to 9, for 10, 20, ..., 90, for 100, 200, ..., 900, etc. With the /heh/ as
-- largest value denoting one million.
--
-- In Egyptian numerals, one could write numbers left-to-right and right-to-left (or even vertical). The human or animal figures always point to the /beginning/ of the line.
-- Because in the Unicode standard the /heh/ (denoting one million) looks to the left, the values are written left-to-right.
module Data.Char.Number.Egyptian
  ( -- * Ancient plus and minus
    plus,
    minus,

    -- * Ancient Egyptian characters for powers of 10
    nfr,
    singleStroke,
    cattleHobble,
    coilOfRope,
    waterLily,
    bentFinger,
    tadpole,
    heh,

    -- * Ancient Egyptian characters for numbers
    singleStroke1,
    singleStroke2,
    singleStroke3,
    singleStroke4,
    singleStroke5,
    singleStroke6,
    singleStroke7,
    singleStroke8,
    singleStroke9,
    singleStroke5',
    cattleHobble1,
    cattleHobble2,
    cattleHobble3,
    cattleHobble4,
    cattleHobble5,
    cattleHobble6,
    cattleHobble7,
    cattleHobble8,
    cattleHobble9,
    cattleHobble2',
    cattleHobble3',
    cattleHobble4',
    cattleHobble5',
    coilOfRope1,
    coilOfRope2,
    coilOfRope3,
    coilOfRope4,
    coilOfRope5,
    coilOfRope6,
    coilOfRope7,
    coilOfRope8,
    coilOfRope9,
    coilOfRope5',
    waterLily1,
    waterLily2,
    waterLily3,
    waterLily4,
    waterLily5,
    waterLily6,
    waterLily7,
    waterLily8,
    waterLily9,
    bentFinger1,
    bentFinger2,
    bentFinger3,
    bentFinger4,
    bentFinger5,
    bentFinger6,
    bentFinger7,
    bentFinger8,
    bentFinger9,
    bentFinger5',

    -- * Generating ancient Egyptian numerals
    egyptianNumber,
    egyptianNumber',
    egyptianNumber'',
  )
where

import Data.Char (chr, ord)
import Data.Char.Core (Ligate, PlusStyle, signValueSystem, splitLigate)
import Data.Default.Class (def)
import Data.Text (Text, empty, singleton)
import qualified Data.Text as T

-- | The single stroke character, an ancient Egyptian character to denote /one/. This is hieroglyph Z015.
singleStroke ::
  -- | The ancient Egyptian character to denote /one/.
  Char
singleStroke :: Char
singleStroke = Char
'\x133fa'

-- | The single stroke character, an ancient Egyptian character to denote /one/. This is hieroglyph Z015.
singleStroke1 ::
  -- | The ancient Egyptian character to denote /one/.
  Char
singleStroke1 :: Char
singleStroke1 = Char
singleStroke

-- | The double stroke character, an ancient Egyptian character to denote /two/. This is hieroglyph Z015A.
singleStroke2 ::
  -- | The ancient Egyptian character to denote /two/.
  Char
singleStroke2 :: Char
singleStroke2 = Char
'\x133fb'

-- | The triple stroke character, an ancient Egyptian character to denote /three/. This is hieroglyph Z015B.
singleStroke3 ::
  -- | The ancient Egyptian character to denote /three/.
  Char
singleStroke3 :: Char
singleStroke3 = Char
'\x133fc'

-- | The quadruple stroke character, an ancient Egyptian character to denote /four/. This is hieroglyph Z015C.
singleStroke4 ::
  -- | The ancient Egyptian character to denote /four/.
  Char
singleStroke4 :: Char
singleStroke4 = Char
'\x133fd'

-- | The quintuple stroke character, an ancient Egyptian character to denote /five/. This is hieroglyph Z015D.
singleStroke5 ::
  -- | The ancient Egyptian character to denote /five/.
  Char
singleStroke5 :: Char
singleStroke5 = Char
'\x133fe'

-- | An alternative version of the quintuple stroke character, an ancient Egyptian character
-- to denote /five/. This is hieroglyph Z015I.
singleStroke5' ::
  -- | The ancient Egyptian character to denote /five/.
  Char
singleStroke5' :: Char
singleStroke5' = Char
'\x13403'

-- | The sextuple stroke character, an ancient Egyptian character to denote /six/. This is hieroglyph Z015E.
singleStroke6 ::
  -- | The ancient Egyptian character to denote /six/.
  Char
singleStroke6 :: Char
singleStroke6 = Char
'\x133ff'

-- | The septuple stroke character, an ancient Egyptian character to denote /seven/. This is hieroglyph Z015F.
singleStroke7 ::
  -- | The ancient Egyptian character to denote /seven/.
  Char
singleStroke7 :: Char
singleStroke7 = Char
'\x13400'

-- | The octuple stroke character, an ancient Egyptian character to denote /eight/. This is hieroglyph Z015G.
singleStroke8 ::
  -- | The ancient Egyptian character to denote /eight/.
  Char
singleStroke8 :: Char
singleStroke8 = Char
'\x13401'

-- | The nonuple stroke character, an ancient Egyptian character to denote /nine/. This is hieroglyph Z015H.
singleStroke9 ::
  -- | The ancient Egyptian character to denote /nine/.
  Char
singleStroke9 :: Char
singleStroke9 = Char
'\x13402'

-- | The cattle hobble character, an ancient Egyptian character to denote /ten/. This is hieroglyph V020.
cattleHobble ::
  -- | The ancient Egyptian character to denote /ten/.
  Char
cattleHobble :: Char
cattleHobble = Char
'\x13386'

-- | The cattle hobble character, an ancient Egyptian character to denote /ten/.
cattleHobble1 ::
  -- | The ancient Egyptian character to denote /ten/. This is hieroglyph V020.
  Char
cattleHobble1 :: Char
cattleHobble1 = Char
cattleHobble

-- | The two cattle hobble character, an ancient Egyptian character to denote /twenty/.
cattleHobble2 ::
  -- | The ancient Egyptian character to denote /twenty/. This is hieroglyph V020A.
  Char
cattleHobble2 :: Char
cattleHobble2 = Char
'\x13387'

-- | An alternative version of the two cattle hobble character, an ancient Egyptian character
-- to denote /twenty/. This is hieroglyph V020I.
cattleHobble2' ::
  -- | The ancient Egyptian character to denote /twenty/.
  Char
cattleHobble2' :: Char
cattleHobble2' = Char
'\x1338f'

-- | The three cattle hobble character, an ancient Egyptian character to denote /thirty/. This is hieroglyph V020B.
cattleHobble3 ::
  -- | The ancient Egyptian character to denote /thirty/.
  Char
cattleHobble3 :: Char
cattleHobble3 = Char
'\x13388'

-- | An alternative version of the three cattle hobble character, an ancient Egyptian character
-- to denote /thirty/. This is hieroglyph V020J.
cattleHobble3' ::
  -- | The ancient Egyptian character to denote /thirty/.
  Char
cattleHobble3' :: Char
cattleHobble3' = Char
'\x13390'

-- | The four cattle hobble character, an ancient Egyptian character to denote /forty/. This is hieroglyph V020C.
cattleHobble4 ::
  -- | The ancient Egyptian character to denote /forty/.
  Char
cattleHobble4 :: Char
cattleHobble4 = Char
'\x13389'

-- | An alternative version of the four cattle hobble character, an ancient Egyptian character
-- to denote /fourty/. This is hieroglyph V020K.
cattleHobble4' ::
  -- | The ancient Egyptian character to denote /fourty/.
  Char
cattleHobble4' :: Char
cattleHobble4' = Char
'\x13391'

-- | The five cattle hobble character, an ancient Egyptian character to denote /fifty/.
cattleHobble5 ::
  -- | The ancient Egyptian character to denote /fifty/. This is hieroglyph V020D.
  Char
cattleHobble5 :: Char
cattleHobble5 = Char
'\x1338a'

-- | An alternative version of the five cattle hobble character, an ancient Egyptian character
-- to denote /fifty/. This is hieroglyph V020L.
cattleHobble5' ::
  -- | The ancient Egyptian character to denote /fifty/.
  Char
cattleHobble5' :: Char
cattleHobble5' = Char
'\x13392'

-- | The six cattle hobble character, an ancient Egyptian character to denote /sixty/. This is hieroglyph V020E.
cattleHobble6 ::
  -- | The ancient Egyptian character to denote /sixty/.
  Char
cattleHobble6 :: Char
cattleHobble6 = Char
'\x1338b'

-- | The seven cattle hobble character, an ancient Egyptian character to denote /seventy/. This is hieroglyph V020F.
cattleHobble7 ::
  -- | The ancient Egyptian character to denote /seventy/.
  Char
cattleHobble7 :: Char
cattleHobble7 = Char
'\x1338c'

-- | The eight cattle hobble character, an ancient Egyptian character to denote /eighty/. This is hieroglyph V020G.
cattleHobble8 ::
  -- | The ancient Egyptian character to denote /eighty/.
  Char
cattleHobble8 :: Char
cattleHobble8 = Char
'\x1338d'

-- | The nine cattle hobble character, an ancient Egyptian character to denote /ninety/. This is hieroglyph V020H.
cattleHobble9 ::
  -- | The ancient Egyptian character to denote /ninety/.
  Char
cattleHobble9 :: Char
cattleHobble9 = Char
'\x1338e'

-- | The coil of rope character, an ancient Egyptian character to denote /hundred/. This is hieroglyph V001.
coilOfRope ::
  -- | The ancient Egyptian character to denote /hundred/.
  Char
coilOfRope :: Char
coilOfRope = Char
'\x13362'

-- | The coil of rope character, an ancient Egyptian character to denote /hundred/. This is hieroglyph V001.
coilOfRope1 ::
  -- | The ancient Egyptian character to denote /hundred/.
  Char
coilOfRope1 :: Char
coilOfRope1 = Char
coilOfRope1

-- | The double coil of rope character, an ancient Egyptian character to denote /two hundred/. This is hieroglyph V001A.
coilOfRope2 ::
  -- | The ancient Egyptian character to denote /two hundred/.
  Char
coilOfRope2 :: Char
coilOfRope2 = Char
'\x13363'

-- | The tripple coil of rope character, an ancient Egyptian character to denote /three hundred/. This is hieroglyph V001B.
coilOfRope3 ::
  -- | The ancient Egyptian character to denote /three hundred/.
  Char
coilOfRope3 :: Char
coilOfRope3 = Char
'\x13364'

-- | The quadruple coil of rope character, an ancient Egyptian character to denote /four hundred/. This is hieroglyph V001C.
coilOfRope4 ::
  -- | The ancient Egyptian character to denote /four hundred/.
  Char
coilOfRope4 :: Char
coilOfRope4 = Char
'\x13365'

-- | The quintuple coil of rope character, an ancient Egyptian character to denote /five hundred/. This is hieroglyph V001D.
coilOfRope5 ::
  -- | The ancient Egyptian character to denote /five hundred/.
  Char
coilOfRope5 :: Char
coilOfRope5 = Char
'\x13366'

-- | An alternative version of the quintuple coil of rope character, an ancient Egyptian character
-- to denote /five hundred/. This is hieroglyph V001I.
coilOfRope5' ::
  -- | The ancient Egyptian character to denote /five hundred/.
  Char
coilOfRope5' :: Char
coilOfRope5' = Char
'\x1336b'

-- | The sextuple coil of rope character, an ancient Egyptian character to denote /six hundred/. This is hieroglyph V001E.
coilOfRope6 ::
  -- | The ancient Egyptian character to denote /six hundred/.
  Char
coilOfRope6 :: Char
coilOfRope6 = Char
'\x13367'

-- | The septuple coil of rope character, an ancient Egyptian character to denote /seven hundred/. This is hieroglyph V001F.
coilOfRope7 ::
  -- | The ancient Egyptian character to denote /seven hundred/.
  Char
coilOfRope7 :: Char
coilOfRope7 = Char
'\x13368'

-- | The octuple coil of rope character, an ancient Egyptian character to denote /eight hundred/. This is hieroglyph V001G.
coilOfRope8 ::
  -- | The ancient Egyptian character to denote /eight hundred/.
  Char
coilOfRope8 :: Char
coilOfRope8 = Char
'\x13369'

-- | The nonuple coil of rope character, an ancient Egyptian character to denote /nine hundred/. This is hieroglyph V001H.
coilOfRope9 ::
  -- | The ancient Egyptian character to denote /nine hundred/.
  Char
coilOfRope9 :: Char
coilOfRope9 = Char
'\x1336a'

-- | The water lily character, an ancient Egyptian character to denote /thousand/. This is hieroglyph M012.
waterLily ::
  -- | The ancient Egyptian character to denote /thousand/.
  Char
waterLily :: Char
waterLily = Char
'\x131bc'

-- | The water lily character, an ancient Egyptian character to denote /thousand/. This is hieroglyph M012.
waterLily1 ::
  -- | The ancient Egyptian character to denote /thousand/.
  Char
waterLily1 :: Char
waterLily1 = Char
waterLily

-- | The two water lilies character, an ancient Egyptian character to denote /two thousand/. This is hieroglyph M012A.
waterLily2 ::
  -- | The ancient Egyptian character to denote /two thousand/.
  Char
waterLily2 :: Char
waterLily2 = Char
'\x131bd'

-- | The three water lilies character, an ancient Egyptian character to denote /three thousand/. This is hieroglyph M012B.
waterLily3 ::
  -- | The ancient Egyptian character to denote /three thousand/.
  Char
waterLily3 :: Char
waterLily3 = Char
'\x131be'

-- | The four water lilies character, an ancient Egyptian character to denote /four thousand/. This is hieroglyph M012C.
waterLily4 ::
  -- | The ancient Egyptian character to denote /four thousand/.
  Char
waterLily4 :: Char
waterLily4 = Char
'\x131bf'

-- | The five water lilies character, an ancient Egyptian character to denote /five thousand/. This is hieroglyph M012D.
waterLily5 ::
  -- | The ancient Egyptian character to denote /five thousand/.
  Char
waterLily5 :: Char
waterLily5 = Char
'\x131c0'

-- | The six water lilies character, an ancient Egyptian character to denote /six thousand/. This is hieroglyph M012E.
waterLily6 ::
  -- | The ancient Egyptian character to denote /six thousand/.
  Char
waterLily6 :: Char
waterLily6 = Char
'\x131c1'

-- | The seven water lilies character, an ancient Egyptian character to denote /seven thousand/. This is hieroglyph M012F.
waterLily7 ::
  -- | The ancient Egyptian character to denote /seven thousand/.
  Char
waterLily7 :: Char
waterLily7 = Char
'\x131c2'

-- | The eight water lilies character, an ancient Egyptian character to denote /eight thousand/. This is hieroglyph M012G.
waterLily8 ::
  -- | The ancient Egyptian character to denote /eight thousand/.
  Char
waterLily8 :: Char
waterLily8 = Char
'\x131c3'

-- | The nine water lilies character, an ancient Egyptian character to denote /nine thousand/. This is hieroglyph M012H.
waterLily9 ::
  -- | The ancient Egyptian character to denote /nine thousand/.
  Char
waterLily9 :: Char
waterLily9 = Char
'\x131c4'

-- | The bent finger character, an ancient Egyptian character to denote /ten thousand/. This is hieroglyph B050.
bentFinger ::
  -- | The ancient Egyptian character to denote /ten thousand/.
  Char
bentFinger :: Char
bentFinger = Char
'\x130ad'

-- | The bent finger character, an ancient Egyptian character to denote /ten thousand/. This is hieroglyph B050.
bentFinger1 ::
  -- | The ancient Egyptian character to denote /ten thousand/.
  Char
bentFinger1 :: Char
bentFinger1 = Char
bentFinger

-- | The two bent fingers character, an ancient Egyptian character to denote /twenty thousand/. This is hieroglyph B050A.
bentFinger2 ::
  -- | The ancient Egyptian character to denote /twenty thousand/.
  Char
bentFinger2 :: Char
bentFinger2 = Char
'\x130ae'

-- | The three bent fingers character, an ancient Egyptian character to denote /thirty thousand/. This is hieroglyph B050B.
bentFinger3 ::
  -- | The ancient Egyptian character to denote /thirty thousand/.
  Char
bentFinger3 :: Char
bentFinger3 = Char
'\x130af'

-- | The four bent fingers character, an ancient Egyptian character to denote /fourty thousand/. This is hieroglyph B050C.
bentFinger4 ::
  -- | The ancient Egyptian character to denote /fourty thousand/.
  Char
bentFinger4 :: Char
bentFinger4 = Char
'\x130b0'

-- | The five bent fingers character, an ancient Egyptian character to denote /fifty thousand/. This is hieroglyph B050D.
bentFinger5 ::
  -- | The ancient Egyptian character to denote /fifty thousand/.
  Char
bentFinger5 :: Char
bentFinger5 = Char
'\x130b1'

-- | An alternative version of the five bent fingers character, an ancient Egyptian character
-- to denote /fifty thousand/. This is hieroglyph B050I.
bentFinger5' ::
  -- | The ancient Egyptian character to denote /fifty thousand/.
  Char
bentFinger5' :: Char
bentFinger5' = Char
'\x130b6'

-- | The six bent fingers character, an ancient Egyptian character to denote /sixty thousand/. This is hieroglyph B050E.
bentFinger6 ::
  -- | The ancient Egyptian character to denote /sixty thousand/.
  Char
bentFinger6 :: Char
bentFinger6 = Char
'\x130b2'

-- | The seven bent fingers character, an ancient Egyptian character to denote /seventy thousand/. This is hieroglyph B050F.
bentFinger7 ::
  -- | The ancient Egyptian character to denote /seventy thousand/.
  Char
bentFinger7 :: Char
bentFinger7 = Char
'\x130b3'

-- | The eight bent fingers character, an ancient Egyptian character to denote /eighty thousand/. This is hieroglyph B050G.
bentFinger8 ::
  -- | The ancient Egyptian character to denote /eighty thousand/.
  Char
bentFinger8 :: Char
bentFinger8 = Char
'\x130b4'

-- | The nine bent fingers character, an ancient Egyptian character to denote /ninety thousand/. This is hieroglyph B050H.
bentFinger9 ::
  -- | The ancient Egyptian character to denote /ninety thousand/.
  Char
bentFinger9 :: Char
bentFinger9 = Char
'\x130b5'

-- | The tadpole character, an ancient Egyptian character to denote /hundred thousand/. This is hieroglyph I008.
tadpole ::
  -- | The ancient Egyptian character to denote /hundred thousand/.
  Char
tadpole :: Char
tadpole = Char
'\x13190'

-- | The heh character, an ancient Egyptian character to denote /one million/, or /many/. This is hieroglyph C011.
heh ::
  -- | The ancient Egyptian character to denote /one million/, or /many/.
  Char
heh :: Char
heh = Char
'\x13068'

-- | The nfr character, an ancient Egyptian character to denote /zero/, it also
-- means /beautiful/. This is hieroglyph F035.
nfr ::
  -- | The ancient Egyptian character to denote /zero/.
  Char
nfr :: Char
nfr = Char
'\x13124'

_normalizeCount :: Int -> Int -> Int
_normalizeCount :: Int -> Int -> Int
_normalizeCount Int
n
  | Int
n forall a. Ord a => a -> a -> Bool
< Int
6 = forall a. a -> a
id
  | Bool
otherwise = forall a. Num a => a -> a -> a
(*) (Int
10 forall a b. (Num a, Integral b) => a -> b -> a
^ (Int
n forall a. Num a => a -> a -> a
- Int
6))

_toTranslate :: Int -> Char
_toTranslate :: Int -> Char
_toTranslate Int
0 = Char
singleStroke
_toTranslate Int
1 = Char
cattleHobble
_toTranslate Int
2 = Char
coilOfRope
_toTranslate Int
3 = Char
waterLily
_toTranslate Int
4 = Char
bentFinger
_toTranslate Int
5 = Char
tadpole
_toTranslate Int
_ = Char
heh

_ligateDigit :: Int -> Char -> Char
_ligateDigit :: Int -> Char -> Char
_ligateDigit Int
k = Int -> Char
chr forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Num a => a -> a -> a
(+) (Int
k forall a. Num a => a -> a -> a
- Int
1) forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Int
ord

_noLigate :: Int -> Int -> Text
_noLigate :: Int -> Int -> Text
_noLigate Int
_ Int
0 = Text
empty
_noLigate Int
k Int
i = Int -> Text -> Text
T.replicate (Int -> Int -> Int
_normalizeCount Int
k Int
i) (Char -> Text
singleton (Int -> Char
_toTranslate Int
k))

_withLigate :: Int -> Int -> Text
_withLigate :: Int -> Int -> Text
_withLigate Int
_ Int
0 = Text
empty
_withLigate Int
5 Int
k = Int -> Text -> Text
T.replicate Int
k (Char -> Text
singleton Char
tadpole)
_withLigate Int
n Int
k
  | Int
n forall a. Ord a => a -> a -> Bool
< Int
5 = Char -> Text
singleton (Int -> Char -> Char
_ligateDigit Int
k (Int -> Char
_toTranslate Int
n))
  | Bool
otherwise = Int -> Text -> Text
T.replicate (Int
10 forall a b. (Num a, Integral b) => a -> b -> a
^ (Int
n forall a. Num a => a -> a -> a
- Int
6) forall a. Num a => a -> a -> a
* Int
k) (Char -> Text
singleton Char
heh)

-- | Obtain
digits :: Ligate -> Int -> Int -> Text
digits :: Ligate -> Int -> Int -> Text
digits = forall a. a -> a -> Ligate -> a
splitLigate Int -> Int -> Text
_withLigate Int -> Int -> Text
_noLigate

-- | The hieroglyph used as a /plus/ sign. This character is used for /addition/. This is hieroglyph D055.
plus ::
  -- | The ancient Egyptian character to denote /addition/.
  Char
plus :: Char
plus = Char
'\x130bd'

-- | The hieroglyph used as a /minus/ sign. This character is used for
-- /subtraction/. This is hieroglyph D054.
minus ::
  -- | The ancient Egyptian character to denote /subtraction/.
  Char
minus :: Char
minus = Char
'\x130bb'

-- | Construct an ancient Egyptian numeral with the given 'Ligate' style and
-- 'PlusStyle' for the given number.
egyptianNumber ::
  Integral i =>
  -- | The given ligation style to use.
  Ligate ->
  -- | The given 'PlusStyle' to use.
  PlusStyle ->
  -- | The given number to convert to an ancient Egyptian numeral.
  i ->
  -- | A sequence of characters that is the ancient Egytian equivalent of the given number.
  Text
egyptianNumber :: forall i. Integral i => Ligate -> PlusStyle -> i -> Text
egyptianNumber Ligate
l = forall i.
Integral i =>
i
-> (Int -> Int -> Text)
-> Text
-> Char
-> Char
-> PlusStyle
-> i
-> Text
signValueSystem i
10 (Ligate -> Int -> Int -> Text
digits Ligate
l) (Char -> Text
singleton Char
nfr) Char
plus Char
minus

-- | Construct an acient Egyptian ligated numeral with the given 'PlusStyle' for
-- the given number.
egyptianNumber' ::
  Integral i =>
  -- | The given 'PlusStyle' to use.
  PlusStyle ->
  -- | The given number to convert to an ancient Egyptian numeral.
  i ->
  -- | A sequence of characters that is the ancient Egytian equivalent of the given number.
  Text
egyptianNumber' :: forall i. Integral i => PlusStyle -> i -> Text
egyptianNumber' = forall i. Integral i => Ligate -> PlusStyle -> i -> Text
egyptianNumber forall a. Default a => a
def

-- | Construct an ancient Egyptian ligated numeral with the default 'PlusStyle.
egyptianNumber'' ::
  Integral i =>
  -- | The given number to convert to an ancient Egyptian numeral.
  i ->
  -- | A sequence of characters that is the ancient Egytian equivalent of the given number.
  Text
egyptianNumber'' :: forall i. Integral i => i -> Text
egyptianNumber'' = forall i. Integral i => PlusStyle -> i -> Text
egyptianNumber' forall a. Default a => a
def