module Kewar.Layout (placeBits, Grid, Module (..), Position, cols, rows) where

import Kewar.Layout.Constants (size)
import Kewar.Layout.Data (dataBits)
import Kewar.Layout.FormatVersion (format, formatLocations, version, versionLocations)
import Kewar.Layout.FunctionalPatterns (functionalPatterns)
import Kewar.Layout.Interleaving (interleave)
import Kewar.Layout.Masking (optimalMask)
import Kewar.Layout.Types (Grid, Module (..), Position, cols, insert, mkGrid, rows)
import Kewar.Types (CorrectionLevel, Group, Version)

placeBits :: Version -> CorrectionLevel -> [Group] -> [Group] -> Grid
placeBits :: Version -> CorrectionLevel -> [Group] -> [Group] -> Grid
placeBits Version
v CorrectionLevel
cl [Group]
dataCodeWords [Group]
errorCodeWords = do
  let s :: Version
s = Version -> Version
size Version
v
  let g :: Grid
g = Size -> Grid
mkGrid ((Version
0, Version
0), (Version
s Version -> Version -> Version
forall a. Num a => a -> a -> a
-Version
1, Version
s Version -> Version -> Version
forall a. Num a => a -> a -> a
-Version
1))

  let fps :: [(Position, Module)]
fps = Version -> [(Position, Module)]
functionalPatterns Version
v
  let functionalPatternsLocations :: [Position]
functionalPatternsLocations = ((Position, Module) -> Position)
-> [(Position, Module)] -> [Position]
forall a b. (a -> b) -> [a] -> [b]
map (Position, Module) -> Position
forall a b. (a, b) -> a
fst [(Position, Module)]
fps
  let forbiddenLocations :: [Position]
forbiddenLocations = [[Position]] -> [Position]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat (Version -> [[Position]]
formatLocations Version
v) [Position] -> [Position] -> [Position]
forall a. [a] -> [a] -> [a]
++ [[Position]] -> [Position]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat (Version -> [[Position]]
versionLocations Version
v) [Position] -> [Position] -> [Position]
forall a. [a] -> [a] -> [a]
++ [Position]
functionalPatternsLocations

  let interleaved :: BitString
interleaved = Version -> [Group] -> [Group] -> BitString
interleave Version
v [Group]
dataCodeWords [Group]
errorCodeWords
  let g' :: Grid
g' = Grid -> [(Position, Module)] -> Grid
insert Grid
g ([(Position, Module)]
fps [(Position, Module)]
-> [(Position, Module)] -> [(Position, Module)]
forall a. [a] -> [a] -> [a]
++ Version -> BitString -> [Position] -> [(Position, Module)]
dataBits Version
s BitString
interleaved [Position]
forbiddenLocations)

  let (Grid
masked, Version
pattern) = [Position] -> Grid -> (Grid, Version)
optimalMask [Position]
forbiddenLocations Grid
g'
  let formatModules :: [(Position, Module)]
formatModules = Version -> CorrectionLevel -> Version -> [(Position, Module)]
format Version
v CorrectionLevel
cl Version
pattern
  let versionModules :: [(Position, Module)]
versionModules = Version -> [(Position, Module)]
version Version
v

  Grid -> [(Position, Module)] -> Grid
insert Grid
masked ([(Position, Module)]
formatModules [(Position, Module)]
-> [(Position, Module)] -> [(Position, Module)]
forall a. [a] -> [a] -> [a]
++ [(Position, Module)]
versionModules)