{-# LANGUAGE OverloadedStrings #-}
module Eventloop.Module.Websocket.Keyboard.Keyboard
    ( defaultKeyboardModuleConfiguration
    , defaultKeyboardModuleIOState
    , keyboardModuleIdentifier
    , keyboardInitializer
    , keyboardEventRetriever
    , keyboardTeardown
    ) where

import Data.Aeson
import Data.Maybe
import Control.Applicative
import qualified Data.ByteString.Lazy.Char8 as BL

import Eventloop.Types.EventTypes
import Eventloop.Module.Websocket.Keyboard.Types
import Eventloop.Utility.Config
import qualified Eventloop.Utility.BufferedWebsockets as WS


defaultKeyboardModuleConfiguration :: EventloopModuleConfiguration
defaultKeyboardModuleConfiguration = ( EventloopModuleConfiguration 
                                        keyboardModuleIdentifier
                                        defaultKeyboardModuleIOState
                                        (Just keyboardInitializer)
                                        (Just keyboardEventRetriever)
                                        Nothing
                                        Nothing
                                        (Just keyboardTeardown)
                                        Nothing
                                      )


defaultKeyboardModuleIOState :: IOState
defaultKeyboardModuleIOState = KeyboardState undefined undefined undefined

keyboardModuleIdentifier :: EventloopModuleIdentifier
keyboardModuleIdentifier = "keyboard"

                  
instance FromJSON Keyboard where
    parseJSON (Object v) = Key <$> v .: "key"

    
keyboardInitializer :: Initializer
keyboardInitializer sharedIO _ = do
                                    (recvBuffer, clientConn, serverSock) <- WS.setupWebsocketConnection ipAddress  keyboardPort
                                    return (sharedIO, KeyboardState recvBuffer clientConn serverSock)

                            
keyboardEventRetriever :: EventRetriever
keyboardEventRetriever sharedIO keyboardState = do
                                                    messages <- WS.takeMessages (receiveBuffer keyboardState)
                                                    return (sharedIO, keyboardState, map ((.) InKeyboard messageToKeyboardIn) messages)
                                        

messageToKeyboardIn :: WS.Message -> Keyboard
messageToKeyboardIn message = fromJust.decode $ BL.pack message


keyboardTeardown :: Teardown
keyboardTeardown sharedIO ks@(KeyboardState _ clientConn serverSock) = do
                                                                        WS.closeWebsocketConnection serverSock clientConn
                                                                        return (sharedIO, ks)