#!/usr/local/bin/wishx -f

proc Set        {name value}    { global cfg;       set cfg($name) $value}

#---------------------------------------------------------------------------------

Set norm_font           *-courier-medium-r-*-120-*
Set normb_font          *-courier-bold-r-*-120-*
Set fixed_font          -misc-fixed-medium-r-normal--10-70-*

Set CalDir              Calendar
Set curday              ""
Set curmon              ""
Set curyear             ""
Set actDay              [exec date "+%d"]
Set actMonth            ""
Set actYear             ""

option add *Font        $cfg(norm_font)

set CalDayNames {Sun Mon Tue Wed Thu Fri Sat}

#---------------------------------------------------------------------------------

proc Init {} {
    global cfg

    cd
    if {![file isdirectory $cfg(CalDir)]} {
        puts "making directory $cfg(CalDir)"
        catch {exec mkdir $cfg(CalDir)} rsp
    }
}

#---------------------------------------------------------------------------------


proc CalGetMonth {date} {
    set fp [open "|cal $date" "r"]
    set res [list                        \
            [eval "list [gets $fp]"    ]        \
            [eval "list [gets $fp]"    ]        \
            [list                    \
            [eval "list [gets $fp]"    ]    \
            [eval "list [gets $fp]"    ]    \
            [eval "list [gets $fp]"    ]    \
            [eval "list [gets $fp]"    ]    \
            [eval "list [gets $fp]"    ]    \
            [eval "list [gets $fp]"    ]    \
            ]                    \
        ]
    close $fp
    return $res
}

#---------------------------------------------------------------------------------

proc yearOverview {year} {
    global cfg

    if {[winfo exists .overview$year]} {
        return
    }

    toplevel .overview$year -bg grey90 
    wm title .overview$year "$year Overview"
    text .overview$year.text -font $cfg(fixed_font) -bg #eafbff -fg black \
        -width 68 -height 38 -relief flat -bd 0
    pack .overview$year.text -padx 0 -expand 1 -fill both -anchor n

    set fd [open "|cal $year" "r"]
    while { ! [eof $fd] } {
        set line [read  $fd]
        .overview$year.text insert end $line
    }
    button .overview$year.close -text "Close" -command "destroy .overview$year"
    pack .overview$year.close -side bottom -expand 1 -fill x

}

#---------------------------------------------------------------------------------

proc Calendar {date} {
    global CalDayNames cfg

    set month [CalGetMonth $date]
    set name [lindex [lindex $month 0] 0]
    set year [lindex [lindex $month 0] 1]
    set weeks [lindex $month 2]

    set cfg(actMonth) [expr [lindex $date 0]]
    set cfg(actYear) $year

    if {![winfo exists .cmds]} {
        frame    ".cmds" -bg grey80
        pack append . ".cmds" top 
    
        button    ".cmds.next" -text ">" -command "Calendar [CalNext $date]" -bg grey80 \
            -fg blue
        pack append ".cmds" ".cmds.next" right
    
        label   ".cmds.title" -width 20 -bg #fffbda -fg black -text "$name $year" \
            -font $cfg(normb_font) -relief ridge
        pack append .cmds .cmds.title {right expand}

        button    ".cmds.prev" -text "<" -command "Calendar [CalPrev $date]" -bg grey80 \
            -fg blue
        pack append ".cmds" ".cmds.prev" right

        button .year -text "Year" -command "yearOverview $year"
        pack .year -side bottom -expand 1 -fill x
    } else {
        .cmds.title configure -text "$name $year"
        .cmds.next configure -command "Calendar [CalNext $date]"
        .cmds.prev configure -command "Calendar [CalPrev $date]"
        .year configure -command "yearOverview $year"
    }

    if {![winfo exists .days]} {
        frame    ".days" -bg grey80
        pack append . ".days" top
    
        set n 0
        foreach day [lindex $month 1] {
            set dname [lindex $CalDayNames $n]
            button ".days.$n" -text "$day" -width 3 -text $dname -relief ridge -state disabled \
                -disabledforeground black -bg grey80
            pack append ".days" ".days.$n" left
            set n [expr "$n + 1"]
        }
    }

    if {[winfo exists .wkdays]} {
        destroy .wkdays
    }

    set orientation "ne"
    regexp "..." $name nam
    set n 0
    set cfg(Weeks) $weeks

    frame .wkdays -bg grey80

    foreach week "$weeks" {
        frame    .wkdays.week$nam$n
        pack append .wkdays .wkdays.week$nam$n "top frame $orientation"
    
        set orientation "sw"

        set dow 0
        foreach day "$week" {
            set filename $cfg(CalDir)/$year/$day$nam$year
            if {[file exists $filename]} {
                set hlc blue
                set tfont $cfg(normb_font)
            } else {
                set hlc black
                set tfont $cfg(norm_font)
            }
            if {$cfg(curday) == $day && $cfg(curmon) == $cfg(actMonth)} {
                set bgc yellow
            } else {
                set bgc grey80
            }
            button ".wkdays.week$nam$n.$day" -bg $bgc -fg $hlc -text "$day" -width 3 -font $tfont \
                -command "CalEdit .wkdays.week$nam$n.$day $year $nam $day [lindex $CalDayNames $dow]"
            pack append ".wkdays.week$nam$n" ".wkdays.week$nam$n.$day" left
            incr dow
        }

        incr n
    }
    pack .wkdays -side top
}

