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

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

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

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

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

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

koi8uList :: [Char]
koi8uList :: String
koi8uList =
	[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
'\x0454',Char
'\x2554',Char
'\x0456',Char
'\x0457'
	,Char
'\x2557',Char
'\x2558',Char
'\x2559',Char
'\x255a',Char
'\x255b',Char
'\x0491',Char
'\x255d',Char
'\x255e'
	,Char
'\x255f',Char
'\x2560',Char
'\x2561',Char
'\x0401',Char
'\x0403',Char
'\x2563',Char
'\x0406',Char
'\x0407'
	,Char
'\x2566',Char
'\x2567',Char
'\x2568',Char
'\x2569',Char
'\x256a',Char
'\x0490',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 KOI8U where
    decodeChar :: forall (m :: * -> *). ByteSource m => KOI8U -> m Char
decodeChar KOI8U
_ = do
      Word8
w <- m Word8
forall (m :: * -> *). ByteSource m => m Word8
fetchWord8
      if Word8
w Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< Word8
128
         then Char -> m Char
forall (m :: * -> *) a. Monad m => a -> m a
return (Char -> m Char) -> Char -> m Char
forall a b. (a -> b) -> a -> b
$ Int -> Char
chr (Int -> Char) -> Int -> Char
forall a b. (a -> b) -> a -> b
$ Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
w
         else Char -> m Char
forall (m :: * -> *) a. Monad m => a -> m a
return (Char -> m Char) -> Char -> m Char
forall a b. (a -> b) -> a -> b
$ UArray Word8 Char
koi8uArrUArray Word8 Char -> Word8 -> Char
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> i -> e
!Word8
w
    encodeChar :: forall (m :: * -> *). ByteSink m => KOI8U -> Char -> m ()
encodeChar KOI8U
_ Char
ch
	| Char
ch Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
< Char
'\128' = Word8 -> m ()
forall (m :: * -> *). ByteSink m => Word8 -> m ()
pushWord8 (Word8 -> m ()) -> Word8 -> m ()
forall a b. (a -> b) -> a -> b
$ Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word8) -> Int -> Word8
forall a b. (a -> b) -> a -> b
$ Char -> Int
ord Char
ch
	| Bool
otherwise   = case Char -> Map Char Word8 -> Maybe Word8
forall k a. Ord k => k -> Map k a -> Maybe a
lookup Char
ch Map Char Word8
koi8uMap of
		Just Word8
w  -> Word8 -> m ()
forall (m :: * -> *). ByteSink m => Word8 -> m ()
pushWord8 Word8
w
		Maybe Word8
Nothing -> EncodingException -> m ()
forall e (m :: * -> *) a. Throws e m => e -> m a
throwException (Char -> EncodingException
HasNoRepresentation Char
ch)
    encodeable :: KOI8U -> Char -> Bool
encodeable KOI8U
_ Char
c = Char -> Map Char Word8 -> Bool
forall k a. Ord k => k -> Map k a -> Bool
member Char
c Map Char Word8
koi8uMap