{-
    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 OverloadedStrings #-}
{-|
Module      : Monky.Outputs.I3
Description : Output module for i3-bar
Maintainer  : ongy
Stability   : testing
Portability : Linux

This module provides the output generation for i3-bar outputs.
Do note, if you are using this output, you have to compile monky
once before you are piping it to i3-bar.
GHC will output something during compilation step, this can't be avoided
by monky, this will break the output.
-}
module Monky.Outputs.I3
  ( I3Output
  , getI3Output
  )
where

import Monky.Modules
import Monky.Outputs.Unicode

import Control.Monad (unless)
import Data.Text (Text)
import qualified Data.Text as T
import qualified Data.Text.IO as T
import System.IO (hFlush, stdout)

-- |Output handle for i3-bar
data I3Output = I3Output

i3Full :: Text -> Text
i3Full xs = "\"full_text\": \"" `T.append` xs `T.append` "\""

getOut :: MonkyOut -> Text
getOut (MonkyPlain t)   = i3Full t
getOut (MonkyImage _ c)   = i3Full $ T.singleton c -- Images are not supported :(
getOut (MonkyBar p)     = i3Full $ T.singleton (barChar p)
getOut (MonkyHBar p)    = i3Full $ T.pack (replicate (p `div` 10) '█') `T.append` (T.singleton $ hBarChar (p `mod` 10 * 10))
getOut (MonkyColor (f, b) o) = T.concat
  [ getOut o
  , ", \"color\": \""
  , f
  , "\", \"background\": \""
  , b
  , "\""
  ]

doSegment :: [MonkyOut] -> IO ()
doSegment [] = return ()
doSegment [x] = do
  putChar '{'
  T.putStr $ getOut x
  putChar '}'
doSegment (x:xs) = do
  putChar '{'
  T.putStr $ getOut x
  putStr ", \"separator\": false"
  putStr ", \"separator_block_width\": 1"
  putStr "},"
  doSegment xs

outputLine :: [[MonkyOut]] -> IO ()
outputLine [] = error "i3-output outputLIne should never be called with an empty list"
outputLine [x] = doSegment x
outputLine (x:xs) = do
  doSegment x
  unless (null x) (putChar ',')
  outputLine xs

instance MonkyOutput I3Output where
  doLine _ xs = do
    putChar '['
    outputLine xs
    putStr "],"
    putChar '\n'
    hFlush stdout


-- | Get output handle for i3-bar. This initializes the communication on generation
getI3Output :: IO I3Output
getI3Output = do
  putStrLn "{\"version\":1}" -- Static version thingy we have to print
  putChar '[' -- Start the output lines array
  return I3Output