doModeChange ::
  UserInfo     {- ^ who           -} ->
  Identifier   {- ^ target        -} ->
  ByteString   {- ^ modes changed -} ->
  [ByteString] {- ^ arguments     -} ->
  IrcConnection -> Logic IrcConnection
doModeChange who target modes0 args0 conn
  | isChannelName target conn =
      case splitModes modeSettings modes0 args0 of
        Nothing -> return conn
        Just ms -> doChannelModeChanges ms who target conn

  -- TODO: Implement user modes
  | otherwise =
      case splitModes (view connUserModeTypes conn) modes0 args0 of
        Nothing -> return conn
        Just ms -> return (doUserModeChanges ms conn)

  where
  modeSettings = view connChanModeTypes conn
doModeChange ::
  UserInfo     {- ^ who           -} ->
  Identifier   {- ^ target        -} ->
  ByteString   {- ^ modes changed -} ->
  [ByteString] {- ^ arguments     -} ->
  IrcConnection -> Logic IrcConnection
doModeChange who target modes0 args0 conn
  | isChannelName target conn =
      case splitModes modeSettings modes0 args0 of
        Nothing -> return conn
        Just ms -> doChannelModeChanges ms who target conn

  -- TODO: Implement user modes
  | otherwise =
      case splitModes (view connUserModeTypes conn) modes0 args0 of
        Nothing -> return conn
        Just ms -> return (doUserModeChanges ms conn)

  where
  modeSettings = view connChanModeTypes conn
doModeChange who target modes0 args0 conn
  | isChannelName target conn =
      case splitModes modeSettings modes0 args0 of
        Nothing -> return conn
        Just ms -> doChannelModeChanges ms who target conn

  -- TODO: Implement user modes
  | otherwise =
      case splitModes (view connUserModeTypes conn) modes0 args0 of
        Nothing -> return conn
        Just ms -> return (doUserModeChanges ms conn)

  where
  modeSettings = view connChanModeTypes conn