{- Copyright (C) 2013-2014 Dr. Alistair Ward This file is part of WeekDaze. WeekDaze is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. WeekDaze is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with WeekDaze. If not, see . -} {- | [@AUTHOR@] Dr. Alistair Ward [@DESCRIPTION@] * This is a group of /student-bodies/, merged for the duration of a single booking in the timetable, or the bookings required for a single /course/. * In contrast to a /student-body/, the members of a /student-class/ don't have identical 'Data.Student.Profile's, but their requirements are sufficiently similar to permit them to study a /course/ together. * Temporarily merging /student-bodies/, better utilises the available /teacher/s & /location/s, by increasing the pool of /student/s available to be taught simultaneously. -} module WeekDaze.Aggregate.StudentClass( -- * Types -- ** Type-synonyms StudentClass, MnemonicSeparator, -- * Constants tag, -- * Functions merge, getSize, -- ** Translation toHtml ) where import Control.Arrow((***)) import qualified Data.Foldable import qualified Data.List import qualified Data.Set import qualified Text.XHtml.Strict import Text.XHtml.Strict((<<)) import qualified WeekDaze.Aggregate.StudentBody as Aggregate.StudentBody import qualified WeekDaze.Size as Size import qualified WeekDaze.Text.XHTML as Text.XHTML -- | Used to qualify XML & CSS. tag :: String tag = "studentClass" {- | Whilst a /student-body/ represents a group with identical requirements, when one or more /student-bodies/ have similar requirements for a single /subject/, they can be temporarily merged to form a /class/. -} type StudentClass = Data.Set.Set Aggregate.StudentBody.StudentBody -- | Used to separate /mnemonic/s, when merging a /student-class/ into a /student-body/. type MnemonicSeparator = String {- | * Remove the boundaries separating the groups of /student/s within a class, to form a single /student-body/. * The mnemonics for the constituent /student-bodies/ are concatenated to form a composite mnemonic for the new /student-body/. * CAVEAT: any /student-Ids/ common to more than one /student-body/ within the /student-class/, will be merged. * CAVEAT: a null set, will result in a null mnemonic, which will be rejected by 'Aggregate.StudentBody.mkStudentBody'. -} merge :: MnemonicSeparator -> StudentClass -> Aggregate.StudentBody.StudentBody merge mnemonicSeparator = uncurry Aggregate.StudentBody.mkStudentBody . ( Data.List.intercalate mnemonicSeparator *** Data.Set.unions {-members-} ) . unzip . map Aggregate.StudentBody.toPair . Data.Set.toList {- | * Counts the number of /student/s in a class. * CAVEAT: assumes that the /student-bodies/, from which the class is composed, are distinct. -} getSize :: Data.Foldable.Foldable foldable => foldable Aggregate.StudentBody.StudentBody -> Size.NStudents getSize = Data.Foldable.foldr ((+) . Aggregate.StudentBody.getSize) 0 -- | Convert to XHTML. toHtml :: StudentClass -> Text.XHtml.Strict.Html toHtml = (Text.XHTML.mkXHTMLSpan tag <<) . Data.List.intersperse (Text.XHtml.Strict.stringToHtml ", ") . map Text.XHtml.Strict.toHtml . Data.Set.toList