content: {-#LANGUAGE TemplateHaskell#-}
  module Godot.Gdnative.Internal.TH where
  
  import Data.Maybe
  import Godot.Gdnative.Internal.Gdnative
  import Language.Haskell.TH
  import Language.Haskell.TH.Syntax
  import Foreign
  import qualified Data.Text as T
  
  generateAsVariantInstances :: Q [Dec]
  generateAsVariantInstances = do
    (TyConI (DataD _ _ bndrs _ cons _)) <- lookupTypeName "Variant" >>= \(Just x) -> reify x
    let tys = mapMaybe getCon cons
    mapM mkInstance tys
  
    where
      getCon (NormalC name [(_, AppT (AppT _ _) ty)]) = Just (name, ty)
      getCon (NormalC name [(_, ty)]) = Just (name, ty)
      getCon _ = Nothing
      mkInstance (name, ty)
        = instanceD (cxt []) (appT (conT $ mkName "AsVariant") (return ty))
            [ valD (varP $ mkName "toVariant") (normalB $ conE $ mkName $ nameBase name) []
            , valD (varP $ mkName "fromVariant") (normalB
                [| \var -> case var of
                     $(conP (mkName $ nameBase name) [varP $ mkName "x"]) -> Just x
                     _ -> Nothing |]) []
            , valD (varP $ mkName "variantType") (normalB
                [| \_ -> $(conE $ mkName $ T.unpack $ T.replace "Variant" "VariantType" $ T.pack $ nameBase name) |]) [] ]
  