{-# LANGUAGE ScopedTypeVariables #-}
module WeekDaze.Model.Traverse(
generateRasterCoordinates
) where
import Control.Arrow((&&&))
import qualified Data.Array.IArray
import Data.Array.IArray((!))
import qualified Data.Maybe
import qualified WeekDaze.Model.TimetableAxis as Model.TimetableAxis
import qualified WeekDaze.Model.TimetableAxisTraversal as Model.TimetableAxisTraversal
import qualified WeekDaze.Model.TimetableAxisTriple as Model.TimetableAxisTriple
import qualified WeekDaze.Model.TimetableCoordinates as Model.TimetableCoordinates
import qualified WeekDaze.Temporal.Day as Temporal.Day
import qualified WeekDaze.Temporal.Time as Temporal.Time
generateRasterCoordinates :: forall observerId timeslotId.
Model.TimetableAxisTriple.Axes
-> [observerId]
-> [timeslotId]
-> Model.TimetableCoordinates.Vector observerId timeslotId
generateRasterCoordinates timetableAxes observerIds timeslotIdRange
| Model.TimetableAxisTriple.hasWildSense timetableAxes = error $ "WeekDaze.Model.Traverse.generateRasterCoordinates:\twild sense-specification received; " ++ show timetableAxes
| otherwise = case (axisX, axisY, axisZ) of
(Model.TimetableAxis.ObserverId, Model.TimetableAxis.Day, Model.TimetableAxis.TimeslotId) -> [
(observerId, Temporal.Time.mkTime day timeslotId) |
observerId <- observerIdsBySense ! senseX,
day <- dayRangeBySense ! senseY,
timeslotId <- timeslotIdRangeBySense ! senseZ
]
(Model.TimetableAxis.ObserverId, Model.TimetableAxis.TimeslotId, Model.TimetableAxis.Day) -> [
(observerId, Temporal.Time.mkTime day timeslotId) |
observerId <- observerIdsBySense ! senseX,
timeslotId <- timeslotIdRangeBySense ! senseY,
day <- dayRangeBySense ! senseZ
]
(Model.TimetableAxis.Day, Model.TimetableAxis.ObserverId, Model.TimetableAxis.TimeslotId) -> [
(observerId, Temporal.Time.mkTime day timeslotId) |
day <- dayRangeBySense ! senseX,
observerId <- observerIdsBySense ! senseY,
timeslotId <- timeslotIdRangeBySense ! senseZ
]
(Model.TimetableAxis.Day, Model.TimetableAxis.TimeslotId, Model.TimetableAxis.ObserverId) -> [
(observerId, Temporal.Time.mkTime day timeslotId) |
day <- dayRangeBySense ! senseX,
timeslotId <- timeslotIdRangeBySense ! senseY,
observerId <- observerIdsBySense ! senseZ
]
(Model.TimetableAxis.TimeslotId, Model.TimetableAxis.ObserverId, Model.TimetableAxis.Day) -> [
(observerId, Temporal.Time.mkTime day timeslotId) |
timeslotId <- timeslotIdRangeBySense ! senseX,
observerId <- observerIdsBySense ! senseY,
day <- dayRangeBySense ! senseZ
]
(Model.TimetableAxis.TimeslotId, Model.TimetableAxis.Day, Model.TimetableAxis.ObserverId) -> [
(observerId, Temporal.Time.mkTime day timeslotId) |
timeslotId <- timeslotIdRangeBySense ! senseX,
day <- dayRangeBySense ! senseY,
observerId <- observerIdsBySense ! senseZ
]
_ -> error $ "WeekDaze.Model.Traverse.generateRasterCoordinates:\tunsupported axis-order; " ++ show timetableAxes ++ "."
where
[(senseX, axisX), (senseY, axisY), (senseZ, axisZ)] = map (Data.Maybe.fromJust . Model.TimetableAxisTraversal.getMaybeSense &&& Model.TimetableAxisTraversal.getAxis) $ Model.TimetableAxisTriple.toList timetableAxes
observerIdsBySense :: Data.Array.IArray.Array Model.TimetableAxisTraversal.Sense [observerId]
observerIdsBySense = Data.Array.IArray.array (minBound, maxBound) $ zip [minBound .. maxBound] [reverse observerIds, observerIds]
dayRangeBySense :: Data.Array.IArray.Array Model.TimetableAxisTraversal.Sense [Temporal.Day.Day]
dayRangeBySense = Data.Array.IArray.array (minBound, maxBound) $ zip [minBound .. maxBound] [reverse Temporal.Day.range, Temporal.Day.range]
timeslotIdRangeBySense :: Data.Array.IArray.Array Model.TimetableAxisTraversal.Sense [timeslotId]
timeslotIdRangeBySense = Data.Array.IArray.array (minBound, maxBound) $ zip [minBound .. maxBound] [reverse timeslotIdRange, timeslotIdRange]