module Igor2.Ppr (

    showp, set, asMap, asRepl, 

    (<^>), ($$), patternNotDef,

    module Text.PrettyPrint.ANSI.Leijen,
)where

import Prelude hiding ((<$>))

import qualified Data.Map as M
import qualified Data.Set as S
import qualified Data.Bimap as B
import qualified Data.Foldable as F
import Data.Maybe

import Data.Maybe (maybeToList)

--import System.Time
import Debug.Trace

import Text.PrettyPrint.ANSI.Leijen

 
--------------------------------------------------------------------------------
-- Pretty Utils
--------------------------------------------------------------------------------

x $$ y = align (x <$> y)
x <^> y = x <$> ( indent 2 y )


patternNotDef :: [Doc] -> Doc
patternNotDef as = text "Pattern not defined !!!" <$>
                   vsep [ text "arg" <> int i <+> a | (a, i) <- zip as [1..]]


showp :: (Pretty a) => a -> String
showp = show.pretty

--------------------------------------------------------------------------------
-- Pretty Helpers
--------------------------------------------------------------------------------

  
set  l = braces $ align $ hcat $ punctuate comma l

asMap (a,b) = 
    lparen <> (pretty a) <+> ((text "|->" ) <> softbreak <> indent 2 (pretty b) <> rparen)
    
asRepl (a,b) = 
    lparen <> (pretty a) <+> ((text "<~" ) <+> softbreak <> align (pretty b) <> rparen)



--------------------------------------------------------------------------------
-- Pretty Instances
--------------------------------------------------------------------------------

instance Pretty Ordering where
    pretty = text.show
   
instance (Pretty a,Pretty b,Pretty c,Pretty d) => Pretty (a,b,c,d) where
  pretty (w,x,y,z)= tupled [pretty w, pretty x, pretty y, pretty z]
  
instance (Pretty a,Pretty b) => Pretty (Either a b) where
  pretty (Left a)= text "Left" <+> pretty a
  pretty (Right b)= text "Right" <+> pretty b
   
instance (Pretty a,Pretty b,Pretty c,Pretty d,Pretty e) => Pretty (a,b,c,d,e) where
  pretty (v,w,x,y,z)= tupled [pretty v,pretty w, pretty x, pretty y, pretty z]
   
instance (Pretty a,Pretty b,Pretty c,Pretty d,Pretty e,Pretty f) => Pretty (a,b,c,d,e,f) where
  pretty (u,v,w,x,y,z)= tupled [pretty u, pretty v, pretty w, pretty x, pretty y, pretty z]

instance (Pretty a,Pretty b,Pretty c,Pretty d,Pretty e,Pretty f,Pretty g) => Pretty (a,b,c,d,e,f,g) where
  pretty (t,u,v,w,x,y,z)= tupled [pretty t,pretty u, pretty v, pretty w, pretty x, pretty y, pretty z]

instance (Pretty a,Pretty b,Pretty c,Pretty d,Pretty e,Pretty f,Pretty g,Pretty h) => Pretty (a,b,c,d,e,f,g,h) where
  pretty (s,t,u,v,w,x,y,z)= tupled [pretty s,pretty t,pretty u, pretty v, pretty w, pretty x, pretty y, pretty z]

instance (Pretty k, Pretty v) => Pretty (M.Map k v) where
    pretty m = list $ map asMap (M.toList m)
    
--instance (Pretty v) => Pretty (IM.IntMap v) where
--    pretty m = list $ map asMap (IM.toList m)

instance (Pretty e) => Pretty (S.Set e) where
    pretty s = semiBraces $ map pretty (S.toList s)
    
--instance (Pretty e) => Pretty (Sq.Seq e) where
--    pretty = pretty . F.toList
--    
--instance Pretty (IS.IntSet) where
--    pretty s = set $ map pretty (IS.toList s)
    
instance (Pretty a, Pretty b) => Pretty (B.Bimap a b) where
    pretty b = list $ map asMap (B.toAscList b) 
    
--instance Pretty TimeDiff where
--    pretty t 
--        | tdYear t == 0 && tdMonth t == 0 = 
--            text (show $ 24 * tdDay t + tdHour t) <> text "h" <+>
--            text (show $ tdMin t) <> text "m" <+>
--            text (show $ fromIntegral (tdSec t)  + 1.0e-12 *  fromIntegral (tdPicosec t)) <> text "s"
--        | otherwise = text "Cannot print a TimeDiff with Month or Year field set"
