{-# LANGUAGE OverloadedStrings #-}

-- |
-- Module      :  Users.dd..dwork.hs.hero-club-five-tenets.ACME.Acme.HeroClub.FiveTenets
-- Copyright   :  I am D. 2015-2016
-- License     :  BSD3
--
-- Maintainer  :  d.kupanhy@gmail.com
-- Stability   :  stable
--
-- This package give you Hero Club Five Tenets, Yuki Yuna is a Hero.
--
module Acme.HeroClub.FiveTenets
    ( Lang (..)
    , No (..)
    , putFiveTenetsIn
    , putOneTenetIn
    , putRndTenetIn
    ) where

import qualified Data.Text as T
import qualified Data.Text.IO as T
import System.Random (StdGen, newStdGen, randomR)


-- | Language dispaly.
data Lang = Japan | English


-- | Number of five Tenets.
data No = One | Two | Three | Four | Five deriving ( Bounded, Enum )

class FiveTenets t where
    tenets :: t -> No ->  T.Text

instance FiveTenets Lang where
    tenets Japan One   = "挨拶はきちんと!"
    tenets Japan Two   = "なるべく諦めない!"
    tenets Japan Three = "よく寝て、よく食べる!"
    tenets Japan Four  = "悩んだら相談!"
    tenets Japan Five  = "なせば大抵なんとかなる!"

    tenets English One   = "Give a good greeting!"
    tenets English Two   = "Try not to give up!"
    tenets English Three = "Sleep well, eat well!"
    tenets English Four  = "If you're troubled, talk to someone!"
    tenets English Five  = "You're likely to succeed if you try!"

title :: T.Text -> T.Text
title t = "-- " `T.append` t `T.append` " --"

heroClub :: Lang -> T.Text
heroClub Japan = "勇者部五箇条!"
heroClub English = "Hero Club Five Tenets!"

cnt :: Lang -> T.Text
cnt Japan   = "一つ、"
cnt English = "One, "

oneOfTheTenetsIn :: Lang -> No -> T.Text
oneOfTheTenetsIn lang no = heroClub lang `T.append` " " `T.append` cnt lang `T.append` tenets lang no


fiveTenetsIn :: Lang -> T.Text
fiveTenetsIn lang = title (heroClub lang) `T.append` "\n" `T.append` foldl T.append T.empty ( map (flip T.snoc '\n' . T.append (cnt lang) . tenets lang) [minBound :: No .. maxBound :: No] )


-- | You select a language and dispaly Five Tenets.
--
-- @
-- >>> putFiveTenetsIn English
-- -- Hero Club Five Tenets! --
-- One, Give a good greeting!
-- One, Try not to give up!
-- One, Sleep well, eat well!
-- One, If you're troubled, talk to someone!
-- One, You're likely to succeed if you try!
-- @
--
--
-- @
-- >>> putFiveTenetsIn Japan
--  -- 勇者部五箇条! --
--  一つ、挨拶はきちんと!
--  一つ、なるべく諦めない!
--  一つ、よく寝て、よく食べる!
--  一つ、悩んだら相談!
--  一つ、なせば大抵なんとかなる!
-- @
--
putFiveTenetsIn :: Lang -> IO ()
putFiveTenetsIn = T.putStr . fiveTenetsIn


-- | Dispaly one of five tenets you have selected.
--
-- @
-- >>> putOneTenetIn English One
--  Hero Club Five Tenets! One, Give a good greeting!
--
-- >>> putOneTenetIn Japan Two
--  勇者部五箇条! 一つ、なるべく諦めない!
--
-- >>> putOneTenetIn English Three
--  Hero Club Five Tenets! One, Sleep well, eat well!
--
-- >>> putOneTenetIn English Four
--  Hero Club Five Tenets! One, If you're troubled, talk to someone!
--
-- >>> putOneTenetIn Japan Five
--  勇者部五箇条! 一つ、なせば大抵なんとかなる!
--
-- @
--
putOneTenetIn :: Lang -> No -> IO ()
putOneTenetIn lang no = T.putStrLn $ oneOfTheTenetsIn lang no


-- | Dispaly one of five tenets at random.
putRndTenetIn :: Lang -> IO ()
putRndTenetIn lang = do
    gen <- newStdGen
    let (n, _) = randomR (0,4) gen :: (Int, StdGen)
    let no = [minBound :: No .. maxBound :: No] !! n
    putOneTenetIn lang no