listenLoop :: MIrc -> IO ()
listenLoop s = do
  server <- readMVar s

  let h = fromJust $ sSock server
  eof <- timeout (sPingTimeoutInterval server) $ hIsEOF h

  -- If EOF then we are disconnected
  if (eof /= Just False)
    then do
      modifyMVar_ s (\serv -> return $ serv {sSock = Nothing})
      Foldable.mapM_ (callDisconnectFunction s) (sEvents server)
    else do
      line <- B.hGetLine h

      server1 <- takeMVar s

      -- Print the received line.
      debugWrite server1 $ (B.pack ">> ") `B.append` line

      -- Call the internal events
      newServ <- foldM (\sr f -> f sr (parse line)) server1 internalEvents

      putMVar s newServ -- Put the MVar back.

      let parsed = (parse line)
      -- Call the events
      callEvents s parsed

      -- Call the RawMsg Events.
      events s (RawMsg undefined) parsed


      listenLoop s
  where
    callDisconnectFunction mIrc (Disconnect f) = f mIrc
    callDisconnectFunction _ _ = return ()

-- Internal Events - They can edit the server
listenLoop :: MIrc -> IO ()
listenLoop s = do
  server <- readMVar s

  let h = fromJust $ sSock server
  eof <- timeout (sPingTimeoutInterval server) $ hIsEOF h

  -- If EOF then we are disconnected
  if (eof /= Just False)
    then do
      modifyMVar_ s (\serv -> return $ serv {sSock = Nothing})
      Foldable.mapM_ (callDisconnectFunction s) (sEvents server)
    else do
      line <- B.hGetLine h

      server1 <- takeMVar s

      -- Print the received line.
      debugWrite server1 $ (B.pack ">> ") `B.append` line

      -- Call the internal events
      newServ <- foldM (\sr f -> f sr (parse line)) server1 internalEvents

      putMVar s newServ -- Put the MVar back.

      let parsed = (parse line)
      -- Call the events
      callEvents s parsed

      -- Call the RawMsg Events.
      events s (RawMsg undefined) parsed


      listenLoop s
  where
    callDisconnectFunction mIrc (Disconnect f) = f mIrc
    callDisconnectFunction _ _ = return ()

-- Internal Events - They can edit the server
listenLoop s = do
  server <- readMVar s

  let h = fromJust $ sSock server
  eof <- timeout (sPingTimeoutInterval server) $ hIsEOF h

  -- If EOF then we are disconnected
  if (eof /= Just False)
    then do
      modifyMVar_ s (\serv -> return $ serv {sSock = Nothing})
      Foldable.mapM_ (callDisconnectFunction s) (sEvents server)
    else do
      line <- B.hGetLine h

      server1 <- takeMVar s

      -- Print the received line.
      debugWrite server1 $ (B.pack ">> ") `B.append` line

      -- Call the internal events
      newServ <- foldM (\sr f -> f sr (parse line)) server1 internalEvents

      putMVar s newServ -- Put the MVar back.

      let parsed = (parse line)
      -- Call the events
      callEvents s parsed

      -- Call the RawMsg Events.
      events s (RawMsg undefined) parsed


      listenLoop s
  where
    callDisconnectFunction mIrc (Disconnect f) = f mIrc
    callDisconnectFunction _ _ = return ()

-- Internal Events - They can edit the server