{-# LANGUAGE NoImplicitPrelude #-}

module Codec.QRCode
  (
  -- * Encoders
    encode
  , encodeAutomatic
  , encodeText
  , encodeBinary
  , encodeKanji
  , encodeAlphanumeric
  , encodeNumeric
  -- * Re-Exports
  , module Codec.QRCode.Data.QRCodeOptions
  , module Codec.QRCode.Data.ErrorLevel
  , module Codec.QRCode.Data.Mask
  , module Codec.QRCode.Data.TextEncoding
  , module Codec.QRCode.Data.ToInput
  , module Codec.QRCode.Data.QRImage
  ) where

import           Codec.QRCode.Base

import           Codec.QRCode.Code.Intermediate
import           Codec.QRCode.Data.ErrorLevel
import           Codec.QRCode.Data.Mask
import           Codec.QRCode.Data.QRCodeOptions
import           Codec.QRCode.Data.QRImage
import           Codec.QRCode.Data.Result
import           Codec.QRCode.Data.TextEncoding
import           Codec.QRCode.Data.ToInput
import           Codec.QRCode.Mode.Alphanumeric
import           Codec.QRCode.Mode.Automatic
import           Codec.QRCode.Mode.Byte
import           Codec.QRCode.Mode.Kanji
import           Codec.QRCode.Mode.Mixed
import           Codec.QRCode.Mode.Numeric

-- | Encode a string into an QR code using any mode that seems fit, will encode the input in parts, each as
--   `encodeNumeric`, `encodeAlphanumeric`, `encodeKanji` and `encodeText` based on the contents.
--
--   Please refer to the specific documentations for details.
--
--   Should result in the shortest encoded data.
encode :: ToText a => QRCodeOptions -> TextEncoding -> a -> Maybe QRImage
{-# INLINABLE encode #-}
encode :: QRCodeOptions -> TextEncoding -> a -> Maybe QRImage
encode QRCodeOptions
opt TextEncoding
te = Result QRImage -> Maybe QRImage
forall a. Result a -> Maybe a
getResult (Result QRImage -> Maybe QRImage)
-> (a -> Result QRImage) -> a -> Maybe QRImage
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (QRIntermediate -> QRImage
fromIntermediate (QRIntermediate -> QRImage)
-> Result QRIntermediate -> Result QRImage
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>) (Result QRIntermediate -> Result QRImage)
-> (a -> Result QRIntermediate) -> a -> Result QRImage
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (QRCodeOptions -> QRSegment -> Result QRIntermediate
toIntermediate QRCodeOptions
opt (QRSegment -> Result QRIntermediate)
-> Result QRSegment -> Result QRIntermediate
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<) (Result QRSegment -> Result QRIntermediate)
-> (a -> Result QRSegment) -> a -> Result QRIntermediate
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TextEncoding -> a -> Result QRSegment
forall a. ToText a => TextEncoding -> a -> Result QRSegment
mixed TextEncoding
te

-- | Encode a whole string into an QR code using the mode with the shortest result.
--   Will pick either `encodeNumeric`, `encodeAlphanumeric`, `encodeKanji` or `encodeText` based on the contents.
--
--   Please refer to the specific documentations for details.
encodeAutomatic :: ToText a => QRCodeOptions -> TextEncoding -> a -> Maybe QRImage
{-# INLINABLE encodeAutomatic #-}
encodeAutomatic :: QRCodeOptions -> TextEncoding -> a -> Maybe QRImage
encodeAutomatic QRCodeOptions
opt TextEncoding
te = Result QRImage -> Maybe QRImage
forall a. Result a -> Maybe a
getResult (Result QRImage -> Maybe QRImage)
-> (a -> Result QRImage) -> a -> Maybe QRImage
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (QRIntermediate -> QRImage
fromIntermediate (QRIntermediate -> QRImage)
-> Result QRIntermediate -> Result QRImage
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>) (Result QRIntermediate -> Result QRImage)
-> (a -> Result QRIntermediate) -> a -> Result QRImage
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (QRCodeOptions -> QRSegment -> Result QRIntermediate
toIntermediate QRCodeOptions
opt (QRSegment -> Result QRIntermediate)
-> Result QRSegment -> Result QRIntermediate
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<) (Result QRSegment -> Result QRIntermediate)
-> (a -> Result QRSegment) -> a -> Result QRIntermediate
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TextEncoding -> a -> Result QRSegment
forall a. ToText a => TextEncoding -> a -> Result QRSegment
automatic TextEncoding
te

-- | Generate a QR code representing the specified text data encoded as ISO-8859-1 or UTF-8
--   (with or without ECI) in byte mode.
--
--   Please refer to `TextEncoding` on what the difference is.
--
--   In case you want to encode as ISO-8859-1 and already have a [Word8] or similar
--   you can use 'encodeBinary' as it creates the same result.
encodeText :: ToText a => QRCodeOptions -> TextEncoding -> a -> Maybe QRImage
{-# INLINABLE encodeText #-}
encodeText :: QRCodeOptions -> TextEncoding -> a -> Maybe QRImage
encodeText QRCodeOptions
opt TextEncoding
te = Result QRImage -> Maybe QRImage
forall a. Result a -> Maybe a
getResult (Result QRImage -> Maybe QRImage)
-> (a -> Result QRImage) -> a -> Maybe QRImage
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (QRIntermediate -> QRImage
fromIntermediate (QRIntermediate -> QRImage)
-> Result QRIntermediate -> Result QRImage
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>) (Result QRIntermediate -> Result QRImage)
-> (a -> Result QRIntermediate) -> a -> Result QRImage
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (QRCodeOptions -> QRSegment -> Result QRIntermediate
toIntermediate QRCodeOptions
opt (QRSegment -> Result QRIntermediate)
-> Result QRSegment -> Result QRIntermediate
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<) (Result QRSegment -> Result QRIntermediate)
-> (a -> Result QRSegment) -> a -> Result QRIntermediate
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TextEncoding -> a -> Result QRSegment
forall a. ToText a => TextEncoding -> a -> Result QRSegment
text TextEncoding
te

-- | Generate a QR code representing the specified binary data in byte mode.
encodeBinary :: ToBinary a => QRCodeOptions -> a -> Maybe QRImage
{-# INLINABLE encodeBinary #-}
encodeBinary :: QRCodeOptions -> a -> Maybe QRImage
encodeBinary QRCodeOptions
opt = Result QRImage -> Maybe QRImage
forall a. Result a -> Maybe a
getResult (Result QRImage -> Maybe QRImage)
-> (a -> Result QRImage) -> a -> Maybe QRImage
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (QRIntermediate -> QRImage
fromIntermediate (QRIntermediate -> QRImage)
-> Result QRIntermediate -> Result QRImage
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>) (Result QRIntermediate -> Result QRImage)
-> (a -> Result QRIntermediate) -> a -> Result QRImage
forall b c a. (b -> c) -> (a -> b) -> a -> c
. QRCodeOptions -> QRSegment -> Result QRIntermediate
toIntermediate QRCodeOptions
opt (QRSegment -> Result QRIntermediate)
-> (a -> QRSegment) -> a -> Result QRIntermediate
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> QRSegment
forall a. ToBinary a => a -> QRSegment
binary

-- | Generate a QR code representing the specified text data encoded as QR code Kanji.
--
--   Since this encoding does neither contain ASCII nor the half width katakana characters
--   it may be impossible to encode all text in this encoding.
encodeKanji :: ToText a => QRCodeOptions -> a -> Maybe QRImage
{-# INLINABLE encodeKanji #-}
encodeKanji :: QRCodeOptions -> a -> Maybe QRImage
encodeKanji QRCodeOptions
opt = Result QRImage -> Maybe QRImage
forall a. Result a -> Maybe a
getResult (Result QRImage -> Maybe QRImage)
-> (a -> Result QRImage) -> a -> Maybe QRImage
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (QRIntermediate -> QRImage
fromIntermediate (QRIntermediate -> QRImage)
-> Result QRIntermediate -> Result QRImage
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>) (Result QRIntermediate -> Result QRImage)
-> (a -> Result QRIntermediate) -> a -> Result QRImage
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (QRCodeOptions -> QRSegment -> Result QRIntermediate
toIntermediate QRCodeOptions
opt (QRSegment -> Result QRIntermediate)
-> Result QRSegment -> Result QRIntermediate
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<) (Result QRSegment -> Result QRIntermediate)
-> (a -> Result QRSegment) -> a -> Result QRIntermediate
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Result QRSegment
forall a. ToText a => a -> Result QRSegment
kanji

-- | Generate a QR code representing the specified text string encoded in alphanumeric mode.
--
--    The alphanumeric encoding contains this characters: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:".
--
--    When the input is case insensitive the chars are converted to uppercase since this alphabet contains only uppercase characters.
--    This can be archived by applying `Data.CaseInsensitive.mk` to the input.
encodeAlphanumeric :: ToText a => QRCodeOptions -> a -> Maybe QRImage
{-# INLINABLE encodeAlphanumeric #-}
encodeAlphanumeric :: QRCodeOptions -> a -> Maybe QRImage
encodeAlphanumeric QRCodeOptions
opt = Result QRImage -> Maybe QRImage
forall a. Result a -> Maybe a
getResult (Result QRImage -> Maybe QRImage)
-> (a -> Result QRImage) -> a -> Maybe QRImage
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (QRIntermediate -> QRImage
fromIntermediate (QRIntermediate -> QRImage)
-> Result QRIntermediate -> Result QRImage
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>) (Result QRIntermediate -> Result QRImage)
-> (a -> Result QRIntermediate) -> a -> Result QRImage
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (QRCodeOptions -> QRSegment -> Result QRIntermediate
toIntermediate QRCodeOptions
opt (QRSegment -> Result QRIntermediate)
-> Result QRSegment -> Result QRIntermediate
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<) (Result QRSegment -> Result QRIntermediate)
-> (a -> Result QRSegment) -> a -> Result QRIntermediate
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Result QRSegment
forall a. ToText a => a -> Result QRSegment
alphanumeric

-- | Generate a QR code representing the specified string of decimal digits encoded in numeric mode.
encodeNumeric :: ToNumeric a => QRCodeOptions -> a -> Maybe QRImage
{-# INLINABLE encodeNumeric #-}
encodeNumeric :: QRCodeOptions -> a -> Maybe QRImage
encodeNumeric QRCodeOptions
opt = Result QRImage -> Maybe QRImage
forall a. Result a -> Maybe a
getResult (Result QRImage -> Maybe QRImage)
-> (a -> Result QRImage) -> a -> Maybe QRImage
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (QRIntermediate -> QRImage
fromIntermediate (QRIntermediate -> QRImage)
-> Result QRIntermediate -> Result QRImage
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>) (Result QRIntermediate -> Result QRImage)
-> (a -> Result QRIntermediate) -> a -> Result QRImage
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (QRCodeOptions -> QRSegment -> Result QRIntermediate
toIntermediate QRCodeOptions
opt (QRSegment -> Result QRIntermediate)
-> Result QRSegment -> Result QRIntermediate
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<) (Result QRSegment -> Result QRIntermediate)
-> (a -> Result QRSegment) -> a -> Result QRIntermediate
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Result QRSegment
forall a. ToNumeric a => a -> Result QRSegment
numeric