{-# LANGUAGE MultiParamTypeClasses,FlexibleInstances #-}
module Main where

import System.Console.Editline.Readline
import Control.Exception as Exc
import System.Process
import System.Exit
import System.IO
import Control.Monad.Error
import Text.PrettyPrint  (render,text,nest, (<>),(<+>),($$),sep)
import Editor
import Operation
import Eval
import Parser
import Engine
import Undo 
import Paths_Hedi

-- | a SIO data made right for running the editor 
instance SIO IO where
	inputSio	= readline
	outputSio 	= putStrLn
	historySio	= addHistory
	errorSIO	= putStrLn
	readfileSio	= handleWith show . strictReadFile
	writefileSio x y = handleWith show (writeFile x y)	
	externalSio	= externalCommand 
	commandhelpSIO	= getDataFileName "command.help"

handleWith :: (IOError -> k) -> IO a -> ErrorT k IO a
handleWith h f 	= ErrorT $ Exc.catch (Right `fmap` f) (return . Left . h)
strictReadFile :: String -> IO String
strictReadFile x = readFile x >>= \x -> Exc.evaluate (length x) >> return x

-- |launches an external program , catching output and errors, return on exit
externalCommand :: String -> ErrorT String IO String
externalCommand s = ErrorT $ do
	(_,output,error,h) <- runInteractiveCommand s
	status <- waitForProcess h
	output <- hGetContents output
	error  <- hGetContents error
	return $ case status of 
		ExitSuccess -> Right output
		ExitFailure _ -> Left error

-- | the greetings
greetings 	:: IO ()
greetings = putStrLn . render $
	text "Hedi command line editor.      " <> (
		text "Version 0.1.1" $$
		text "Released under BSD licence." $$
		text "Copyright 2008 Paolo Veronelli" $$
		text "Homepage http://code.haskell.org/Hedi")
	$$ text " "
	$$ text "Type \"he\" for help or \"he command\"  for help on command"
	$$ text "Type \"CTRL-D\" to quit without saving"
		
main :: IO ()
main 	= do
	run 	(liftIO greetings >> commandLoop parse eval) 
		(Stato empty "" Nothing Nothing Nothing)
	return ()