{-# LANGUAGE Trustworthy #-}

-- |
-- Module      : Codec.Dvorak
-- Description : Dvorak encoding1 for Haskell.
-- Copyright   : (c) Kyle Van Berendonck, 2014
-- License     : BSD3
-- Maintainer  : kvanberendonck@gmail.com
-- Stability   : experimental
-- Portability : portable
--
-- This module exposes all the API for this package.
module Codec.Dvorak
    ( toDvorakChar
    , toDvorak
    , fromDvorakChar
    , fromDvorak
    ) where

import           Data.Tuple
import qualified Data.Map.Strict as Map


toTable :: Map.Map Char Char
toTable = Map.fromList $ zip
  "-=qwertyuiop[]asdfghjkl;'zxcvbnm,./_+QWERTYUIOP{}ASDFGHJKL:\"ZXCVBNM<>?"
  "[]',.pyfgcrl/=aoeuidhtns-;qjkxbmwvz{}\"<>PYFGCRL?+AOEUIDHTNS_:QJKXBMWVZ"

fromTable :: Map.Map Char Char
fromTable = Map.fromList . map swap . Map.assocs $ toTable

-- | Encodes a single given 'Char' to its dvorak encoded equivalent.
toDvorakChar :: Char -> Char
toDvorakChar c = case Map.lookup c toTable of
  Just x  -> x
  Nothing -> c
{-# INLINABLE toDvorakChar #-}

-- | Encodes a string to its dvorak encoded equivalent using 'toDvorakChar'. Analagous to:
-- 
-- @
--    toDvorak = map toDvorakChar
-- @
toDvorak :: String -> String
toDvorak = map toDvorakChar
{-# INLINE toDvorak #-}

-- | Decodes a single given 'Char' from its dvorak encoded equivalent.
fromDvorakChar :: Char -> Char
fromDvorakChar c = case Map.lookup c fromTable of
  Just x  -> x
  Nothing -> c
{-# INLINABLE fromDvorakChar #-}

-- | Decodes a string from its dvorak encoded equivalent using 'fromDvorakChar'. Analagous to:
--
-- @
--    fromDvorak = map fromDvorakChar
-- @
fromDvorak :: String -> String
fromDvorak = map fromDvorakChar
{-# INLINE fromDvorak #-}