content: {-
      Copyright 2016 Markus Ongyerth
  
      This file is part of Monky.
  
      Monky is free software: you can redistribute it and/or modify
      it under the terms of the GNU Lesser General Public License as published by
      the Free Software Foundation, either version 3 of the License, or
      (at your option) any later version.
  
      Monky is distributed in the hope that it will be useful,
      but WITHOUT ANY WARRANTY; without even the implied warranty of
      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      GNU Lesser General Public License for more details.
  
      You should have received a copy of the GNU Lesser General Public License
      along with Monky.  If not, see <http://www.gnu.org/licenses/>.
  -}
  {-# LANGUAGE CPP #-}
  {-|
  Module      : Monky.Examples.Modify
  Description : Monky module that modifies other modules output
  Maintainer  : ongy
  Stability   : testing
  Portability : Linux
  
  Example that limits MPD song title to 20 characters
  
  @
  import Data.Text as T
  
  modifyMPD :: [MonkyOut] -> [MonkyOut]
  modifyMPD orig@(MonkyPlain xs:ys) =
    if T.length xs > 20
       then MonkyPlain (T.take 17 xs `T.append` "..."):ys
       else orig
  
  
  evtPack    $ getModifyHandle modifyMPD $ getMPDHandle "127.0.0.1" "6600"
  @
  
  -}
  module Monky.Examples.Modify
    ( ModifyHandle
    , getModifyHandle
  
    , IOModifyHandle
    , getIOModifyHandle
  
    , changeImage
    )
  where
  
  #if MIN_VERSION_base(4,8,0)
  #else
  import Control.Applicative ((<$>))
  #endif
  
  import Monky.Modules
  
  -- |Handle for duing pure modification of module output
  data ModifyHandle a = MH ([MonkyOut] -> [MonkyOut]) a
  
  -- |Get a handle to purely modify another modules output
  getModifyHandle :: ([MonkyOut] -> [MonkyOut]) -> IO a -> IO (ModifyHandle a)
  getModifyHandle = fmap . MH
  
  instance PollModule a => PollModule (ModifyHandle a) where
    initialize (MH _ m) = initialize m
    getOutput (MH fun m) = fun <$> getOutput m
  
  instance EvtModule a => EvtModule (ModifyHandle a) where
    startEvtLoop (MH fun m) f = startEvtLoop m (f . fun)
  
  
  -- |Handle for modifying output in IO monad
  data IOModifyHandle a = IOMH ([MonkyOut] -> IO [MonkyOut]) a
  
  -- |Get a handle that can modify another handles output in the IO monad
  getIOModifyHandle :: ([MonkyOut] -> IO [MonkyOut]) -> IO a -> IO (IOModifyHandle a)
  getIOModifyHandle fun = fmap (IOMH fun)
  
  instance PollModule a => PollModule (IOModifyHandle a) where
    initialize (IOMH _ m) = initialize m
    getOutput (IOMH fun m) = fun =<< getOutput m
  
  instance EvtModule a => EvtModule (IOModifyHandle a) where
    startEvtLoop (IOMH fun m) f = startEvtLoop m (\e -> f =<< fun e)
  
  -- |Change the replacemant char in an monky image (if your font doesn't support it), returns initial value if not an image
  changeImage :: Char -> MonkyOut -> MonkyOut
  changeImage c (MonkyImage x _) = MonkyImage x c
  changeImage _ x                = x
  