{-# LANGUAGE OverloadedStrings #-} module Model.Mail ( mailSubject , mailBody ) where import Data.Text (Text) import qualified Data.Text as T import Data.Maybe (fromMaybe) import Model.Date import Model.Event data Time = Today | NextWeek deriving (Eq, Show) mailSubject :: [Event] -> [Event] -> Text mailSubject eventsToday eventsNextWeek = T.concat [ "Hey, " , if not . null $ eventsToday then mailSubjectSentence Today eventsToday else "" , if not . null $ eventsNextWeek then T.concat [ if not . null $ eventsToday then " and " else "" , mailSubjectSentence NextWeek eventsNextWeek ] else "" , "!" ] mailSubjectSentence :: Time -> [Event] -> Text mailSubjectSentence time events = let count = length events in T.concat [ case time of Today -> if count > 1 then "there are" else "there is" NextWeek -> "there will be" , " " , T.pack . show $ count , " event" , if count > 1 then "s" else "" , " " , if time == Today then "today" else "next week" ] mailBody :: Date -> SuccessiveDates -> [Event] -> [Event] -> Text mailBody currentDate nextWeek eventsToday eventsNextWeek = T.concat [ if not . null $ eventsToday then mailBodySentence Today currentDate nextWeek eventsToday else "" , if not . null $ eventsNextWeek then T.concat [ if not . null $ eventsToday then " " else "" , mailBodySentence NextWeek currentDate nextWeek eventsNextWeek ] else "" ] mailBodySentence :: Time -> Date -> SuccessiveDates -> [Event] -> Text mailBodySentence time currentDate nextWeek events = T.concat $ map (mailBodyPart time currentDate nextWeek) (attachLines events) attachLines :: [Event] -> [(Line, Event)] attachLines events = let count = length events lineKind 1 = if count == 1 then SingleLine else FirstLine lineKind line = if line == count then LastLine else MiddleLine mapFst f (x, y) = (f x, y) in map (mapFst lineKind) . zip [1..] $ events data Line = SingleLine | FirstLine | MiddleLine | LastLine deriving (Eq, Show) mailBodyPart :: Time -> Date -> SuccessiveDates -> (Line, Event) -> Text mailBodyPart time currDate nextWeek (line, event) = let nextWeekDay = dayAndMonthInRange nextWeek (date event) in T.concat [ case line of x | x `elem` [SingleLine, FirstLine] -> if time == Today then "Today, " else "Next week, " MiddleLine -> ", " LastLine -> " and " _ -> "" , name event , if time == Today then " is " else " will be " , T.pack . show $ if time == Today then age currDate event else fromMaybe 0 $ (\d -> year d - year (date event)) <$> nextWeekDay , " years old" , if time == NextWeek then fromMaybe "" $ (\d -> T.concat [" on " , getWeekDay d]) <$> nextWeekDay else "" , if line == SingleLine || line == LastLine then "." else "" ]