{-# OPTIONS_HADDOCK hide #-}
module Codec.Binary.QRCode.Spec where

import Data.Maybe

import Codec.Binary.QRCode.GaloisField

data Mode = Numeric -- ^ @0123456789@

          -- | @0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-.:.@
          -- 
          -- Input alphabets are automatically converted to upper case.
          | Alphanumeric
          | EightBit
          | Kanji
          deriving (Show, Eq)

newtype Version = Version Int deriving (Show, Eq)
data ErrorLevel = L -- ^ Error recovery up to 7%.
                | M -- ^ Error recovery up to 15%.
                | Q -- ^ Error recovery up to 25%.
                | H -- ^ Error recovery up to 30%.
                deriving (Show, Eq)
data Info = Info
    { qrVersion :: Int
    , qrNumModulesPerSide :: Int
    , qrNumFunctionPatternModules :: Int
    , qrNumFormatAndVersionInfoModules :: Int
    , qrNumDataModules :: Int
    , qrDataCapacity :: Int
    , qrRemainderBits :: Int
    } deriving (Eq, Show)

qrGetWidth :: Version -> Int
qrGetWidth = qrNumModulesPerSide . qrGetInfo

qrFormatInfoMask :: Int
qrFormatInfoMask = readBin "101010000010010"

qrFormatInfoGenPoly :: GFPolynomial
qrFormatInfoGenPoly = mkPolynomial [1,0,1,0,0,1,1,0,1,1,1]

qrVersionInfoGenPoly :: GFPolynomial
qrVersionInfoGenPoly = mkPolynomial [1,1,1,1,1,0,0,1,0,0,1,0,1]

qrErrorLevelIndicators :: ErrorLevel -> String
qrErrorLevelIndicators L = "01"
qrErrorLevelIndicators M = "00"
qrErrorLevelIndicators Q = "11"
qrErrorLevelIndicators H = "10"

qrAlignmentCenters :: Version -> [Int]
qrAlignmentCenters = fromJust . flip lookup table
    where
        table =
            [ ( Version 1, [] ) 
            , ( Version 2, [6,18] )
            , ( Version 3, [6,22] )
            , ( Version 4, [6,26] )
            , ( Version 5, [6,30] )
            , ( Version 6, [6,34] )
            , ( Version 7, [6,22,38] )
            , ( Version 8, [6,24,42] )
            , ( Version 9, [6,26,46] )
            , ( Version 10, [6,28,50] )
            , ( Version 11, [6,30,54] )
            , ( Version 12, [6,32,58] )
            , ( Version 13, [6,34,62] )
            , ( Version 14, [6,26,46,66] )
            , ( Version 15, [6,26,48,70] )
            , ( Version 16, [6,26,50,74] )
            , ( Version 17, [6,30,54,78] )
            , ( Version 18, [6,30,56,82] )
            , ( Version 19, [6,30,58,86] )
            , ( Version 20, [6,34,62,90] )
            , ( Version 21, [6,28,50,72,94] )
            , ( Version 22, [6,26,50,74,98] )
            , ( Version 23, [6,30,54,78,102] )
            , ( Version 24, [6,28,54,80,106] )
            , ( Version 25, [6,32,58,84,110] )
            , ( Version 26, [6,30,58,86,114] )
            , ( Version 27, [6,34,62,90,118] )
            , ( Version 28, [6,26,50,74,98,122] )
            , ( Version 29, [6,30,54,78,102,126] )
            , ( Version 30, [6,26,52,78,104,130] )
            , ( Version 31, [6,30,56,82,108,134] )
            , ( Version 32, [6,34,60,86,112,138] )
            , ( Version 33, [6,30,58,86,114,142] )
            , ( Version 34, [6,34,62,90,118,146] )
            , ( Version 35, [6,30,54,78,102,126,150] )
            , ( Version 36, [6,24,50,76,102,128,154] )
            , ( Version 37, [6,28,54,80,106,132,158] )
            , ( Version 38, [6,32,58,84,110,136,162] )
            , ( Version 39, [6,26,54,82,110,138,166] )
            , ( Version 40, [6,30,58,86,114,142,170] )
            ]


qrGetInfo :: Version -> Info
qrGetInfo = fromJust . flip lookup table
    where table = 
            [ ( Version 1, Info 1 21 202 31 208 26 0 )
            , ( Version 2, Info 2 25 235 31 359 44 7 )
            , ( Version 3, Info 3 29 243 31 567 70 7 )
            , ( Version 4, Info 4 33 251 31 807 100 7 )
            , ( Version 5, Info 5 37 259 31 1079 134 7 )
            , ( Version 6, Info 6 41 267 31 1383 172 7 )
            , ( Version 7, Info 7 45 390 67 1568 196 0 )
            , ( Version 8, Info 8 49 398 67 1936 242 0 )
            , ( Version 9, Info 9 53 406 67 2336 292 0 )
            , ( Version 10, Info 10 57 414 67 2768 346 0 )
            , ( Version 11, Info 11 61 422 67 3232 404 0 )
            , ( Version 12, Info 12 65 430 67 3728 466 0 )
            , ( Version 13, Info 13 69 438 67 4256 532 0 )
            , ( Version 14, Info 14 73 611 67 4651 581 3 )
            , ( Version 15, Info 15 77 619 67 5243 655 3 )
            , ( Version 16, Info 16 81 627 67 5867 733 3 )
            , ( Version 17, Info 17 85 635 67 6523 815 3 )
            , ( Version 18, Info 18 89 643 67 7211 901 3 )
            , ( Version 19, Info 19 93 651 67 7931 991 3 )
            , ( Version 20, Info 20 97 659 67 8683 1085 3 )
            , ( Version 21, Info 21 101 882 67 9252 1156 4 )
            , ( Version 22, Info 22 105 890 67 10068 1258 4 )
            , ( Version 23, Info 23 109 898 67 10916 1364 4 )
            , ( Version 24, Info 24 113 906 67 11796 1474 4 )
            , ( Version 25, Info 25 117 914 67 12708 1588 4 )
            , ( Version 26, Info 26 121 922 67 13652 1706 4 )
            , ( Version 27, Info 27 125 930 67 14628 1828 4 )
            , ( Version 28, Info 28 129 1203 67 15371 1921 3 )
            , ( Version 29, Info 29 133 1211 67 16411 2051 3 )
            , ( Version 30, Info 30 137 1219 67 17483 2185 3 )
            , ( Version 31, Info 31 141 1227 67 18587 2323 3 )
            , ( Version 32, Info 32 145 1235 67 19723 2465 3 )
            , ( Version 33, Info 33 149 1243 67 20891 2611 3 )
            , ( Version 34, Info 34 153 1251 67 22091 2761 3 )
            , ( Version 35, Info 35 157 1574 67 23008 2876 0 )
            , ( Version 36, Info 36 161 1582 67 24272 3034 0 )
            , ( Version 37, Info 37 165 1590 67 25568 3196 0 )
            , ( Version 38, Info 38 169 1598 67 26896 3362 0 )
            , ( Version 39, Info 39 173 1606 67 28256 3532 0 )
            , ( Version 40, Info 40 177 1614 67 29648 3706 0 )
            ]

mkVersion :: Int -> Version
mkVersion = Version

qrLengthsOfCCI :: [(Mode, Int)]
qrLengthsOfCCI = zip (cycle [Numeric,Alphanumeric,EightBit,Kanji]) table
    where
        table =
            [ 10, 9, 8, 8 -- version 1 to 9
            , 12, 11, 16, 10 -- version 1 to 9
            , 14, 13, 16, 12 -- version 1 to 9
            ]

qrLengthOfCCI :: Version -> Mode -> Int
qrLengthOfCCI (Version ver) mode
    | ver >= 1 && ver <= 9 = go 0
    | ver >= 10 && ver <= 26 = go 1
    | ver >= 27 && ver <= 40 = go 2
    | otherwise = error $ "Invalid Version " ++ show ver
    where go n = fromJust $ lookup mode (drop (n*4) qrLengthsOfCCI)

qrMatchTable :: Int -> ErrorLevel -> [a] -> a
qrMatchTable ver err table = table !! ((ver-1) * 4 + m2i err)
    where
        m2i L = 0
        m2i M = 1
        m2i Q = 2
        m2i H = 3

qrDCWSizes :: Num a => Int -> ErrorLevel -> [a]
qrDCWSizes ver err = qrMatchTable ver err table
    where
        table =
            [ [19], [16], [13], [9] -- 1L, 1M, 1Q, 1H
            , [34], [28], [22], [16]
            , [55], [44], [17,17], [13,13]
            , [80], [32,32], [24,24], [9,9,9,9]
            , [108], [43,43], [15,15,16,16], [11,11,12,12]
            , [68,68], [27,27,27,27], [19,19,19,19], [15,15,15,15]
            , [78,78], [31,31,31,31], [14,14,15,15,15,15], [13,13,13,13,14]
            , [97,97], [38,38,39,39], [18,18,18,18,19,19], [14,14,14,14,15,15]
            , [116,116], [36,36,36,37,37], [16,16,16,16,17,17,17,17], [12,12,12,12,13,13,13,13]
            , [68,68,69,69], [43,43,43,43,44], [19,19,19,19,19,19,20,20], [15,15,15,15,15,15,16,16]
            , [81,81,81,81], [50,51,51,51,51], [22,22,22,22,23,23,23,23], [12,12,12,13,13,13,13,13,13,13,13]
            , [92,92,93,93], [36,36,36,36,36,36,37,37], [20,20,20,20,21,21,21,21,21,21], [14,14,14,14,14,14,14,15,15,15,15]
            , [107,107,107,107], [37,37,37,37,37,37,37,37,38], [20,20,20,20,20,20,20,20,21,21,21,21], [11,11,11,11,11,11,11,11,11,11,11,11,12,12,12,12]
            , [115,115,115,116], [40,40,40,40,41,41,41,41,41], [16,16,16,16,16,16,16,16,16,16,16,17,17,17,17,17], [12,12,12,12,12,12,12,12,12,12,12,13,13,13,13,13]
            , [87,87,87,87,87,88], [41,41,41,41,41,42,42,42,42,42], [24,24,24,24,24,25,25,25,25,25,25,25], [12,12,12,12,12,12,12,12,12,12,12,13,13,13,13,13,13,13]
            , [98,98,98,98,98,99], [45,45,45,45,45,45,45,46,46,46], [19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,20,20], [15,15,15,16,16,16,16,16,16,16,16,16,16,16,16,16]
            , [107,108,108,108,108,108], [46,46,46,46,46,46,46,46,46,46,47], [22,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23], [14,14,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15]
            , [120,120,120,120,120,121], [43,43,43,43,43,43,43,43,43,44,44,44,44], [22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,23], [14,14,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15]
            , [113,113,113,114,114,114,114], [44,44,44,45,45,45,45,45,45,45,45,45,45,45], [21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,22,22,22,22], [13,13,13,13,13,13,13,13,13,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14]
            , [107,107,107,108,108,108,108,108], [41,41,41,42,42,42,42,42,42,42,42,42,42,42,42,42], [24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25], [15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,16,16,16,16,16,16,16,16,16,16]
            , [116,116,116,116,117,117,117,117], [42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42], [22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,23,23,23,23,23,23], [16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,17,17,17,17,17,17]
            , [111,111,112,112,112,112,112,112,112], [46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46], [24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25], [13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13]
            , [121,121,121,121,122,122,122,122,122], [47,47,47,47,48,48,48,48,48,48,48,48,48,48,48,48,48,48], [24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,25,25], [15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,16,16,16,16,16,16,16,16,16,16,16,16,16,16]
            , [117,117,117,117,117,117,118,118,118,118], [45,45,45,45,45,45,46,46,46,46,46,46,46,46,46,46,46,46,46,46], [24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25], [16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,17,17]
            , [106,106,106,106,106,106,106,106,107,107,107,107], [47,47,47,47,47,47,47,47,48,48,48,48,48,48,48,48,48,48,48,48,48], [24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25], [15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,16,16,16,16,16,16,16,16,16,16,16,16,16]
            , [114,114,114,114,114,114,114,114,114,114,115,115], [46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,47,47,47,47], [22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,23,23,23,23,23,23], [16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,17,17,17,17]
            , [122,122,122,122,122,122,122,122,123,123,123,123], [45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,46,46,46], [23,23,23,23,23,23,23,23,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24], [15,15,15,15,15,15,15,15,15,15,15,15,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16]
            , [117,117,117,118,118,118,118,118,118,118,118,118,118], [45,45,45,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46], [24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25], [15,15,15,15,15,15,15,15,15,15,15,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16]
            , [116,116,116,116,116,116,116,117,117,117,117,117,117,117], [45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,46,46,46,46,46,46,46], [23,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24], [15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16]
            , [115,115,115,115,115,116,116,116,116,116,116,116,116,116,116], [47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,48,48,48,48,48,48,48,48,48,48], [24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25], [15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16]
            , [115,115,115,115,115,115,115,115,115,115,115,115,115,116,116,116], [46,46,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47], [24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,25], [15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16]
            , [115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115], [46,46,46,46,46,46,46,46,46,46,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47], [24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25], [15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16]
            , [115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,116], [46,46,46,46,46,46,46,46,46,46,46,46,46,46,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47], [24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25], [15,15,15,15,15,15,15,15,15,15,15,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16]
            , [115,115,115,115,115,115,115,115,115,115,115,115,115,116,116,116,116,116,116], [46,46,46,46,46,46,46,46,46,46,46,46,46,46,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47], [24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25], [16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,17]
            , [121,121,121,121,121,121,121,121,121,121,121,121,122,122,122,122,122,122,122], [47,47,47,47,47,47,47,47,47,47,47,47,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48], [24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,25,25], [15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16]
            , [121,121,121,121,121,121,122,122,122,122,122,122,122,122,122,122,122,122,122,122], [47,47,47,47,47,47,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48], [24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25], [15,15,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16]
            , [122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,123,123,123,123], [46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,47,47,47,47,47,47,47,47,47,47,47,47,47,47], [24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25], [15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16]
            , [122,122,122,122,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123], [46,46,46,46,46,46,46,46,46,46,46,46,46,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47], [24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,25,25], [15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16]
            , [117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,118,118,118,118], [47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,48,48,48,48,48,48,48], [24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25], [15,15,15,15,15,15,15,15,15,15,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16]
            , [118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,119,119,119,119,119,119], [47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48], [24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25], [15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16]
            ]


qrNumErrorCodewordsPerBlock :: Num a => Int -> ErrorLevel -> a
qrNumErrorCodewordsPerBlock ver err = qrMatchTable ver err table
    where table =
            [ 7, 10, 13, 17 -- 1M, 1M, 1Q, 1H
            , 10, 16, 22, 28
            , 15, 26, 18, 22
            , 20, 18, 26, 16
            , 26, 24, 18, 22
            , 18, 16, 24, 28
            , 20, 18, 18, 26
            , 24, 22, 22, 26
            , 30, 22, 20, 24
            , 18, 26, 24, 28
            , 20, 30, 28, 24
            , 24, 22, 26, 28
            , 26, 22, 24, 22
            , 30, 24, 20, 24
            , 22, 24, 30, 24
            , 24, 28, 24, 30
            , 28, 28, 28, 28
            , 30, 26, 28, 28
            , 28, 26, 26, 26
            , 28, 26, 30, 28
            , 28, 26, 28, 30
            , 28, 28, 30, 24
            , 30, 28, 30, 30
            , 30, 28, 30, 30
            , 26, 28, 30, 30
            , 28, 28, 28, 30
            , 30, 28, 30, 30
            , 30, 28, 30, 30
            , 30, 28, 30, 30
            , 30, 28, 30, 30
            , 30, 28, 30, 30
            , 30, 28, 30, 30
            , 30, 28, 30, 30
            , 30, 28, 30, 30
            , 30, 28, 30, 30
            , 30, 28, 30, 30
            , 30, 28, 30, 30
            , 30, 28, 30, 30
            , 30, 28, 30, 30
            , 30, 28, 30, 30
            ]

qrNumDataBits :: Num a => Int -> ErrorLevel -> a
qrNumDataBits ver mode = qrMatchTable ver mode table
    where table = 
            [ 152, 128, 104, 72
            , 272, 224, 176, 128
            , 440, 352, 272, 208
            , 640, 512, 384, 288
            , 864, 688, 496, 368
            , 1088, 864, 608, 480
            , 1248, 992, 704, 528
            , 1552, 1232, 880, 688
            , 1856, 1456, 1056, 800
            , 2192, 1728, 1232, 976
            , 2592, 2032, 1440, 1120
            , 2960, 2320, 1648, 1264
            , 3424, 2672, 1952, 1440
            , 3688, 2920, 2088, 1576
            , 4184, 3320, 2360, 1784
            , 4712, 3624, 2600, 2024
            , 5176, 4056, 2936, 2264
            , 5768, 4504, 3176, 2504
            , 6360, 5016, 3560, 2728
            , 6888, 5352, 3880, 3080
            , 7456, 5712, 4096, 3248
            , 8048, 6256, 4544, 3536
            , 8752, 6880, 4912, 3712
            , 9392, 7312, 5312, 4112
            , 10208, 8000, 5744, 4304
            , 10960, 8496, 6032, 4768
            , 11744, 9024, 6464, 5024
            , 12248, 9544, 6968, 5288
            , 13048, 10136, 7288, 5608
            , 13880, 10984, 7880, 5960
            , 14744, 11640, 8264, 6344
            , 15640, 12328, 8920, 6760
            , 16568, 13048, 9368, 7208
            , 17528, 13800, 9848, 7688
            , 18448, 14496, 10288, 7888
            , 19472, 15312, 10832, 8432
            , 20528, 15936, 11408, 8768
            , 21616, 16816, 12016, 9136
            , 22496, 17728, 12656, 9776
            , 23648, 18672, 13328, 10208
            ]

qrGenPoly :: Int -> [Int]
qrGenPoly = map gfALog . qrGenPolyRaw

-- Decreasing degree of x
qrGenPolyRaw :: Int -> [Int]
qrGenPolyRaw 7 = [0,87,229,146,149,238,102,21] -- (x^7) + (a^87)(x^6) + (a^146)(x^4) + ... + (a^21)
qrGenPolyRaw 10 = [0,251,67,46,61,118,70,64,94,32,45]
qrGenPolyRaw 13 = [0,74,152,176,100,86,100,106,104,130,218,206,140,78]
qrGenPolyRaw 15 = [0,8,183,61,91,202,37,51,58,58,237,140,124,5,99,105]
qrGenPolyRaw 16 = [0,120,104,107,109,102,161,76,3,91,191,147,169,182,194,225,12]
qrGenPolyRaw 17 = [0,43,139,206,78,43,239,123,206,214,147,24,99,150,39,243,163,136]
qrGenPolyRaw 18 = [0,215,234,158,94,184,97,118,170,79,187,152,148,252,179,5,98,96,15]
qrGenPolyRaw 20 = [0,17,60,79,50,61,163,26,187,202,180,221,225,83,239,156,164,212,212,188,19]
qrGenPolyRaw 22 = [0,210,171,247,242,93,230,14,109,221,53,200,74,8,172,98,80,219,134,160,105,165,23]
qrGenPolyRaw 24 = [0,229,121,135,48,211,117,251,126,159,180,169,152,192,226,228,218,111,0,117,232,87,96,227,2]
qrGenPolyRaw 26 = [0,173,125,158,2,103,182,118,17,145,201,111,28,165,53,161,21,245,142,13,102,48,227,153,145,218,7]
qrGenPolyRaw 28 = [0,168,223,200,104,224,234,108,180,110,190,195,147,205,27,232,201,21,43,245,87,42,195,212,119,242,37,9,12]
qrGenPolyRaw 30 = [0,41,173,145,152,216,31,179,182,50,48,110,86,239,96,222,125,42,173,226,193,224,130,156,37,251,216,238,40,192,18]
qrGenPolyRaw 32 = [0,10,6,106,190,249,167,4,67,209,138,138,32,242,123,89,27,120,185,80,156,38,69,171,60,28,222,80,52,254,185,220,24]
qrGenPolyRaw 34 = [0,111,77,146,94,26,21,108,19,105,94,113,193,86,140,163,125,58,158,229,239,218,103,56,70,114,61,183,129,167,13,98,62,129,5]
qrGenPolyRaw 36 = [0,200,183,98,16,172,31,246,234,60,152,115,0,167,152,113,248,238,107,18,63,218,37,87,210,105,177,120,74,121,196,117,251,113,233,30,12]
qrGenPolyRaw 40 = [0,59,116,79,161,252,98,128,205,128,161,247,57,163,56,235,106,53,26,187,174,226,104,170,7,175,35,181,114,88,41,47,163,125,134,72,20,232,53,35,1]
qrGenPolyRaw 42 = [0,250,103,221,230,25,18,137,231,0,3,58,242,221,191,110,84,230,8,188,106,96,147,15,131,139,34,101,223,39,101,213,199,237,254,201,123,171,162,194,117,50,9]
qrGenPolyRaw 44 = [0,190,7,61,121,71,246,69,55,168,188,89,243,191,25,72,123,9,145,14,247,1,238,44,78,143,62,224,126,118,114,68,163,52,194,217,147,204,169,37,130,113,102,73,18]
qrGenPolyRaw 46 = [0,112,94,88,112,253,224,202,115,187,99,89,5,54,113,129,44,58,16,135,216,169,211,36,1,4,96,60,241,73,104,234,8,249,245,119,174,52,25,157,224,43,202,223,19,82,1]
qrGenPolyRaw 48 = [0,228,25,196,130,211,146,60,24,251,90,39,102,240,61,178,63,46,123,115,18,221,111,135,160,182,205,107,206,95,150,120,184,91,21,247,156,140,238,191,11,94,227,84,50,163,39,34,10]
qrGenPolyRaw 50 = [0,232,125,157,161,164,9,118,46,209,99,203,193,35,3,209,111,195,242,203,225,46,13,32,160,126,209,130,160,242,215,242,75,77,42,189,32,113,65,124,69,228,114,235,175,124,170,215,232,133,20]
qrGenPolyRaw 52 = [0,116,50,86,186,50,220,251,89,192,46,86,127,124,19,184,233,151,215,22,14,59,145,37,242,203,134,254,89,190,94,59,65,124,113,100,233,235,121,22,76,86,97,39,242,200,220,101,33,239,254,116,5]
qrGenPolyRaw 54 = [0,183,26,201,87,210,221,113,21,46,65,45,50,238,184,249,225,102,58,209,218,109,165,26,95,184,192,52,245,35,254,238,175,172,79,123,25,122,43,120,108,215,80,128,201,235,8,153,59,101,31,198,76,31,15]
qrGenPolyRaw 56 = [0,106,120,107,157,164,216,112,116,2,91,248,163,36,201,202,229,6,144,254,155,135,208,170,209,12,139,127,142,182,249,177,174,190,28,10,85,239,184,101,124,152,206,96,23,163,61,27,196,247,151,154,202,207,20,61,1]
qrGenPolyRaw 58 = [0,82,116,26,247,66,27,62,107,252,182,200,185,235,55,251,242,210,144,154,237,176,141,192,248,152,249,206,85,253,142,65,165,125,23,24,30,122,240,214,6,129,218,29,145,127,134,206,245,117,29,41,63,159,142,233,125,148,12]
qrGenPolyRaw 60 = [0,107,140,26,12,9,141,243,197,226,197,219,45,211,101,219,120,28,181,127,6,100,247,2,205,198,57,115,219,101,109,160,82,37,38,238,49,160,209,121,86,11,124,30,181,84,25,194,87,65,102,190,220,70,27,209,16,89,7,33,24]
qrGenPolyRaw 62 = [0,65,202,113,98,71,223,248,118,214,94,0,122,37,23,2,228,58,121,7,105,135,78,243,118,70,76,223,89,72,50,70,111,194,17,212,126,181,35,221,117,235,11,229,149,147,123,213,40,115,6,200,100,26,246,182,218,127,215,36,186,110,10]
qrGenPolyRaw 64 = [0,45,51,175,9,7,158,159,49,68,119,92,123,177,204,187,254,200,78,141,149,119,26,127,53,160,93,199,212,29,24,145,156,208,150,218,209,4,216,91,47,184,146,47,140,195,195,125,242,238,63,99,108,140,230,242,31,204,11,178,243,217,156,213,23]
qrGenPolyRaw 66 = [0,5,118,222,180,136,136,162,51,46,117,13,215,81,17,139,247,197,171,95,173,65,137,178,68,111,95,101,41,72,214,169,197,95,7,44,154,77,111,236,40,121,143,63,87,80,253,240,126,217,77,34,232,106,50,168,82,76,146,67,106,171,25,32,93,45,10]
qrGenPolyRaw 68 = [0,247,159,223,33,224,93,77,70,90,160,32,254,43,150,84,101,190,205,133,52,60,202,165,220,203,151,93,84,15,84,253,173,160,89,227,52,199,97,95,231,52,177,41,125,137,241,166,225,118,2,54,32,82,215,175,198,43,238,235,27,101,184,127,3,5,8,163,23]
qrGenPolyRaw _ = error "Invalid number of codewords"