{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE Safe #-}
{-# LANGUAGE TypeApplications #-}

-- |
-- Module      : Data.Char.Private.Klingon
-- Description : Support for Klingon, which is sometimes implemented in the /private usage area/.
-- Maintainer  : hapytexeu+gh@gmail.com
-- Stability   : experimental
-- Portability : POSIX
--
-- Some fonts implement the /Klingon script/ characters with the /private usage area/. <https://en.wikipedia.org/wiki/Klingon_scripts Wikipedia>
-- describes the different fonts and <https://www.evertype.com/standards/csur/klingon.html Evertype> provides a font to typeset Klingon script.
module Data.Char.Private.Klingon
  ( -- * Representing Klingon characters
    Klingon
      ( A,
        B,
        Ch,
        D,
        E,
        Gh,
        H,
        I,
        J,
        L,
        M,
        N,
        Ng,
        O,
        P,
        Q,
        QUpper,
        R,
        S,
        T,
        Tlh,
        U,
        V,
        W,
        Y,
        GlottalStop,
        Zero,
        One,
        Two,
        Three,
        Four,
        Five,
        Six,
        Seven,
        Eight,
        Nine,
        Comma,
        FullStop,
        Mummification
      ),
  )
where

import Control.DeepSeq (NFData)
import Data.Char (chr, ord)
import Data.Char.Core (UnicodeCharacter (fromUnicodeChar, fromUnicodeChar', isInCharRange, toUnicodeChar), UnicodeText (isInTextRange), generateIsInTextRange')
import Data.Data (Data)
import Data.Hashable (Hashable)
import GHC.Generics (Generic)
import Test.QuickCheck.Arbitrary (Arbitrary (arbitrary), arbitraryBoundedEnum)

-- | A datatype to represent the Klingon characters, and their mapping to a Klingon font.
data Klingon
  = -- | The @a@ character in Klingon script.
    A
  | -- | The @b@ character in Klingon script.
    B
  | -- | The @ch@ character in Klingon script.
    Ch
  | -- | The @D@ character in Klingon script.
    D
  | -- | The @e@ character in Klingon script.
    E
  | -- | The @gh@ character in Klingon script.
    Gh
  | -- | The @H@ character in Klingon script.
    H
  | -- | The @I@ character in Klingon script.
    I
  | -- | The @j@ character in Klingon script.
    J
  | -- | The @l@ character in Klingon script.
    L
  | -- | The @m@ character in Klingon script.
    M
  | -- | The @n@ character in Klingon script.
    N
  | -- | The @ng@ character in Klingon script.
    Ng
  | -- | The @o@ character in Klingon script.
    O
  | -- | The @p@ character in Klingon script.
    P
  | -- | The @q@ character in Klingon script.
    Q
  | -- | The @Q@ character in Klingon script.
    QUpper
  | -- | The @r@ character in Klingon script.
    R
  | -- | The @S@ character in Klingon script.
    S
  | -- | The @t@ character in Klingon script.
    T
  | -- | The @tlh@ character in Klingon script.
    Tlh
  | -- | The @u@ character in Klingon script.
    U
  | -- | The @v@ character in Klingon script.
    V
  | -- | The @w@ character in Klingon script.
    W
  | -- | The @y@ character in Klingon script.
    Y
  | -- | The @ʼ@ character in Klingon script, denoting the /glottal stop/.
    GlottalStop
  | -- | The @0@ character in Klingon script.
    Zero
  | -- | The @1@ character in Klingon script.
    One
  | -- | The @2@ character in Klingon script.
    Two
  | -- | The @3@ character in Klingon script.
    Three
  | -- | The @4@ character in Klingon script.
    Four
  | -- | The @5@ character in Klingon script.
    Five
  | -- | The @6@ character in Klingon script.
    Six
  | -- | The @7@ character in Klingon script.
    Seven
  | -- | The @8@ character in Klingon script.
    Eight
  | -- | The @9@ character in Klingon script.
    Nine
  | -- | The /comma/ character in Klingon script, denoted by an /up-turned triangle/.
    Comma
  | -- | The /full stop/ character in Klingon script, denoted by a /down-turned triangle/.
    FullStop
  | -- | The /mummification/ character in Klingon script, also known as the /klingon character for the empire/ or /heart of virtue/.
    Mummification
  deriving (Klingon
forall a. a -> a -> Bounded a
maxBound :: Klingon
$cmaxBound :: Klingon
minBound :: Klingon
$cminBound :: Klingon
Bounded, Typeable Klingon
Klingon -> DataType
Klingon -> Constr
(forall b. Data b => b -> b) -> Klingon -> Klingon
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> Klingon -> u
forall u. (forall d. Data d => d -> u) -> Klingon -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Klingon -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Klingon -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Klingon -> m Klingon
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Klingon -> m Klingon
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Klingon
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Klingon -> c Klingon
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Klingon)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Klingon)
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Klingon -> m Klingon
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Klingon -> m Klingon
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Klingon -> m Klingon
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Klingon -> m Klingon
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Klingon -> m Klingon
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Klingon -> m Klingon
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Klingon -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Klingon -> u
gmapQ :: forall u. (forall d. Data d => d -> u) -> Klingon -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> Klingon -> [u]
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Klingon -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Klingon -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Klingon -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Klingon -> r
gmapT :: (forall b. Data b => b -> b) -> Klingon -> Klingon
$cgmapT :: (forall b. Data b => b -> b) -> Klingon -> Klingon
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Klingon)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Klingon)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Klingon)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Klingon)
dataTypeOf :: Klingon -> DataType
$cdataTypeOf :: Klingon -> DataType
toConstr :: Klingon -> Constr
$ctoConstr :: Klingon -> Constr
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Klingon
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Klingon
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Klingon -> c Klingon
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Klingon -> c Klingon
Data, Int -> Klingon
Klingon -> Int
Klingon -> [Klingon]
Klingon -> Klingon
Klingon -> Klingon -> [Klingon]
Klingon -> Klingon -> Klingon -> [Klingon]
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: Klingon -> Klingon -> Klingon -> [Klingon]
$cenumFromThenTo :: Klingon -> Klingon -> Klingon -> [Klingon]
enumFromTo :: Klingon -> Klingon -> [Klingon]
$cenumFromTo :: Klingon -> Klingon -> [Klingon]
enumFromThen :: Klingon -> Klingon -> [Klingon]
$cenumFromThen :: Klingon -> Klingon -> [Klingon]
enumFrom :: Klingon -> [Klingon]
$cenumFrom :: Klingon -> [Klingon]
fromEnum :: Klingon -> Int
$cfromEnum :: Klingon -> Int
toEnum :: Int -> Klingon
$ctoEnum :: Int -> Klingon
pred :: Klingon -> Klingon
$cpred :: Klingon -> Klingon
succ :: Klingon -> Klingon
$csucc :: Klingon -> Klingon
Enum, Klingon -> Klingon -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Klingon -> Klingon -> Bool
$c/= :: Klingon -> Klingon -> Bool
== :: Klingon -> Klingon -> Bool
$c== :: Klingon -> Klingon -> Bool
Eq, forall x. Rep Klingon x -> Klingon
forall x. Klingon -> Rep Klingon x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Klingon x -> Klingon
$cfrom :: forall x. Klingon -> Rep Klingon x
Generic, Eq Klingon
Klingon -> Klingon -> Bool
Klingon -> Klingon -> Ordering
Klingon -> Klingon -> Klingon
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
min :: Klingon -> Klingon -> Klingon
$cmin :: Klingon -> Klingon -> Klingon
max :: Klingon -> Klingon -> Klingon
$cmax :: Klingon -> Klingon -> Klingon
>= :: Klingon -> Klingon -> Bool
$c>= :: Klingon -> Klingon -> Bool
> :: Klingon -> Klingon -> Bool
$c> :: Klingon -> Klingon -> Bool
<= :: Klingon -> Klingon -> Bool
$c<= :: Klingon -> Klingon -> Bool
< :: Klingon -> Klingon -> Bool
$c< :: Klingon -> Klingon -> Bool
compare :: Klingon -> Klingon -> Ordering
$ccompare :: Klingon -> Klingon -> Ordering
Ord, ReadPrec [Klingon]
ReadPrec Klingon
Int -> ReadS Klingon
ReadS [Klingon]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Klingon]
$creadListPrec :: ReadPrec [Klingon]
readPrec :: ReadPrec Klingon
$creadPrec :: ReadPrec Klingon
readList :: ReadS [Klingon]
$creadList :: ReadS [Klingon]
readsPrec :: Int -> ReadS Klingon
$creadsPrec :: Int -> ReadS Klingon
Read, Int -> Klingon -> ShowS
[Klingon] -> ShowS
Klingon -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Klingon] -> ShowS
$cshowList :: [Klingon] -> ShowS
show :: Klingon -> String
$cshow :: Klingon -> String
showsPrec :: Int -> Klingon -> ShowS
$cshowsPrec :: Int -> Klingon -> ShowS
Show)