#---------------------------------------------------------------------------------

proc CalNext {date} {
    set month [lindex $date 0]
    set year [lindex $date 1]
    incr month
    if { $month == 13 } {
        set month 1
        incr year
    }
    return "\{$month $year\}"
}

#---------------------------------------------------------------------------------

proc CalPrev {date} {
    set month [lindex $date 0]
    set year [lindex $date 1]
    set  month [expr $month - 1]
    if { $month == 0 } {
        set month 12
        set  year [expr $year - 1]
    }
    return "\{$month $year\}"
}

#---------------------------------------------------------------------------------

proc deleteFile {filename txt w} {
    global cfg

    if {[file exists $filename]} {
        catch {exec /bin/rm $filename}
    }
    $txt delete 1.0 end
    if {[winfo exists $w]} {
        $w configure -fg black
        $w configure -font $cfg(norm_font)
    }
}

#---------------------------------------------------------------------------------

proc setButt {w} {
    global cfg

    if {[winfo exists $w]} {
        $w configure -fg blue 
        $w configure -font $cfg(normb_font) 
    }
}

#---------------------------------------------------------------------------------

proc CalEdit {butt year nam day dname} {
    global cfg

    set fnum $day$nam$year

    if {[winfo exists .file$fnum]} {
        return
    }
    toplevel ".file$fnum" -bg grey80
    wm title  ".file$fnum" "$dname $day $nam $year"

    if {![file isdirectory $cfg(CalDir)/$year]} {
        catch {exec mkdir $cfg(CalDir)/$year}
    }

    set id 0
    set filename $cfg(CalDir)/$year/$day$nam$year

    frame .file$fnum.f$id -bg grey80
    pack append .file$fnum .file$fnum.f$id top

    set w .file$fnum.f$id

    label  "$w.filename" -text "Daily Events from $filename" -bg #eafbff -fg black \
        -relief ridge
    text "$w.text" -relief sunken -height 10 -borderwidth 1 -width 60 \
        -selectbackground black -selectforeground yellow -bg #fffbda -fg black
    if {[file exists $filename] } {
        set fd [open $filename "r"]
        while { ! [eof $fd] } {
            set line [gets $fd]
            $w.text insert end "$line\n"
        }
        close $fd
    }
    pack $w.filename -side top 
    pack $w.text -side top -expand 1 -fill both

    frame .file$fnum.buttons -bg grey80

    button .file$fnum.buttons.save -width 10 -text "Save" -bg grey80 -fg black -command "\
        set fd \[open $filename w\] ;        \
        puts \$fd \[ $w.text get 0.0 end \] ;  \
        close \$fd ; \
        setButt $butt"

    button .file$fnum.buttons.delete -width 10 -text "Delete" \
        -command "deleteFile $filename $w.text $butt" -bg grey80 -fg black
    button .file$fnum.buttons.close -width 10 -text "Close" -command "destroy .file$fnum" \
        -bg grey80 -fg black
    pack .file$fnum.buttons.save .file$fnum.buttons.delete .file$fnum.buttons.close \
        -fill x -side left -expand 1
    pack .file$fnum.buttons -side bottom -fill x

    focus $w.text
}


#---------------------------------------------------------------------------------

proc CalGetToday {} {
    set fd [open {|date "+%m %Y"} "r"]
    set res [gets $fd]
    close $fd
    return $res
}


#---------------------------------------------------------------------------------

proc setCurDate {} {
    global cfg

    set cfg(curday) [exec date "+%d"]
    set cfg(curmon) [expr [exec date "+%m"]]
    set cfg(curyear) [exec date "+%Y"]

    if {$cfg(actMonth) == $cfg(curmon) && $cfg(actYear) == $cfg(curyear)} {
        if {$cfg(actDay) != $cfg(curday)} {
            Calendar [CalGetToday]
            set cfg(actDay) $cfg(curday)
        }
    } 
#HAVE_ALARM_SUPPORT
    alarm 3600
#ELSE
#NO_ALARM_SUPPORT
#	after 3600 setCurDate
}

#---------------------------------------------------------------------------------

Init
wm title . "Organizer"
. configure -bg grey80
setCurDate
Calendar [CalGetToday]

#HAVE_ALARM_SUPPORT
signal trap {ALRM} {setCurDate}
set id [alarm 3600]
#END_ALARM


#---------------------------------------------------------------------------------

