-- | Haskell project name generation
-- semi-joke
module Lambdabot.Plugin.Misc.Fresh (freshPlugin) where

import Lambdabot.Plugin

import Control.Monad.Trans
import Data.Char

type Fresh = ModuleT Integer LB

freshPlugin :: Module Integer
freshPlugin :: Module Integer
freshPlugin = forall st. Module st
newModule
    { moduleDefState :: LB Integer
moduleDefState = forall (m :: * -> *) a. Monad m => a -> m a
return Integer
0
    , moduleSerialize :: Maybe (Serial Integer)
moduleSerialize = forall a. a -> Maybe a
Just forall s. (Show s, Read s) => Serial s
stdSerial
    
    , moduleCmds :: ModuleT Integer LB [Command (ModuleT Integer LB)]
moduleCmds = forall (m :: * -> *) a. Monad m => a -> m a
return
        [ (String -> Command Identity
command String
"freshname")
            { help :: Cmd (ModuleT Integer LB) ()
help = forall (m :: * -> *). Monad m => String -> Cmd m ()
say String
"freshname. Return a unique Haskell project name."
            , process :: String -> Cmd (ModuleT Integer LB) ()
process = \String
_ -> forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift Fresh String
fresh forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall (m :: * -> *). Monad m => String -> Cmd m ()
say
            }
        ]
    }

fresh :: Fresh String
fresh :: Fresh String
fresh = forall (m :: * -> *) a.
MonadLBState m =>
(LBState m -> (LBState m -> m ()) -> m a) -> m a
withMS forall a b. (a -> b) -> a -> b
$ \LBState (ModuleT Integer LB)
n LBState (ModuleT Integer LB) -> ModuleT Integer LB ()
f -> do
    LBState (ModuleT Integer LB) -> ModuleT Integer LB ()
f (LBState (ModuleT Integer LB)
nforall a. Num a => a -> a -> a
+Integer
1)
    forall (m :: * -> *) a. Monad m => a -> m a
return (String
"Ha" forall a. [a] -> [a] -> [a]
++ forall a. [a] -> [a]
reverse (Integer -> String
asName LBState (ModuleT Integer LB)
n))

asName :: Integer -> String
asName :: Integer -> String
asName Integer
i
    | Integer
i forall a. Eq a => a -> a -> Bool
== Integer
0    = [Int -> Char
chr (Char -> Int
ord Char
'a')]
    | Integer
r forall a. Eq a => a -> a -> Bool
== Integer
0    = [Int -> Char
chr (Char -> Int
ord Char
'a' forall a. Num a => a -> a -> a
+ (forall a b. (Integral a, Num b) => a -> b
fromIntegral Integer
a))]
    | Bool
otherwise =  Int -> Char
chr (Char -> Int
ord Char
'a' forall a. Num a => a -> a -> a
+ (forall a b. (Integral a, Num b) => a -> b
fromIntegral Integer
a)) forall a. a -> [a] -> [a]
: Integer -> String
asName Integer
r
    where
      (Integer
r,Integer
a) = Integer
i forall a. Integral a => a -> a -> (a, a)
`quotRem` Integer
26