instance Arbitrary Klingon where
  arbitrary :: Gen Klingon
arbitrary = forall a. (Bounded a, Enum a) => Gen a
arbitraryBoundedEnum

instance Hashable Klingon

instance NFData Klingon

instance UnicodeCharacter Klingon where
  toUnicodeChar :: Klingon -> Char
toUnicodeChar Klingon
c
    | Klingon
c forall a. Ord a => a -> a -> Bool
<= Klingon
GlottalStop = Int -> Char
chr (Int
0xf8d0 forall a. Num a => a -> a -> a
+ Int
ci)
    | Klingon
c forall a. Ord a => a -> a -> Bool
<= Klingon
Nine = Int -> Char
chr (Int
0xf8d6 forall a. Num a => a -> a -> a
+ Int
ci)
    | Bool
otherwise = Int -> Char
chr (Int
0xf8d9 forall a. Num a => a -> a -> a
+ Int
ci)
    where
      ci :: Int
ci = forall a. Enum a => a -> Int
fromEnum Klingon
c
  fromUnicodeChar :: Char -> Maybe Klingon
fromUnicodeChar Char
c
    | Char
c forall a. Ord a => a -> a -> Bool
< Char
'\xf8d0' = forall a. Maybe a
Nothing
    | Char
c forall a. Ord a => a -> a -> Bool
< Char
'\xf8ea' = forall a. a -> Maybe a
Just (forall a. Enum a => Int -> a
toEnum (Int
ci forall a. Num a => a -> a -> a
- Int
0xf8d0))
    | Char
