{-# LANGUAGE DeriveDataTypeable #-}
{- | This module implements KOI8-R encoding which covers the russian and bulgarian alphabet.
     See <http://en.wikipedia.org/wiki/KOI8-R> for more information.
 -}
module Data.Encoding.KOI8R
	(KOI8R(..)) where

import Control.Throws
import Data.Array.Unboxed
import Data.Char (ord,chr)
import Data.Map hiding (map,(!))
import Data.Word
import Prelude hiding (lookup)
import Data.Typeable

import Data.Encoding.Base
import Data.Encoding.ByteSource
import Data.Encoding.ByteSink
import Data.Encoding.Exception

data KOI8R = KOI8R deriving (KOI8R -> KOI8R -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: KOI8R -> KOI8R -> Bool
$c/= :: KOI8R -> KOI8R -> Bool
== :: KOI8R -> KOI8R -> Bool
$c== :: KOI8R -> KOI8R -> Bool
Eq,Int -> KOI8R -> ShowS
[KOI8R] -> ShowS
KOI8R -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [KOI8R] -> ShowS
$cshowList :: [KOI8R] -> ShowS
show :: KOI8R -> String
$cshow :: KOI8R -> String
showsPrec :: Int -> KOI8R -> ShowS
$cshowsPrec :: Int -> KOI8R -> ShowS
Show,Typeable)

koi8rArr :: UArray Word8 Char
koi8rArr :: UArray Word8 Char
koi8rArr = forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
(i, i) -> [e] -> a i e
listArray (Word8
128,Word8
255) String
koi8rList

koi8rMap :: Map Char Word8
koi8rMap :: Map Char Word8
koi8rMap = forall k a. Ord k => [(k, a)] -> Map k a
fromList (forall a b. [a] -> [b] -> [(a, b)]
zip String
koi8rList [Word8
128..])

koi8rList :: [Char]
koi8rList :: String
koi8rList =
	[Char
'\x2500',Char
'\x2502',Char
'\x250c',Char
'\x2510',Char
'\x2514',Char
'\x2518',Char
'\x251c',Char
'\x2524'
	,Char
'\x252c',Char
'\x2534',Char
'\x253c',Char
'\x2580',Char
'\x2584',Char
'\x2588',Char
'\x258c',Char
'\x2590'
	,Char
'\x2591',Char
'\x2592',Char
'\x2593',Char
'\x2320',Char
'\x25a0',Char
'\x2219',Char
'\x221a',Char
'\x2248'
	,Char
'\x2264',Char
'\x2265',Char
'\x00a0',Char
'\x2321',Char
'\x00b0',Char
'\x00b2',Char
'\x00b7',Char
'\x00f7'
	,Char
'\x2550',Char
'\x2551',Char
'\x2552',Char
'\x0451',Char
'\x2553',Char
'\x2554',Char
'\x2555',Char
'\x2556'
	,Char
'\x2557',Char
'\x2558',Char
'\x2559',Char
'\x255a',Char
'\x255b',Char
'\x255c',Char
'\x255d',Char
'\x255e'
	,Char
'\x255f',Char
'\x2560',Char
'\x2561',Char
'\x0401',Char
'\x2562',Char
'\x2563',Char
'\x2564',Char
'\x2565'
	,Char
'\x2566',Char
'\x2567',Char
'\x2568',Char
'\x2569',Char
'\x256a',Char
'\x256b',Char
'\x256c',Char
'\x00a9'
	,Char
'\x044e',Char
'\x0430',Char
'\x0431',Char
'\x0446',Char
'\x0434',Char
'\x0435',Char
'\x0444',Char
'\x0433'
	,Char
'\x0445',Char
'\x0438',Char
'\x0439',Char
'\x043a',Char
'\x043b',Char
'\x043c',Char
'\x043d',Char
'\x043e'
	,Char
'\x043f',Char
'\x044f',Char
'\x0440',Char
'\x0441',Char
'\x0442',Char
'\x0443',Char
'\x0436',Char
'\x0432'
	,Char
'\x044c',Char
'\x044b',Char
'\x0437',Char
'\x0448',Char
'\x044d',Char
'\x0449',Char
'\x0447',Char
'\x044a'
	,Char
'\x042e',Char
'\x0410',Char
'\x0411',Char
'\x0426',Char
'\x0414',Char
'\x0415',Char
'\x0424',Char
'\x0413'
	,Char
'\x0425',Char
'\x0418',Char
'\x0419',Char
'\x041a',Char
'\x041b',Char
'\x041c',Char
'\x041d',Char
'\x041e'
	,Char
'\x041f',Char
'\x042f',Char
'\x0420',Char
'\x0421',Char
'\x0422',Char
'\x0423',Char
'\x0416',Char
'\x0412'
	,Char
'\x042c',Char
'\x042b',Char
'\x0417',Char
'\x0428',Char
'\x042d',Char
'\x0429',Char
'\x0427',Char
'\x042a'
	]

instance Encoding KOI8R where
    decodeChar :: forall (m :: * -> *). ByteSource m => KOI8R -> m Char
decodeChar KOI8R
_ = do
      Word8
w <- forall (m :: * -> *). ByteSource m => m Word8
fetchWord8
      if Word8
w forall a. Ord a => a -> a -> Bool
< Word8
128
        then forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Int -> Char
chr forall a b. (a -> b) -> a -> b
$ forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
w
        else forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ UArray Word8 Char
koi8rArrforall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> i -> e
!Word8
w
    encodeChar :: forall (m :: * -> *). ByteSink m => KOI8R -> Char -> m ()
encodeChar KOI8R
_ Char
ch
	| Char
ch forall a. Ord a => a -> a -> Bool
< Char
'\128' = forall (m :: * -> *). ByteSink m => Word8 -> m ()
pushWord8 forall a b. (a -> b) -> a -> b
$ forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ Char -> Int
ord Char
ch
	| Bool
otherwise   = case forall k a. Ord k => k -> Map k a -> Maybe a
lookup Char
ch Map Char Word8
koi8rMap of
		Just Word8
w -> forall (m :: * -> *). ByteSink m => Word8 -> m ()
pushWord8 Word8
w
		Maybe Word8
Nothing -> forall e (m :: * -> *) a. Throws e m => e -> m a
throwException (Char -> EncodingException
HasNoRepresentation Char
ch)
    encodeable :: KOI8R -> Char -> Bool
encodeable KOI8R
_ Char
c = forall k a. Ord k => k -> Map k a -> Bool
member Char
c Map Char Word8
koi8rMap