module Kewar.Encoding.Analysis (mode, version) where

import Data.Char (isDigit, isLatin1)
import Kewar.Constants (allowedAlphaNumericValues, capacities)
import Kewar.Types (Exception (InvalidCharacterSet), Mode (AlphaNumeric, Byte, Numeric), Version, CorrectionLevel)
import Data.List (find)
import Data.Maybe (fromJust)

mode :: String -> Either Exception Mode
mode :: String -> Either Exception Mode
mode String
i
  | (Char -> Bool) -> String -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Char -> Bool
isDigit String
i = Mode -> Either Exception Mode
forall a b. b -> Either a b
Right Mode
Numeric
  | (Char -> Bool) -> String -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (Char -> String -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` String
allowedAlphaNumericValues) String
i = Mode -> Either Exception Mode
forall a b. b -> Either a b
Right Mode
AlphaNumeric
  | (Char -> Bool) -> String -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Char -> Bool
isLatin1 String
i = Mode -> Either Exception Mode
forall a b. b -> Either a b
Right Mode
Byte
  | Bool
otherwise = Exception -> Either Exception Mode
forall a b. a -> Either a b
Left Exception
InvalidCharacterSet

version :: String -> Mode -> CorrectionLevel -> Version
version :: String -> Mode -> CorrectionLevel -> Version
version String
i Mode
m CorrectionLevel
cl = (Version, Version) -> Version
forall a b. (a, b) -> a
fst ((Version, Version) -> Version) -> (Version, Version) -> Version
forall a b. (a -> b) -> a -> b
$ Maybe (Version, Version) -> (Version, Version)
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe (Version, Version) -> (Version, Version))
-> Maybe (Version, Version) -> (Version, Version)
forall a b. (a -> b) -> a -> b
$ ((Version, Version) -> Bool)
-> [(Version, Version)] -> Maybe (Version, Version)
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find (\(Version
_, Version
limit) -> Version
limit Version -> Version -> Bool
forall a. Ord a => a -> a -> Bool
> Version
s) [(Version, Version)]
cs
  where
    cs :: [(Version, Version)]
cs = CorrectionLevel -> Mode -> [(Version, Version)]
capacities CorrectionLevel
cl Mode
m
    s :: Version
s = String -> Version
forall (t :: * -> *) a. Foldable t => t a -> Version
length String
i