c forall a. Ord a => a -> a -> Bool
< Char
'\xf8f0' = forall a. Maybe a
Nothing
    | Char
c forall a. Ord a => a -> a -> Bool
< Char
'\xf8fa' = forall a. a -> Maybe a
Just (forall a. Enum a => Int -> a
toEnum (Int
ci forall a. Num a => a -> a -> a
- Int
0xf8d6))
    | Char
c forall a. Ord a => a -> a -> Bool
< Char
'\xf8fd' = forall a. Maybe a
Nothing
    | Char
c forall a. Ord a => a -> a -> Bool
< Char
'\xf900' = forall a. a -> Maybe a
Just (forall a. Enum a => Int -> a
toEnum (Int
ci forall a. Num a => a -> a -> a
- Int
0xf8d9))
    | Bool
otherwise = forall a. Maybe a
Nothing
    where
      ci :: Int
ci = Char -> Int
ord Char
c
  fromUnicodeChar' :: Char -> Klingon
fromUnicodeChar' Char
c
    | Char
c forall a. Ord a => a -> a -> Bool
< Char
'\xf8ea' = forall a. Enum a => Int -> a
toEnum (Int
ci forall a. Num a => a -> a -> a
- Int
0xf8d0)
    | Char
c forall a. Ord a => a -> a -> Bool
< Char
'\xf8fa' = forall a. Enum a => Int -> a
toEnum (Int
ci forall a. Num a => a -> a -> a
- Int
0xf8d6)
    | Bool
otherwise = forall a. Enum a => Int -> a
toEnum (Int
ci forall a. Num a => a -> a -> a
- Int
0xf8d9)
    where
      ci :: Int
ci = Char -> Int
ord Char
c
  isInCharRange :: Char -> Bool
isInCharRange Char
c = (Char
'\xf8d0' forall a. Ord a => a -> a -> Bool
<= Char
c Bool -> Bool -> Bool
&& Char
c forall a. Ord a => a -> a -> Bool
<= Char
'\xf8e9') Bool -> Bool -> Bool
|| (Char
'\xf8f0' forall a. Ord a => a -> a -> Bool
<= Char
c Bool -> Bool -> Bool
&& Char
c forall a. Ord a => a -> a -> Bool
<= Char
'\xf8f9') Bool -> Bool -> Bool
|| (Char
'\xf8fd' forall a. Ord a => a -> a -> Bool
<= Char
c Bool -> Bool -> Bool
&& Char
c forall a. Ord a => a -> a -> Bool
<= Char
'\xf8ff')

instance UnicodeText Klingon where
  isInTextRange :: Text -> Bool
isInTextRange = forall a. UnicodeCharacter a => Text -> Bool
generateIsInTextRange' @Klingon