{-# OPTIONS_GHC -Wall #-}
module QuickWeave.QuasiQuoter (qweaveQQWith) where

import Language.Haskell.Exts.Annotated

import Language.Haskell.Suite.QuasiQuoter
import Language.Haskell.Suite.Transformer

import qualified QuickWeave.TransformationsList as TS

import Control.Monad

import Data.Generics.Uniplate.Data hiding (Transformer)

import Language.Haskell.TH.Quote

qweaveQQWith :: [String] -> QuasiQuoter 
qweaveQQWith opts = quasiQuoter (tValid opts) 
 
tValid :: [String] -> 
  (Transformer Exp
  ,Transformer Pat 
  ,Transformer Type
  ,Transformer Decl)
tValid opts = let validTrans = filter (\tr-> (optionName tr) `elem` opts) 
                               TS.transformations
              in                  
               (\ e  -> foldM (\e'  t -> tE t opts e' ) e  validTrans
               ,\ p  -> foldM (\p'  t -> tP t opts p' ) p  validTrans
               ,\ ty -> foldM (\ty' t -> tT t opts ty') ty validTrans
               ,\ d  -> foldM (\d'  t -> tD t opts d' ) d  validTrans)

tD :: Transformation -> [String] -> Transformer Decl 
tD  t opts d = do  
  tDec <- transformBiM (transDec t opts) d 
  tTyp <- transformBiM (transTyp t opts) tDec 
  tPat <- transformBiM (transPat t opts) tTyp 
  transformBiM (transExp t opts) tPat 
  
tT :: Transformation -> [String] -> Transformer Type 
tT  t opts ty = transformBiM (transTyp t opts) ty
 
tP :: Transformation -> [String] -> Transformer Pat 
tP  t opts p = do  
  tTyp <- transformBiM (transTyp t opts) p 
  tPat <- transformBiM (transPat t opts) tTyp 
  transformBiM (transExp t opts) tPat 

tE :: Transformation -> [String] -> Transformer Exp 
tE  t opts e = do  
  tTyp <- transformBiM (transTyp t opts) e 
  tPat <- transformBiM (transPat t opts) tTyp 
  transformBiM (transExp t opts) tPat 