1{-# LANGUAGE CPP #-}23module DatePicker.Util4 ( Week,5 monthWeeks,6 addWeeks,7 horizPad,8 horizCenter,9 vertCenter,10 locale,11 format,12 parseTime,13 addSep,14 makePad,15 periodAllMonths,16 splitEvery,17 )18where1920import Data.List (intersperse)21import Data.List.NonEmpty qualified as NE22import Data.Time.Calendar qualified as Cal23import Data.Time.Calendar.Month (Month, addMonths, diffMonths)24import Data.Time.Format qualified as Fmt25import Graphics.Vty.Attributes qualified as Attr26import Graphics.Vty.Image qualified as I2728splitEvery :: Int -> [a] -> [[a]]29splitEvery _ [] = []30splitEvery n list = first : splitEvery n rest31 where32 (first, rest) = splitAt n list3334------------------------------------------------------------------------3536type Week = NE.NonEmpty Cal.Day3738monthWeeks :: Month -> Cal.DayOfWeek -> NE.NonEmpty Week39monthWeeks m dw = NE.fromList $ map NE.fromList (monthWeeks' $ Cal.periodFirstDay m)40 where41 weekOfDay :: Cal.Day -> [Cal.Day]42 weekOfDay = Cal.weekAllDays dw4344 monthWeeks' :: Cal.Day -> [[Cal.Day]]45 monthWeeks' d46 | Cal.dayPeriod d /= m = []47 | otherwise =48 let days = weekOfDay d49 nday = Cal.addDays 1 $ last days50 in filter ((==) m . Cal.dayPeriod) days : monthWeeks' nday5152periodAllMonths :: (Cal.DayPeriod p) => p -> [Month]53periodAllMonths p =54 let (fd, ld) = (Cal.periodFirstDay p, Cal.periodLastDay p)55 (fm, lm) = (Cal.dayPeriod fd :: Month, Cal.dayPeriod ld :: Month)56 in map (`addMonths` fm) [0 .. lm `diffMonths` fm]5758addWeeks :: Integer -> Cal.Day -> Cal.Day59addWeeks n = Cal.addDays (n * 7)6061------------------------------------------------------------------------6263-- TODO: Make the default locale configurable64locale :: Fmt.TimeLocale65locale = Fmt.defaultTimeLocale6667format :: (Fmt.FormatTime t) => String -> t -> String68format = Fmt.formatTime locale6970parseTime :: (MonadFail m, Fmt.ParseTime t) => Bool -> String -> String -> m t71parseTime acceptWS = Fmt.parseTimeM acceptWS locale7273addSep :: [I.Image] -> [I.Image]74addSep = intersperse (I.char Attr.defAttr ' ')7576makePad :: Int -> Int -> I.Image77makePad = I.charFill Attr.defAttr ' '7879horizPad :: Int -> Bool -> I.Image -> I.Image80horizPad w padLeft i =81 let diff = w - I.imageWidth i82 comb = if padLeft then I.horizJoin else flip I.horizJoin83 in if diff > 084 then makePad diff 1 `comb` i85 else i8687horizCenter :: Int -> I.Image -> I.Image88horizCenter w img =89 let diff = fromIntegral (w - I.imageWidth img) :: Double90 ldiff = floor (diff / 2)91 rdiff = ceiling (diff / 2)92 in if diff > 093 then makePad ldiff 1 I.<|> img I.<|> makePad rdiff 194 else img9596vertCenter :: Int -> I.Image -> I.Image97vertCenter w img =98 let diff = fromIntegral (w - I.imageHeight img) :: Double99 tdiff = floor (diff / 2)100 bdiff = ceiling (diff / 2)101 in if diff > 0102 then makePad 1 tdiff I.<-> img I.<-> makePad 1 bdiff103 else img