 USING: arrays hashtables io io.streams.string kernel math
 math.vectors math.functions math.parser namespaces sequences
 strings tuples system debugger combinators vocabs.loader
-calendar.backend structs alien.c-types math.vectors ;
+calendar.backend structs alien.c-types math.vectors
+math.ranges shuffle ;
 IN: calendar
 
 TUPLE: timestamp year month day hour minute second gmt-offset ;

        [ 1+ 3 * 5 /i + ] keep 2 * + r>
    1+ + 7 mod ;

: day-of-week ( timestamp -- n )
    >date< zeller-congruence ;

: day-of-year ( timestamp -- n )
    [
        [ timestamp-year leap-year? ] keep
        [ >date< 3array ] keep timestamp-year 3 1 3array <=>
        0 >= and 1 0 ?
    ] keep
    [ timestamp-month day-counts swap head-slice sum + ] keep
    timestamp-day + ;

: print-day ( n -- )
    number>string dup length 2 < [ bl ] when write ;

: print-month ( year month -- )
    [ month-names nth write bl number>string print ] 2keep
    [ 1 zeller-congruence ] 2keep
    days-in-month day-abbreviations2 " " join print
    over "   " <repetition> concat write
    [
        [ 1+ print-day ] keep
        1+ + 7 mod zero? [ nl ] [ bl ] if
    ] with each nl ;

: print-year ( year -- )
    12 [ 1+ print-month nl ] with each ;

: pad-00 number>string 2 CHAR: 0 pad-left write ;


: friday ( timestamp -- timestamp ) 5 day-this-week ;
: saturday ( timestamp -- timestamp ) 6 day-this-week ;

: beginning-of-day ( timestamp -- new-timestamp )
    clone dup >r 0 0 0 r>
    { set-timestamp-hour set-timestamp-minute set-timestamp-second }
    set-slots ; inline

: beginning-of-month ( timestamp -- new-timestamp )
    beginning-of-day 1 over set-timestamp-day ;

: beginning-of-week ( timestamp -- new-timestamp )
    beginning-of-day sunday ;

: beginning-of-year ( timestamp -- new-timestamp )
    beginning-of-month 1 over set-timestamp-month ;

: seconds-since-midnight ( timestamp -- x )
    dup beginning-of-day timestamp- ;

{
    { [ unix? ] [ "calendar.unix" ] }
    { [ windows? ] [ "calendar.windows" ] }
