FuzzyClock

General Notes

MiHa 2015-02-24: A fuzzy clock shows approximate time only, that is, with a precision of a few minutes.

For example, for any time between 03:08 and 03:12 you would get a string like "Ten minutes past three o'clock".

There are already some programs that do that, examples are:

My fuzzy clock doesn't output a string, it highlights fixed panels with a list of words on them,
like turning on lamps inside panels which have a cover, labeled with one of those words.

Some inspiration came from the following programs and pages here :

Other programs that are doing something with time:

Designer's notes

  • I use 3*8 rectangles as "panels" on a canvas
  • Each such area has a word (like "ten", "minutes", "before"),
    and tags for adressing.
  • The current time gets read with "clock format clock seconds",
  • this "raw time" gets displayed at the top of the window (for testing),
  • and then I use a table-lookup to figure out which panels to light up.
  • This table has an entry for each minute of the hour, with a list of tags.
  • (When implemening this in hardware, I would instead use 32bit-values,
    where each bit represents one of the panels)
  • Actually, this whole thing works like one of those decoders for a 7-segment-display ,
    just with more "segments", and better configurable.
  • The clock is a 12-hour design , but instead of AM/PM, I use morning/evening,
    where "morning" behaves like AM, but "evening" only starts at 18:00.
  • With "It is"/"It gets"/"It was", my time is fuzzy/precise within two minutes,
  • so I limited the update-frequency to once every 10 seconds..
  • My choice of words went towards "five" and "ten",
    which can in german both be lit to be nicely combined to get the equivalent of "fifteen".
    For a proper english fuzzy clock, you might want "quarter" as a separate word.
  • In hindsight, for designing and changing the layout, it is easier
    to have an addressing scheme for the panels like for cells in a spreadsheet.
  • Some procedure-names were choosen to be short for easy testing/calling from console.

Notes about working with tcl

This section has been moved to my personal page here.


PYK 2019-02-11: The design of this program, as well as the visual style of this source code, offers many lessons in opportunities for improvement. I have begun a series of changes which should ultimately reduce the code size by 50 to 75%. I hope the original author sees this as a positive thing intended to help him and others improve their Tcl chops. We all are beginners in one thing or another.

There will be a little dust as the old architecture gives way to the new. Hopefully anyone else wishing to contribute will follow riff on the "stubs" as they are added. Inevitably there will also be new bugs. My apologies in advance for those. Reports are appreciated.

Notes on changes: Whitespace can be distracting. Too much whitespace between clumps of characters stilts the reading of the code (yes, I appreciate the irony). Long lines can be distracting. For this reason, inlline comments are often discouraged. Backslash line continuations can often be avoided with judicial use of syntactic elements. The human eye scans better vertically than horizontally, so it often makes sense to make content more vertical than horizontal.

For a rationale on when to use braces versus quotes, see Tcl Minimal Escaping Style.

Program


# FuzzyClock89.tcl - Mike Hase - 2015-02-24 / 2015-06-19
# https://wiki.tcl-lang.org/41162

package require Tk
set Prog(Title)    FuzzyClock
set Prog(Version)  v1.30
set Prog(Date)     2019-02-10
set Prog(Author)   {Mike Hase}
set Prog(Contact)  [email protected]
set Prog(HomePage) https://wiki.tcl-lang.org/41162
set Prog(Options)  {}
set Prog(About)    {FuzzyClock: a textual clock that shows
approximate time (rounded to 5 minutes)
by highlighting panels with fixed text.
In various layouts (german and international),
including ship's clock and "Glasenuhr".
}

set scX 12

### Colortable: (ToDo)

set Co(bg) grey
#set bg white
set bg grey
set ol black

set hi1 cyan
set hi2 yellow

set tx1 blue
set tx2 white

set hiC $hi1
set txC $tx1


### Display:

proc makeText {w tag name rectCoords} {
        # Create a panel with some text inside (e.g. "one", or "o'clock").
        # The name of the panel is the same as the text.
        # The panel and the text are assigned tags, that will later be used
        # to turn that panel+text on or off (i.e. change their colors).

        global scX
        set id1 [$w create rect $rectCoords -tag $tag -fill $::bg -outline $::ol]

        foreach {x y} $rectCoords break
        incr x
        incr y
        set id2 [$w create text $x $y -tag t$tag -anchor w -text $name]
        $w addtag time withtag $tag
        $w addtag txt withtag t$tag

        # puts "$id1 $id2 : $x $y $tag $name"
        $w scale $id1 0 0 $scX 15
        $w scale $id2 0 0 $scX 15
}


proc turnOff tag {
        foreach id [ .c find withtag time] {.c itemconfigure $id -fill $::bg}
        foreach id [ .c find withtag txt ] {.c itemconfigure $id -fill black}
}


proc turnOn tag {
        foreach id [ .c find withtag $tag ] {.c itemconfigure $id -fill $::hiC}
        foreach id [ .c find withtag t$tag ] {.c itemconfigure $id -fill $::txC}
}

proc turnOnHour hour {
        set hour [expr {$hour % 12}]
        set tag t_$hour
        foreach id [ .c find withtag $tag ] {.c itemconfigure $id -fill $::hiC}
}


### Update display / highlight panels:

proc upd_fc {} {
        # update for fuzzyclock


        # Find out which hour to show (e.g. 09:45 --> "quarter to ten o'clock" )
        #
        # In the minute-table, look at the entry for the current minute,
        # from there get the list of tags,
        # and turn on all panels listed.

        #-sTab
        global hh mm am mTab

        set nexthour $hh

        #puts "$hh / t_$hh t_$am"

        set i 0
        #puts "$mm : mTab($mm) -->"
        foreach t $mTab([format %02d $mm]) {
                #incr i; puts " $i. $t"; turnOn $t
                # show next hour
                if {$t eq {hH}} {
                        incr nexthour;
                }
        }
        #puts [list {nearest hour} $hh]

        turnOnHour $nexthour
        foreach t $mTab($mm) {
                #incr i; puts " $i. $t"
                turnOn $t
        }
        turnOn t_C
        turnOn t_$am
}


proc upd_sc {} {
        #update for shipclock

        # Instead of hours, we have "watches" and "glasses",
        # and one glass runs 30 minutes.

        #-mTab
        global cs td hh mm am wd sTab

        ### Demo/Test for ship's bell:
        #turnOn t_gI; turnOn t_HN; turnOn t_g2

        set shiptags [list t_gI]

        set ww [watch $hh $mm]
        set W $sTab($ww)
        #puts "ww $ww : $W ==>"
        foreach t $W {
                #incr i; puts " $i. $t"
                turnOn $t
        }

        set gg [bells $hh $mm]
        puts "Ship: $hh h $mm m => watch $ww, $gg glasen/bells"

        lappend shiptags t_g$gg
        #puts "$cs> $hh $hh : $mm - $wd"

        # Special significance on ships: sunday and noon
        if {$::wd == 0} {lappend shiptags t_Su}
        if {$::hh==12 && $::mm== 0} {lappend shiptags t_HN}

        if {$mm>=30} {incr mm -30}

        set gm 0
        # find nearest matching minute-entry in sTab:
        for {set m 0} {$m<30} {incr m} {
                if {[info exists sTab($m)]} {set gm $m}
                #puts ".. $m -> $gm"
                if {$m>=$mm3} {break}
        }
        #puts "!! $mm $m -> <<$sTab($gm)>> $gm"
        lappend shiptags $sTab($gm)

        puts "$hh:$mm $mm3 $gm ---> $shiptags "
        set i 0

        foreach t $shiptags {
                #incr i; puts "Ship: $i. $t"
                turnOn $t
        }
}


proc upd {} {
        # Update the text showing the time in the window-bar, and the panels.

        global cs td hh mm am wd

        #wm title . $td
        #wm title . "$td / $hh:$mm $am"
        wm title . "($::fc) $td / $hh:$mm $am"

        # use only one of the tables: mTab sTab
        if {$::fc in [list G1 G2 SG1 SG2 SB1 SB2]} {
                # Multi-IF
                upd_sc
        } else {
                upd_fc
        }
}


proc u {} {
        # do everything related to display-update

        turnOff time
        turnOff txt
        upd

        if {$::hiC==$::hi1} {
                set ::hiC yellow
        } else {
                # change colors / ToDo: colortable
                set ::hiC cyan
        }
}


### Test+Debug:


proc ? {} help
proc help {} {
        puts "argv0 : $::argv0"
        puts "argv : $::argv"
        puts "tcl/tk: $::tcl_patchLevel / $::tk_patchLevel"
        puts "t0,t1,h,m,x,y:change time, u:update, run,stop, p,p1,p2,pp:pos, bg:color, e:exit"
}


# Note: testing might be easier by changing the system-clock (forward only!).
proc t {} t0
#proc t_ {} {set ::cs [clock scan {2015-03-13 23:55:00} -format {%Y-%m-%d %H:%M:%S}]}
proc t1 {} {set ::cs [clock scan {00:16:00} -format {%H:%M:%S}]; timecodes}
proc t2 {} {set ::cs [clock scan {09:55:00} -format {%H:%M:%S}]; timecodes}
proc x {} {set ::mm 10}
proc y {} {set ::ii 12; set ::mm 02}
proc h {} {incr ::ii}
proc m {} {incr ::mm}


# screen+color / find window for active console:
proc bg {{c HotPink}} {
        .c configure -background $c;
        #wm deiconify .
}


# screen+position


proc p {} {puts "wm geom . : [wm geom .]"}


proc pp {} {
        wm geom . +740+20; wm deiconify .
        p
}


proc p1 {} {
        wm geom . +1+1; wm deiconify .
        p
}


proc p2 {} {
        wm geom . +740+1; wm deiconify .
        p
}


proc e {} exit


### Misc / Utility:


proc s2i s {
        # string-to-int / convert values from [clock seconds] to integer
        ##puts >>>$s<<<
        if {[scan $s %dll i] <= 0} {
                error [list {not an integer} $s]
        }
        return $i
}


# return first char of string
proc c1 s {set c [string range $s 0 0]}


# return first 2 chars
proc c2 s {set c [string range $s 0 1]}

# return last char
proc c9 s {set c [string range $s end end]}

# tcl::mathop::[in] comes with tcl 8.5, see [TIP 201].
# For users of earlier versions:

# Multi-IF
#proc in {list el} {expr [lsearch -exact $list $el] >= 0}

### Ship's bell:


proc b1 {} bell


proc b2 {} {
        bell
        after 250
        bell
        after 400
}


proc ringbell {{b 1}} {
        puts "RingBell>>>$b<<< mm=$::mm sound=$::sound\n"
        if {$::sound == 0} return

        if {$::sound == 1} {
                if {$::mm eq {00}} bell
                return
        }

        # sound==2 : Ship's bell:
        while {$b>=2} {b2; incr b -2}
        while {$b>=1} {b1; incr b -1}
}


proc watch {hh mm} {
        # determine watch for a given hour
        #puts "watch>>>$hh:$mm>> $ww"
        return w[expr {$hh / 4}]
}


proc bells {hh mm} {
        # determine bells for a given time
        set bb [expr {max( 8, (($hh % 4) * 2) + ($mm >= 30))}]
        #puts "bells>>>$hh:$mm>>$bb"
        return $bb
}


### Time:


# Set cs to current time
proc t0 {} {
        # To use some fixed time (for testing) use proc t1, t2 etc.
        set ::cs [clock seconds]
        timecodes
}


# Set all variables that depend on the "current" time from cs
proc timecodes {} {
        global cs td hh mm am wd mTab

        set td [clock format $cs -format "%H:%M:%S - %l:%M %p" ]
        set hh [s2i [clock format $cs -format %H]]
        set mm [s2i [clock format $cs -format %M]]
        set ss [s2i [clock format $cs -format %S]]
        set am [clock format $cs -format %p]

        # 0=Sunday
        set wd [clock format $cs -format %w]

        # no "PM" before 18:00
        if {$hh<18} {set am _}

        puts "$hh:$mm:$ss -> $hh:$mm $am"
        if {$mm % 30 == 0 && $ss < 1} {ringbell [bells $hh $mm]}
}


### Time/Repeat/Wait:


proc every {ms body} {
        try $body
        after $ms [list after idle [namespace code [info level 0]]]
}


proc stop {} {foreach id [after info] {after cancel $id}}


proc run {} run2
proc run2 {} {$::time; timecodes; u; sync2}


proc sync2 {} {
        # adjust time for re-scheduling, to get closer to a time
        # with the seconds at a multiple of 10.

        #set ::cs [clock seconds]
        set s0 [expr $::cs % 10]

        if {$s0 == 0} {
                after 10000 run2;
                #puts "sync2: $::td $::cs $s0 #==ok=="
        } else {
                after 9000 run2;
                #puts "sync2: $::td $::cs $s0 #++adjust++"
        }
}

#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+

### Menu:


proc m+ {head name {cmd {}}} {
#: Menu-creator "m+" by R.Suchenwirth and DKF, 2006-08-24, see https://wiki.tcl-lang.org/16327
        # Uses the undocumented and unsupported feature ::tk::UnderlineAmpersand
        if {![winfo exists .m.m$head]} {
                foreach {l u} [::tk::UnderlineAmpersand $head] break
                .m add cascade -label $l -underline $u -menu [menu .m.m$head -tearoff 0]
        }
        if {[regexp ^-+$ $name]} {
                .m.m$head add separator
        } else {
                foreach {l u} [::tk::UnderlineAmpersand $name] break
                .m.m$head add command -label $l -underline $u -comm $cmd
        }
}

#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+


### GUI:



proc menuOnOff {} {
        if {[winfo exists .m]} {
                destroy .m
        } else {
                initMenu
        }
}


proc initMenu {} {
        # Define menu

        . configure -menu [menu .m]
        # m+ &File &Open {Dummy Open}
        # m+ &File &Save {Dummy Save}
        # m+ &File -----
        m+ &File &Exit exit

        # V,H,Q: uses the terms "Viertel", "Halb"/"Half", "Quarter" in telling the time
        # "-": 5-minute precison only, "...": Todo
        # ":": uses "it was"/"it is"/it gets" for increased precision

        m+ &Fuzzy {&German: 8x3 H}       {start DE1}
        m+ &Fuzzy {DE&2 - 8x3 (common)}  {start DE2}
        m+ &Fuzzy {DE&3 : 8x3 V}         {start DE3}
        m+ &Fuzzy {DE&4 : 8x3 V}         {start DE4}
        m+ &Fuzzy {DE&5 - 5x5}           {start DE5}
        m+ &Fuzzy {DE&6 - 6x4}           {start DE6}
        m+ &Fuzzy {DE&7 - 4x6}           {start DE7}
        m+ &Fuzzy {DE&8 : 6x5 24h}       {start DE8}
        m+ &Fuzzy -----
        m+ &Fuzzy {&Glasenuhr - 8x3}     {start SG1}
        m+ &Fuzzy {G&2 - 3x8 wide}       {start SG2}
        m+ &Fuzzy -----
        m+ &Fuzzy {&International - 8x3} {start I1}
        m+ &Fuzzy {I&2 - 8x3 Q}          {start I2}
        m+ &Fuzzy {I&3...6x5 24h}        {start I3}
        m+ &Fuzzy -----
        m+ &Fuzzy {&Ship's Bell - 8x3}   {start SB1}
        m+ &Fuzzy {SB&2 - 3x8 wide}      {start SB2}

        m+ &Clock {&Stop}                stop
        m+ &Clock {T&0 - Current time}   t0
        m+ &Clock T&1                    t1
        m+ &Clock T&2                    t2
        m+ &Clock &Update                u

        m+ &Help &About        Help0
        m+ &Help &Help         Help1
        m+ &Help -----
        m+ &Help &Debug      {console show}
        m+ &Help {&Menu off} {destroy .m}
}


proc initKeys {} {
        # Define bindings for hotkeys

        bind all <Key-F1>     Help1
        bind all <Key-F2>   {console show}
        bind all <Key-F3>     menuOnOff
        bind all <Key-F4>     exit
        bind all <Escape>   exit

        bind all <Key-F5>   {start DE2}
        bind all <Key-F6>   {start DE7}
        bind all <Key-F7>   {start I1}
        bind all <Key-F8>   {start I2}

        bind all <Key-F9>   {start SG1}
        bind all <Key-F10>  {start SB2}
}

#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+

proc start x {
# Show and run a fresh fuzzyclock,
# after stopping any old ones.

        set ::fc $x

        stop

        # start_DE1 .c
        start_$x .c

        update

        help

        # t0
        $::time

        after 250
        u

        run2
}

#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+

proc Dummy txt {
        #: Alert: "Function X not implemented yet"
        bell
        tk_messageBox -icon warning -title Demo \
                -message "Function '$txt' not implemented yet."
}


proc Help0 {} {
        #: Short info about the program / using tk_messageBox
        global Prog
        set txt "$Prog(Title) $Prog(Version) - "
        append txt "$Prog(Date)\nby $Prog(Author) - $Prog(Contact)\n\n$Prog(About)"
        tk_messageBox -icon info -message $txt -title "About $Prog(Title) $Prog(Version)"
}


# from: Spider Solitaire - Help
proc Help1 {} {
        global Prog
        set w .help
        if {[winfo exists $w]} {
                wm deiconify $w
                raise $w
                focus $w
                return;
        }
        toplevel $w
        wm title $w "$Prog(Title) - Help"

        frame $w.f
        text $w.f.t -wrap word
        scrollbar $w.f.sb
        $w.f.t configure -yscrollcommand [list $w.f.sb set]
        $w.f.sb configure -command [list $w.f.t yview]

        $w.f.t tag configure h1 -font {{} 18 bold } -justify center -foreground red
        $w.f.t tag configure h2 -font {{} 8 italic} -justify center
        $w.f.t tag configure h3 -font {{} 12 bold } -foreground red
        $w.f.t tag configure h4 -font {{} 10 bold } -foreground blue

        $w.f.t insert end "$Prog(Title)\n" h1
        $w.f.t insert end "Version $Prog(Version) - $Prog(Date)\n\n" h2

        $w.f.t insert end "$Prog(Title) is a textual digital clock that shows approximate time\n"
        $w.f.t insert end "(rounded to 5 minutes) by highlighting panels with fixed text.\n\n"
        $w.f.t insert end "The program provides various layouts (german and international),\n"
        $w.f.t insert end "including ship's clock and \"Glasenuhr\".\n\n"

        $w.f.t insert end "Fuzzy LAYOUTS:\n" h3
        $w.f.t insert end "German layouts:\n" h4
        $w.f.t insert end "* DE1 - 8x3, 12hour clock using 'halb' (='half').\n"
        $w.f.t insert end "* DE2 - 8x3\n"
        $w.f.t insert end "* DE3 - 8x3, using 'Viertel' (='Quarter').\n"
        $w.f.t insert end "* DE4 - 8x3, using 'Viertel' (='Quarter').\n"
        $w.f.t insert end "* DE5 - 5x5 \n"
        $w.f.t insert end "* DE6 - 6x4 \n"
        $w.f.t insert end "* DE7 - 4x6 \n"
        $w.f.t insert end "* DE8 - 6x5, 24h-clock.\n\n"

        $w.f.t insert end "International layouts:\n" h4
        $w.f.t insert end "* I1 - 8x3, 12hour AM/PM.\n"
        $w.f.t insert end "* I2 - 8x3, using 'quarter before/past'.\n"
        $w.f.t insert end "* I3 - 6x5, 24h-clock.\n\n"

        $w.f.t insert end "Ship's bell and Glasenuhr:\n" h4
        $w.f.t insert end "* SB1 - Ship's bell, 8x3.\n"
        $w.f.t insert end "* SB2 - Ship's bell, 3x8 wide layout.\n"
        $w.f.t insert end "* SG1 - Glasenuhr, 8x3.\n"
        $w.f.t insert end "* SG2 - Glasenuhr, 3x8 wide layout.\n\n"

        $w.f.t insert end "CLOCK:\n" h3
        $w.f.t insert end "This is useful for testing, comparing layouts, and doing screenshots.\n"
        $w.f.t insert end "* Stop  : stop the updating of the clock.\n"
        $w.f.t insert end "          To restart it, (re-)select any layout.\n"
        $w.f.t insert end "* T0    : set the clock's time to the current time.\n"
        $w.f.t insert end "* T1    : set to fixed time #1 (see 'proc t1')\n"
        $w.f.t insert end "* T2    : set to fixed time #2\n"
        $w.f.t insert end "* Update: update the display after changing the time.\n\n"

        $w.f.t insert end "HOTKEYS:\n" h3
        $w.f.t insert end "* F1 - Show this help.\n* F2 - Activate Debug/Console.\n"
        $w.f.t insert end "* F3 - Switch menu on/off.\n"
        $w.f.t insert end "* F4, Esc - Exit program.\n"
        $w.f.t insert end "* F5,F6  - Select german layouts.\n"
        $w.f.t insert end "* F7,F8  - Select international layouts.\n"
        $w.f.t insert end "* F9,F10 - Select ship's bell and Glasenuhr.\n\n"

        $w.f.t insert end "DEBUG:\n" h3
        $w.f.t insert end "  The console offers access to the program's internals and variables.\n\n"
        $w.f.t insert end "Commands:\n" h4
        $w.f.t insert end "  ?: show console-help, e: Exit program.\n\n"
        $w.f.t insert end "  M  : create new menu.\n"
        $w.f.t insert end "  bg : set background-color (eg. 'bg red').\n"
        $w.f.t insert end "  p  : show size and position of the program-window.\n"
        $w.f.t insert end "  p1,p2,pp : set program-window to some position (see 'proc p1' etc.).\n\n"

        $w.f.t insert end "  stop, run: stop updating the clock / continue display-updates.\n"
        $w.f.t insert end "  t0, t1,t2: set clock to current time / predefined times (see 'proc t1' etc.).\n"
        $w.f.t insert end "  h,m,x,y: change clock.\n"
        $w.f.t insert end "  u: update the clock-display.\n\n"

        $w.f.t insert end "You can enter any tcl-command in the console, for example:\n"
        $w.f.t insert end "% info proc\n"
        $w.f.t insert end "% info var\n"
        $w.f.t insert end "% winfo geom .\n"
        $w.f.t insert end "% puts \$cs\n"
        $w.f.t insert end "% parray mTab\n"
        $w.f.t insert end "% set time t2\n"
        $w.f.t insert end "\n"

        $w.f.t insert end "CREDITS:\n" h3
        $w.f.t insert end "  Written by $Prog(Author) ($Prog(Contact)),\n  source at $Prog(HomePage).\n"


        $w.f.t configure -state disabled
        pack $w.f -side top -expand 1 -fill both
        pack $w.f.t -side left -expand 1 -fill both
        pack $w.f.sb -side right -fill y

        frame $w.f2
        pack $w.f2 -side top -pady 8

        button $w.f2.b -text Close -command [list wm withdraw $w] -width 9
        pack $w.f2.b

        wm protocol $w WM_DELETE_WINDOW [list wm withdraw $w]
        focus $w.f.t
};# Help1


proc _Help1 {} {Dummy Help1}


#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+


### Positions, spreadsheet-style: # see also scale

## 8x3: 8 rows * 3 cols / "tall":

set a1  { 1  1   8  3}
set b1  { 8  1  14  3}
set c1  {14  1  21  3}

set a2  { 1  3   8  5}
set b2  { 8  3  14  5}
set c2  {14  3  21  5}

set a3  { 1  5   8  7}
set b3  { 8  5  14  7}
set c3  {14  5  21  7}

set a4  { 1  7   8  9}
set b4  { 8  7  14  9}
set c4  {14  7  21  9}

set a5  { 1  9   8 11}
set b5  { 8  9  14 11}
set c5  {14  9  21 11}

set a6  { 1 11   8 13}
set b6  { 8 11  14 13}
set c6  {14 11  21 13}

set a7  { 1 13   8 15}
set b7  { 8 13  14 15}
set c7  {14 13  21 15}

set a8  { 1 15   8 17}
set b8  { 8 15  14 17}
set c8  {14 15  21 17}


## 3x8: 3 rows * 8 cols / "wide":

set x1  { 1  1   8  3}
set x2  { 8  1  16  3}
set x3  {16  1  24  3}
set x4  {24  1  32  3}
set x5  {32  1  40  3}
set x6  {40  1  48  3}
set x7  {48  1  56  3}
set x8  {56  1  64  3}

set y1  { 1  3   8  5}
set y2  { 8  3  16  5}
set y3  {16  3  24  5}
set y4  {24  3  32  5}
set y5  {32  3  40  5}
set y6  {40  3  48  5}
set y7  {48  3  56  5}
set y8  {56  3  64  5}

set z1  { 1  5   8  7}
set z2  { 8  5  16  7}
set z3  {16  5  24  7}
set z4  {24  5  32  7}
set z5  {32  5  40  7}
set z6  {40  5  48  7}
set z7  {48  5  56  7}
set z8  {56  5  64  7}


## 6x4: 4 rows * 6 cols / "wide":

set d1  { 1  1   8  3}
set d2  { 8  1  16  3}
set d3  {16  1  24  3}
set d4  {24  1  32  3}
set d5  {32  1  40  3}
set d6  {40  1  48  3}

set e1  { 1  3   8  5}
set e2  { 8  3  16  5}
set e3  {16  3  24  5}
set e4  {24  3  32  5}
set e5  {32  3  40  5}
set e6  {40  3  48  5}

set f1  { 1  5   8  7}
set f2  { 8  5  16  7}
set f3  {16  5  24  7}
set f4  {24  5  32  7}
set f5  {32  5  40  7}
set f6  {40  5  48  7}

set g1  { 1  7   8  9}
set g2  { 8  7  16  9}
set g3  {16  7  24  9}
set g4  {24  7  32  9}
set g5  {32  7  40  9}
set g6  {40  7  48  9}


## 4x6: 6 rows * 4 cols / "tall":

set m1  { 1  1   8  3}
set m2  { 8  1  16  3}
set m3  {16  1  24  3}
set m4  {24  1  32  3}

set n1  { 1  3   8  5}
set n2  { 8  3  16  5}
set n3  {16  3  24  5}
set n4  {24  3  32  5}

set o1  { 1  5   8  7}
set o2  { 8  5  16  7}
set o3  {16  5  24  7}
set o4  {24  5  32  7}

set p1  { 1  7   8  9}
set p2  { 8  7  16  9}
set p3  {16  7  24  9}
set p4  {24  7  32  9}

set q1  { 1  9   8 11}
set q2  { 8  9  16 11}
set q3  {16  9  24 11}
set q4  {24  9  32 11}

set r1  { 1 11   8 13}
set r2  { 8 11  16 13}
set r3  {16 11  24 13}
set r4  {24 11  32 13}


## 5x5: 5 rows * 5 cols :

set q11 { 1  1   8  3}
set q12 { 8  1  16  3}
set q13 {16  1  24  3}
set q14 {24  1  32  3}
set q15 {32  1  40  3}

set q21 { 1  3   8  5}
set q22 { 8  3  16  5}
set q23 {16  3  24  5}
set q24 {24  3  32  5}
set q25 {32  3  40  5}

set q31 { 1  5   8  7}
set q32 { 8  5  16  7}
set q33 {16  5  24  7}
set q34 {24  5  32  7}
set q35 {32  5  40  7}

set q41 { 1  7   8  9}
set q42 { 8  7  16  9}
set q43 {16  7  24  9}
set q44 {24  7  32  9}
set q45 {32  7  40  9}

set q51 { 1  9   8 11}
set q52 { 8  9  16 11}
set q53 {16  9  24 11}
set q54 {24  9  32 11}
set q55 {32  9  40 11}

## + 6x5: 6 rows * 5 cols :

set q61 { 1 11   8 13}
set q62 { 8 11  16 13}
set q63 {16 11  24 13}
set q64 {24 11  32 13}
set q65 {32 11  40 13}


### Fuzzyness starts here:

# Each of the following start_XXX - procedures defines
# one of the the layouts for a fuzzyclock:
# * Scale scX: to adjust panel-size for text-length
# * Background-color,
# * Position on screen: for the "showcase"
# * All panels to be used:  text, position and tags.
# * Minute-table: has one entry for each minute of the hour,
#   with a list of tags/panels to highlight at that time.


proc start_DE1 w {
        puts "setup for german fuzzyclock#DE1"
        # 8x3 panels: "fünf Minuten vor halb vier Uhr"

        destroy $w
        pack [canvas $w  -width 200  -height 260  -background grey]
        set ::scX 9
        if {$::pos < 0} {wm geom . +50+15}

        #makeText $w t_N  {Es wird} {1  1  4  3}
        makeText $w t_N  {Es wird} $::a1
        makeText $w t_I  {Es ist}  $::b1
        makeText $w t_W  {Es war}  $::c1

        makeText $w t_v  fünf      $::a2
        makeText $w t_x  zehn      $::b2
        makeText $w t_M  Minuten   $::c2

        makeText $w t_B  vor       $::a3
        makeText $w t_P  nach      $::b3
        makeText $w t_h  halb      $::c3

        makeText $w t_0  null      $::a4
        makeText $w t_1  ein       $::b4
        makeText $w t_2  zwei      $::c4

        makeText $w t_3  drei      $::a5
        makeText $w t_4  vier      $::b5
        makeText $w t_5  fünf      $::c5

        makeText $w t_6  sechs     $::a6
        makeText $w t_7  sieben    $::b6
        makeText $w t_8  acht      $::c6

        makeText $w t_9  neun      $::a7
        makeText $w t_10 zehn      $::b7
        makeText $w t_11 elf       $::c7

        makeText $w t_12 zwölf     $::a8
        makeText $w t_C  Uhr       $::b8
        makeText $w t_AM morgens   $::c8
        #makeText $w t_PM abends    $::c8

        array set ::mTab {
                00  t_I
                01  t_W
                02  t_W

                03  {t_N t_P t_v t_M}
                04  {t_N t_P t_v t_M}
                05  {t_I t_P t_v t_M}
                06  {t_W t_P t_v t_M}
                07  {t_W t_P t_v t_M}

                08  {t_N t_P t_x t_M}
                09  {t_N t_P t_x t_M}
                10  {t_I t_P t_x t_M}
                11  {t_W t_P t_x t_M}
                12  {t_W t_P t_x t_M}

                13  {t_N t_P t_v t_x t_M}
                14  {t_N t_P t_v t_x t_M}
                15  {t_I t_P t_v t_x t_M}
                16  {t_W t_P t_v t_x t_M}
                17  {t_W t_P t_v t_x t_M}

                18  {t_N t_B t_x t_h t_M hH}
                19  {t_N t_B t_x t_h t_M hH}
                20  {t_I t_B t_x t_h t_M hH}
                21  {t_W t_B t_x t_h t_M hH}
                22  {t_W t_B t_x t_h t_M hH}

                23  {t_N t_B t_v t_h t_M hH}
                24  {t_N t_B t_v t_h t_M hH}
                25  {t_I t_B t_v t_h t_M hH}
                26  {t_W t_B t_v t_h t_M hH}
                27  {t_W t_B t_v t_h t_M hH}

                28  {t_N t_h hH}
                29  {t_N t_h hH}
                30  {t_I t_h hH}
                31  {t_W t_h hH}
                32  {t_W t_h hH}

                33  {t_N t_P t_v t_h t_M hH}
                34  {t_N t_P t_v t_h t_M hH}
                35  {t_I t_P t_v t_h t_M hH}
                36  {t_W t_P t_v t_h t_M hH}
                37  {t_W t_P t_v t_h t_M hH}

                38  {t_N t_P t_x t_h t_M hH}
                39  {t_N t_P t_x t_h t_M hH}
                40  {t_I t_P t_x t_h t_M hH}
                41  {t_W t_P t_x t_h t_M hH}
                42  {t_W t_P t_x t_h t_M hH}

                43  {t_N t_B t_v t_x t_M hH}
                44  {t_N t_B t_v t_x t_M hH}
                45  {t_I t_B t_v t_x t_M hH}
                46  {t_W t_B t_v t_x t_M hH}
                47  {t_W t_B t_v t_x t_M hH}

                48  {t_N t_B t_x t_M hH}
                49  {t_N t_B t_x t_M hH}
                50  {t_I t_B t_x t_M hH}
                51  {t_W t_B t_x t_M hH}
                52  {t_W t_B t_x t_M hH}

                53  {t_N t_B t_v t_M hH}
                54  {t_N t_B t_v t_M hH}
                55  {t_I t_B t_v t_M hH}
                56  {t_W t_B t_v t_M hH}
                57  {t_W t_B t_v t_M hH}

                58  {t_N hH}
                59  {t_N hH}
        }
        .c configure  -background DarkGreen
        ##puts $::mTab(05)
}


proc start_DE2 w {
        puts "setup for german fuzzyclock#DE2"
        # 8x3 panels: "drei Uhr fünf und zwanzig Minuten"

        destroy $w;  pack [canvas $w -width 200 -height 260 -background gray22]
        set ::scX 9
        if {$::pos < 0} {wm geom . +275+15}

        makeText $w t_I {Es ist} $::a1
        makeText $w t_AM morgens $::b1
        makeText $w t_0  null       $::c1

        makeText $w t_1  ein        $::a2
        makeText $w t_2  zwei       $::b2
        makeText $w t_3  drei       $::c2

        makeText $w t_4  vier       $::a3
        makeText $w t_5  fünf       $::b3
        makeText $w t_6  sechs      $::c3

        makeText $w t_7  sieben     $::a4
        makeText $w t_8  acht       $::b4
        makeText $w t_9  neun       $::c4

        makeText $w t_10 zehn       $::a5
        makeText $w t_11 elf        $::b5
        makeText $w t_12 zwölf      $::c5

        makeText $w t_C  Uhr        $::a6
        makeText $w t_v  fünf       $::b6
        makeText $w t_x  zehn       $::c6

        makeText $w t_+  und        $::a7
        makeText $w t_xx zwanzig    $::b7
        makeText $w t_30 dreissig   $::c7

        makeText $w t_40 vierzig    $::a8
        makeText $w t_50 fünfzig    $::b8
        makeText $w t_M  Minuten    $::c8

        array set ::mTab {
                00  t_I
                01  t_I
                02  t_I

                03  {t_I t_v t_M}
                04  {t_I t_v t_M}
                05  {t_I t_v t_M}
                06  {t_I t_v t_M}
                07  {t_I t_v t_M}

                08  {t_I t_x t_M}
                09  {t_I t_x t_M}
                10  {t_I t_x t_M}
                11  {t_I t_x t_M}
                12  {t_I t_x t_M}

                13  {t_I t_v t_x t_M}
                14  {t_I t_v t_x t_M}
                15  {t_I t_v t_x t_M}
                16  {t_I t_v t_x t_M}
                17  {t_I t_v t_x t_M}

                18  {t_I t_+ t_xx t_M}
                19  {t_I t_+ t_xx t_M}
                20  {t_I t_+ t_xx t_M}
                21  {t_I t_+ t_xx t_M}
                22  {t_I t_+ t_xx t_M}

                23  {t_I t_v t_+ t_xx t_M}
                24  {t_I t_v t_+ t_xx t_M}
                25  {t_I t_v t_+ t_xx t_M}
                26  {t_I t_v t_+ t_xx t_M}
                27  {t_I t_v t_+ t_xx t_M}

                28  {t_I t_+ t_30 t_M}
                29  {t_I t_+ t_30 t_M}
                30  {t_I t_+ t_30 t_M}
                31  {t_I t_+ t_30 t_M}
                32  {t_I t_+ t_30 t_M}

                33  {t_I t_v t_+  t_30 t_M}
                34  {t_I t_v t_+  t_30 t_M}
                35  {t_I t_v t_+  t_30 t_M}
                36  {t_I t_v t_+  t_30 t_M}
                37  {t_I t_v t_+  t_30 t_M}

                38  {t_I t_+ t_40 t_M}
                39  {t_I t_+ t_40 t_M}
                40  {t_I t_+ t_40 t_M}
                41  {t_I t_+ t_40 t_M}
                42  {t_I t_+ t_40 t_M}

                43  {t_I t_v t_+  t_40 t_M}
                44  {t_I t_v t_+  t_40 t_M}
                45  {t_I t_v t_+  t_40 t_M}
                46  {t_I t_v t_+  t_40 t_M}
                47  {t_I t_v t_+  t_40 t_M}

                48  {t_I t_+ t_50 t_M}
                49  {t_I t_+ t_50 t_M}
                50  {t_I t_+ t_50 t_M}
                51  {t_I t_+ t_50 t_M}
                52  {t_I t_+ t_50 t_M}

                53  {t_I t_v t_+  t_50 t_M}
                54  {t_I t_v t_+  t_50 t_M}
                55  {t_I t_v t_+  t_50 t_M}
                56  {t_I t_v t_+  t_50 t_M}
                57  {t_I t_v t_+  t_50 t_M}

                58  {t_I  hH}
                59  {t_I  hH}
        }
        .c configure  -background ForestGreen
}


proc start_DE3 w {
        puts "setup for german fuzzyclock#DE3"
        # 8x3 panels: "morgens viertel nach elf"

        destroy $w;  pack [canvas $w -width 205 -height 260 -background gray33]
        set ::scX 9.5
        if {$::pos < 0} {wm geom . +500+15}

        makeText $w t_N  {Es wird} $::a1
        makeText $w t_I  {Es ist}  $::b1
        makeText $w t_W  {Es war}  $::c1

        makeText $w t_AM morgens   $::a2
        makeText $w t_PM abends    $::b2
        makeText $w t_v  fünf      $::c2

        makeText $w t_x  zehn      $::a3
        #makeText $w t_M Minuten   $::b3
        makeText $w t_q  viertel   $::b3
        makeText $w t_B  vor       $::c3

        makeText $w t_P  nach      $::a4
        makeText $w t_h  halb      $::b4
        makeText $w t_0  {null Uhr}    $::c4

        makeText $w t_1  {ein Uhr}     $::a5
        makeText $w t_2  {zwei Uhr}    $::b5
        makeText $w t_3  {drei Uhr}    $::c5

        makeText $w t_4  {vier Uhr}    $::a6
        makeText $w t_5  {fünf Uhr}    $::b6
        makeText $w t_6  {sechs Uhr}   $::c6

        makeText $w t_7  {sieben Uhr}  $::a7
        makeText $w t_8  {acht Uhr}    $::b7
        makeText $w t_9  {neun Uhr}    $::c7

        makeText $w t_10 {zehn Uhr}    $::a8
        makeText $w t_11 {elf Uhr}     $::b8
        makeText $w t_12 {zwölf Uhr}   $::c8

        #makeText $w t_C_  Uhr      $::c9

        array set ::mTab {
                00  t_I
                01  t_W
                02  t_W

                03  {t_N t_P t_v t_M}
                04  {t_N t_P t_v t_M}
                05  {t_I t_P t_v t_M}
                06  {t_W t_P t_v t_M}
                07  {t_W t_P t_v t_M}

                08  {t_N t_P t_x t_M}
                09  {t_N t_P t_x t_M}
                10  {t_I t_P t_x t_M}
                11  {t_W t_P t_x t_M}
                12  {t_W t_P t_x t_M}

                13  {t_N t_P t_q t_M}
                14  {t_N t_P t_q t_M}
                15  {t_I t_P t_q t_M}
                16  {t_W t_P t_q t_M}
                17  {t_W t_P t_q t_M}

                18  {t_N t_B t_x t_h t_M hH}
                19  {t_N t_B t_x t_h t_M hH}
                20  {t_I t_B t_x t_h t_M hH}
                21  {t_W t_B t_x t_h t_M hH}
                22  {t_W t_B t_x t_h t_M hH}

                23  {t_N t_B t_v t_h t_M hH}
                24  {t_N t_B t_v t_h t_M hH}
                25  {t_I t_B t_v t_h t_M hH}
                26  {t_W t_B t_v t_h t_M hH}
                27  {t_W t_B t_v t_h t_M hH}

                28  {t_N t_h hH}
                29  {t_N t_h hH}
                30  {t_I t_h hH}
                31  {t_W t_h hH}
                32  {t_W t_h hH}

                33  {t_N t_P t_v t_h t_M hH}
                34  {t_N t_P t_v t_h t_M hH}
                35  {t_I t_P t_v t_h t_M hH}
                36  {t_W t_P t_v t_h t_M hH}
                37  {t_W t_P t_v t_h t_M hH}

                38  {t_N t_P t_x t_h t_M hH}
                39  {t_N t_P t_x t_h t_M hH}
                40  {t_I t_P t_x t_h t_M hH}
                41  {t_W t_P t_x t_h t_M hH}
                42  {t_W t_P t_x t_h t_M hH}

                43  {t_N t_B t_q t_M hH}
                44  {t_N t_B t_q t_M hH}
                45  {t_I t_B t_q t_M hH}
                46  {t_W t_B t_q t_M hH}
                47  {t_W t_B t_q t_M hH}

                48  {t_N t_B t_x t_M hH}
                49  {t_N t_B t_x t_M hH}
                50  {t_I t_B t_x t_M hH}
                51  {t_W t_B t_x t_M hH}
                52  {t_W t_B t_x t_M hH}

                53  {t_N t_B t_v t_M hH}
                54  {t_N t_B t_v t_M hH}
                55  {t_I t_B t_v t_M hH}
                56  {t_W t_B t_v t_M hH}
                57  {t_W t_B t_v t_M hH}

                58  {t_N hH}
                59  {t_N hH}
        }
        .c configure  -background PaleGreen4
}


proc start_DE4 w {
        puts "setup for german fuzzyclock#DE4"
        # 8x3 panels: "morgens viertel nach elf Uhr"

        destroy $w;  pack [canvas $w  -width 175  -height 260 -background gray44]
        set ::scX 8
        if {$::pos < 0} {wm geom . +725+15}

        makeText $w t_N  {Es wird} $::a1
        makeText $w t_I  {Es ist}  $::b1
        makeText $w t_W  {Es war}  $::c1

        makeText $w t_AM morgens   $::a2
        makeText $w t_v  fünf      $::b2
        makeText $w t_x  zehn      $::c2

        makeText $w t_q  viertel   $::a3
        makeText $w t_B  vor       $::b3
        makeText $w t_P  nach      $::c3

        makeText $w t_h  halb      $::a4
        makeText $w t_0  null      $::b4
        makeText $w t_1  ein       $::c4

        makeText $w t_2  zwei      $::a5
        makeText $w t_3  drei      $::b5
        makeText $w t_4  vier      $::c5

        makeText $w t_5  fünf      $::a6
        makeText $w t_6  sechs     $::b6
        makeText $w t_7  sieben    $::c6

        makeText $w t_8  acht      $::a7
        makeText $w t_9  neun      $::b7
        makeText $w t_10 zehn      $::c7

        makeText $w t_11 elf       $::a8
        makeText $w t_12 zwölf     $::b8
        makeText $w t_C  Uhr       $::c8

        array set ::mTab {
                00  t_I
                01  t_W
                02  t_W

                03  {t_N t_P t_v t_M}
                04  {t_N t_P t_v t_M}
                05  {t_I t_P t_v t_M}
                06  {t_W t_P t_v t_M}
                07  {t_W t_P t_v t_M}

                08  {t_N t_P t_x t_M}
                09  {t_N t_P t_x t_M}
                10  {t_I t_P t_x t_M}
                11  {t_W t_P t_x t_M}
                12  {t_W t_P t_x t_M}

                13  {t_N t_P t_q t_M}
                14  {t_N t_P t_q t_M}
                15  {t_I t_P t_q t_M}
                16  {t_W t_P t_q t_M}
                17  {t_W t_P t_q t_M}

                18  {t_N t_B t_x t_h t_M hH}
                19  {t_N t_B t_x t_h t_M hH}
                20  {t_I t_B t_x t_h t_M hH}
                21  {t_W t_B t_x t_h t_M hH}
                22  {t_W t_B t_x t_h t_M hH}

                23  {t_N t_B t_v t_h t_M hH}
                24  {t_N t_B t_v t_h t_M hH}
                25  {t_I t_B t_v t_h t_M hH}
                26  {t_W t_B t_v t_h t_M hH}
                27  {t_W t_B t_v t_h t_M hH}

                28  {t_N t_h hH}
                29  {t_N t_h hH}
                30  {t_I t_h hH}
                31  {t_W t_h hH}
                32  {t_W t_h hH}

                33  {t_N t_P t_v t_h t_M hH}
                34  {t_N t_P t_v t_h t_M hH}
                35  {t_I t_P t_v t_h t_M hH}
                36  {t_W t_P t_v t_h t_M hH}
                37  {t_W t_P t_v t_h t_M hH}

                38  {t_N t_P t_x t_h t_M hH}
                39  {t_N t_P t_x t_h t_M hH}
                40  {t_I t_P t_x t_h t_M hH}
                41  {t_W t_P t_x t_h t_M hH}
                42  {t_W t_P t_x t_h t_M hH}

                43  {t_N t_B t_q t_M hH}
                44  {t_N t_B t_q t_M hH}
                45  {t_I t_B t_q t_M hH}
                46  {t_W t_B t_q t_M hH}
                47  {t_W t_B t_q t_M hH}

                48  {t_N t_B t_x t_M hH}
                49  {t_N t_B t_x t_M hH}
                50  {t_I t_B t_x t_M hH}
                51  {t_W t_B t_x t_M hH}
                52  {t_W t_B t_x t_M hH}

                53  {t_N t_B t_v t_M hH}
                54  {t_N t_B t_v t_M hH}
                55  {t_I t_B t_v t_M hH}
                56  {t_W t_B t_v t_M hH}
                57  {t_W t_B t_v t_M hH}

                58  {t_N hH}
                59  {t_N hH}
        }
        .c configure -background SeaGreen4
}

proc start_DE5 w {
        puts "setup for german fuzzyclock#DE2->DE5"
        # 5x5 panels: "drei Uhr fünf und zwanzig Minuten"

        #destroy $w; pack [canvas $w -width 200 -height 260 -background gray22]
        destroy $w; pack [canvas $w -width 288 -height 170 -background gray25]
        set ::scX 7.1
        if {$::pos < 0} {wm geom . +50+310}

        makeText $w t_I  {Es ist}   $::q11
        makeText $w t_AM morgens    $::q12
        makeText $w t_0  null       $::q13
        makeText $w t_1  ein        $::q14
        makeText $w t_2  zwei       $::q15

        makeText $w t_3  drei       $::q21
        makeText $w t_4  vier       $::q22
        makeText $w t_5  fünf       $::q23
        makeText $w t_6  sechs      $::q24
        makeText $w t_7  sieben     $::q25

        makeText $w t_8  acht       $::q31
        makeText $w t_9  neun       $::q32
        makeText $w t_10 zehn       $::q33
        makeText $w t_11 elf        $::q34
        makeText $w t_12 zwölf      $::q35

        makeText $w t_C  Uhr        $::q41
        makeText $w t_+  und        $::q42
        makeText $w t_v  fünf       $::q43
        makeText $w t_x  zehn       $::q44
        makeText $w t_++ und        $::q45

        makeText $w t_xx zwanzig    $::q51
        makeText $w t_30 dreissig   $::q52
        makeText $w t_40 vierzig    $::q53
        makeText $w t_50 fünfzig    $::q54
        makeText $w t_M  Minuten    $::q55

        array set ::mTab {
                00  t_I
                01  t_I
                02  t_I

                03  {t_I t_+ t_v t_M}
                04  {t_I t_+ t_v t_M}
                05  {t_I t_+ t_v t_M}
                06  {t_I t_+ t_v t_M}
                07  {t_I t_+ t_v t_M}

                08  {t_I t_+ t_x t_M}
                09  {t_I t_+ t_x t_M}
                10  {t_I t_+ t_x t_M}
                11  {t_I t_+ t_x t_M}
                12  {t_I t_+ t_x t_M}

                13  {t_I t_+ t_v t_x t_M}
                14  {t_I t_+ t_v t_x t_M}
                15  {t_I t_+ t_v t_x t_M}
                16  {t_I t_+ t_v t_x t_M}
                17  {t_I t_+ t_v t_x t_M}

                18  {t_I t_+ t_xx t_M}
                19  {t_I t_+ t_xx t_M}
                20  {t_I t_+ t_xx t_M}
                21  {t_I t_+ t_xx t_M}
                22  {t_I t_+ t_xx t_M}

                23  {t_I t_+ t_v t_++ t_xx t_M}
                24  {t_I t_+ t_v t_++ t_xx t_M}
                25  {t_I t_+ t_v t_++ t_xx t_M}
                26  {t_I t_+ t_v t_++ t_xx t_M}
                27  {t_I t_+ t_v t_++ t_xx t_M}

                28  {t_I t_+ t_30 t_M}
                29  {t_I t_+ t_30 t_M}
                30  {t_I t_+ t_30 t_M}
                31  {t_I t_+ t_30 t_M}
                32  {t_I t_+ t_30 t_M}

                33  {t_I t_+ t_v t_++ t_30 t_M}
                34  {t_I t_+ t_v t_++ t_30 t_M}
                35  {t_I t_+ t_v t_++ t_30 t_M}
                36  {t_I t_+ t_v t_++ t_30 t_M}
                37  {t_I t_+ t_v t_++ t_30 t_M}

                38  {t_I t_+ t_40 t_M}
                39  {t_I t_+ t_40 t_M}
                40  {t_I t_+ t_40 t_M}
                41  {t_I t_+ t_40 t_M}
                42  {t_I t_+ t_40 t_M}

                43  {t_I t_+ t_v t_++ t_40 t_M}
                44  {t_I t_+ t_v t_++ t_40 t_M}
                45  {t_I t_+ t_v t_++ t_40 t_M}
                46  {t_I t_+ t_v t_++ t_40 t_M}
                47  {t_I t_+ t_v t_++ t_40 t_M}

                48  {t_I t_+ t_50 t_M}
                49  {t_I t_+ t_50 t_M}
                50  {t_I t_+ t_50 t_M}
                51  {t_I t_+ t_50 t_M}
                52  {t_I t_+ t_50 t_M}

                53  {t_I t_+ t_v t_++ t_50 t_M}
                54  {t_I t_+ t_v t_++ t_50 t_M}
                55  {t_I t_+ t_v t_++ t_50 t_M}
                56  {t_I t_+ t_v t_++ t_50 t_M}
                57  {t_I t_+ t_v t_++ t_50 t_M}

                58  {t_I  hH}
                59  {t_I  hH}
        }

        #ForestGreen
        .c configure  -background PaleGreen
}


proc start_DE6 w {
        puts "setup for german fuzzyclock#DE2->DE6"
        # 6x4 panels: "drei Uhr fünf und zwanzig Minuten"

        #destroy $w;  pack [canvas $w  -width 200  -height 260  -background gray22]
        destroy $w;  pack [canvas $w  -width 320  -height 140  -background gray61]
        set ::scX 6.5
        if {$::pos < 0} {wm geom . +50+530}

        makeText $w t_I  {Es ist}   $::d1
        makeText $w t_AM morgens    $::d2
        makeText $w t_0  null       $::d3

        makeText $w t_1  ein        $::d4
        makeText $w t_2  zwei       $::d5
        makeText $w t_3  drei       $::d6

        makeText $w t_4  vier       $::e1
        makeText $w t_5  fünf       $::e2
        makeText $w t_6  sechs      $::e3
        makeText $w t_7  sieben     $::e4
        makeText $w t_8  acht       $::e5
        makeText $w t_9  neun       $::e6

        makeText $w t_10 zehn       $::f1
        makeText $w t_11 elf        $::f2
        makeText $w t_12 zwölf      $::f3
        makeText $w t_C  Uhr        $::f4
        makeText $w t_v  fünf       $::f5
        makeText $w t_x  zehn       $::f6

        makeText $w t_+  und        $::g1
        makeText $w t_xx zwanzig    $::g2
        makeText $w t_30 dreissig   $::g3
        makeText $w t_40 vierzig    $::g4
        makeText $w t_50 fünfzig    $::g5
        makeText $w t_M  Minuten    $::g6

        array set ::mTab {
                00  t_I
                01  t_I
                02  t_I

                03  {t_I t_v t_M}
                04  {t_I t_v t_M}
                05  {t_I t_v t_M}
                06  {t_I t_v t_M}
                07  {t_I t_v t_M}

                08  {t_I t_x t_M}
                09  {t_I t_x t_M}
                10  {t_I t_x t_M}
                11  {t_I t_x t_M}
                12  {t_I t_x t_M}

                13  {t_I t_v t_x t_M}
                14  {t_I t_v t_x t_M}
                15  {t_I t_v t_x t_M}
                16  {t_I t_v t_x t_M}
                17  {t_I t_v t_x t_M}

                18  {t_I t_+ t_xx t_M}
                19  {t_I t_+ t_xx t_M}
                20  {t_I t_+ t_xx t_M}
                21  {t_I t_+ t_xx t_M}
                22  {t_I t_+ t_xx t_M}

                23  {t_I t_v t_+ t_xx t_M}
                24  {t_I t_v t_+ t_xx t_M}
                25  {t_I t_v t_+ t_xx t_M}
                26  {t_I t_v t_+ t_xx t_M}
                27  {t_I t_v t_+ t_xx t_M}

                28  {t_I t_+ t_30 t_M}
                29  {t_I t_+ t_30 t_M}
                30  {t_I t_+ t_30 t_M}
                31  {t_I t_+ t_30 t_M}
                32  {t_I t_+ t_30 t_M}

                33  {t_I t_v t_+  t_30 t_M}
                34  {t_I t_v t_+  t_30 t_M}
                35  {t_I t_v t_+  t_30 t_M}
                36  {t_I t_v t_+  t_30 t_M}
                37  {t_I t_v t_+  t_30 t_M}

                38  {t_I t_+ t_40 t_M}
                39  {t_I t_+ t_40 t_M}
                40  {t_I t_+ t_40 t_M}
                41  {t_I t_+ t_40 t_M}
                42  {t_I t_+ t_40 t_M}

                43  {t_I t_v t_+  t_40 t_M}
                44  {t_I t_v t_+  t_40 t_M}
                45  {t_I t_v t_+  t_40 t_M}
                46  {t_I t_v t_+  t_40 t_M}
                47  {t_I t_v t_+  t_40 t_M}

                48  {t_I t_+ t_50 t_M}
                49  {t_I t_+ t_50 t_M}
                50  {t_I t_+ t_50 t_M}
                51  {t_I t_+ t_50 t_M}
                52  {t_I t_+ t_50 t_M}

                53  {t_I t_v t_+  t_50 t_M}
                54  {t_I t_v t_+  t_50 t_M}
                55  {t_I t_v t_+  t_50 t_M}
                56  {t_I t_v t_+  t_50 t_M}
                57  {t_I t_v t_+  t_50 t_M}

                58  {t_I  hH}
                59  {t_I  hH}
        }

        # ForestGreen
        .c configure  -background Green
}


proc start_DE7 w {
        puts "setup for german fuzzyclock#DE2->DE6/DE7"
        # 4x6 panels: "drei Uhr fünf und zwanzig Minuten"

        #destroy $w;  pack [canvas $w -width 200 -height 260 -background gray22]
        destroy $w; pack [canvas $w -width 240 -height 200 -background gray67]
        set ::scX 7.3
        if {$::pos < 0} {wm geom . +360+310}

        makeText $w t_I  {Es ist}   $::m1
        makeText $w t_AM morgens    $::m2
        makeText $w t_0  null       $::m3

        makeText $w t_1  ein        $::m4

        makeText $w t_2  zwei       $::n1
        makeText $w t_3  drei       $::n2
        makeText $w t_4  vier       $::n3
        makeText $w t_5  fünf       $::n4

        makeText $w t_6  sechs      $::o1
        makeText $w t_7  sieben     $::o2
        makeText $w t_8  acht       $::o3
        makeText $w t_9  neun       $::o4

        makeText $w t_10 zehn       $::p1
        makeText $w t_11 elf        $::p2
        makeText $w t_12 zwölf      $::p3
        makeText $w t_C  Uhr        $::p4

        makeText $w t_v  fünf       $::q1
        makeText $w t_x  zehn       $::q2
        makeText $w t_+  und        $::q3
        makeText $w t_xx zwanzig    $::q4

        makeText $w t_30 dreissig   $::r1
        makeText $w t_40 vierzig    $::r2
        makeText $w t_50 fünfzig    $::r3
        makeText $w t_M  Minuten    $::r4

        array set ::mTab {
                00  t_I
                01  t_I
                02  t_I

                03  {t_I t_v t_M}
                04  {t_I t_v t_M}
                05  {t_I t_v t_M}
                06  {t_I t_v t_M}
                07  {t_I t_v t_M}

                08  {t_I t_x t_M}
                09  {t_I t_x t_M}
                10  {t_I t_x t_M}
                11  {t_I t_x t_M}
                12  {t_I t_x t_M}

                13  {t_I t_v t_x t_M}
                14  {t_I t_v t_x t_M}
                15  {t_I t_v t_x t_M}
                16  {t_I t_v t_x t_M}
                17  {t_I t_v t_x t_M}

                18  {t_I t_+ t_xx t_M}
                19  {t_I t_+ t_xx t_M}
                20  {t_I t_+ t_xx t_M}
                21  {t_I t_+ t_xx t_M}
                22  {t_I t_+ t_xx t_M}

                23  {t_I t_v t_+ t_xx t_M}
                24  {t_I t_v t_+ t_xx t_M}
                25  {t_I t_v t_+ t_xx t_M}
                26  {t_I t_v t_+ t_xx t_M}
                27  {t_I t_v t_+ t_xx t_M}

                28  {t_I t_+ t_30 t_M}
                29  {t_I t_+ t_30 t_M}
                30  {t_I t_+ t_30 t_M}
                31  {t_I t_+ t_30 t_M}
                32  {t_I t_+ t_30 t_M}

                33  {t_I t_v t_+  t_30 t_M}
                34  {t_I t_v t_+  t_30 t_M}
                35  {t_I t_v t_+  t_30 t_M}
                36  {t_I t_v t_+  t_30 t_M}
                37  {t_I t_v t_+  t_30 t_M}

                38  {t_I t_+ t_40 t_M}
                39  {t_I t_+ t_40 t_M}
                40  {t_I t_+ t_40 t_M}
                41  {t_I t_+ t_40 t_M}
                42  {t_I t_+ t_40 t_M}

                43  {t_I t_v t_+  t_40 t_M}
                44  {t_I t_v t_+  t_40 t_M}
                45  {t_I t_v t_+  t_40 t_M}
                46  {t_I t_v t_+  t_40 t_M}
                47  {t_I t_v t_+  t_40 t_M}

                48  {t_I t_+ t_50 t_M}
                49  {t_I t_+ t_50 t_M}
                50  {t_I t_+ t_50 t_M}
                51  {t_I t_+ t_50 t_M}
                52  {t_I t_+ t_50 t_M}

                53  {t_I t_v t_+  t_50 t_M}
                54  {t_I t_v t_+  t_50 t_M}
                55  {t_I t_v t_+  t_50 t_M}
                56  {t_I t_v t_+  t_50 t_M}
                57  {t_I t_v t_+  t_50 t_M}

                58  {t_I  hH}
                59  {t_I  hH}
        }

        # ForestGreen
        .c configure  -background Green1
}


proc start_DE8 w {
        puts "setup for german 24h fuzzyclock#DE2->DE5->DE8"

# ToDo ...

}


###


proc start_I1 w {
        puts {setup for international fuzzyclock#1}
        # 8x3 panels: "three o'clock twenty five minutes"

        destroy $w; pack [canvas $w -width 175 -height 260 -background gray11]
        set ::scX 8
        if {$::pos < 0} {wm geom . +620+310}

        makeText $w t_I  {It is}   $::a1
        makeText $w t_AM AM        $::b1
        makeText $w t_0  zero      $::c1

        makeText $w t_1  one       $::a2
        makeText $w t_2  two       $::b2
        makeText $w t_3  three     $::c2

        makeText $w t_4  four      $::a3
        makeText $w t_5  five      $::b3
        makeText $w t_6  six       $::c3

        makeText $w t_7  seven     $::a4
        makeText $w t_8  eight     $::b4
        makeText $w t_9  nine      $::c4

        makeText $w t_10 ten       $::a5
        makeText $w t_11 eleven    $::b5
        makeText $w t_12 twelve    $::c5

        makeText $w t_C  o'clock   $::a6
        makeText $w t_x  ten       $::b6
        makeText $w t_xv fifteen   $::c6

        makeText $w t_xx twenty    $::a7
        makeText $w t_30 thirty    $::b7
        makeText $w t_40 fourty    $::c7

        makeText $w t_50 fifty     $::a8
        makeText $w t_v  five      $::b8
        makeText $w t_M  minutes   $::c8

        array set ::mTab {
                00  t_I
                01  t_I
                02  t_I

                03  {t_I t_v t_M}
                04  {t_I t_v t_M}
                05  {t_I t_v t_M}
                06  {t_I t_v t_M}
                07  {t_I t_v t_M}

                08  {t_I t_x t_M}
                09  {t_I t_x t_M}
                10  {t_I t_x t_M}
                11  {t_I t_x t_M}
                12  {t_I t_x t_M}

                13  {t_I t_xv t_M}
                14  {t_I t_xv t_M}
                15  {t_I t_xv t_M}
                16  {t_I t_xv t_M}
                17  {t_I t_xv t_M}

                18  {t_I t_xx t_M}
                19  {t_I t_xx t_M}
                20  {t_I t_xx t_M}
                21  {t_I t_xx t_M}
                22  {t_I t_xx t_M}

                23  {t_I t_v t_+ t_xx t_M}
                24  {t_I t_v t_+ t_xx t_M}
                25  {t_I t_v t_+ t_xx t_M}
                26  {t_I t_v t_+ t_xx t_M}
                27  {t_I t_v t_+ t_xx t_M}

                28  {t_I t_30 t_M}
                29  {t_I t_30 t_M}
                30  {t_I t_30 t_M}
                31  {t_I t_30 t_M}
                32  {t_I t_30 t_M}

                33  {t_I t_v t_+  t_30 t_M}
                34  {t_I t_v t_+  t_30 t_M}
                35  {t_I t_v t_+  t_30 t_M}
                36  {t_I t_v t_+  t_30 t_M}
                37  {t_I t_v t_+  t_30 t_M}

                38  {t_I t_40 t_M}
                39  {t_I t_40 t_M}
                40  {t_I t_40 t_M}
                41  {t_I t_40 t_M}
                42  {t_I t_40 t_M}

                43  {t_I t_v t_+  t_40 t_M}
                44  {t_I t_v t_+  t_40 t_M}
                45  {t_I t_v t_+  t_40 t_M}
                46  {t_I t_v t_+  t_40 t_M}
                47  {t_I t_v t_+  t_40 t_M}

                48  {t_I t_50 t_M}
                49  {t_I t_50 t_M}
                50  {t_I t_50 t_M}
                51  {t_I t_50 t_M}
                52  {t_I t_50 t_M}

                53  {t_I t_v t_50 t_M}
                54  {t_I t_v t_50 t_M}
                55  {t_I t_v t_50 t_M}
                56  {t_I t_v t_50 t_M}
                57  {t_I t_v t_50 t_M}

                58  {t_I  hH}
                59  {t_I  hH}
        }

        # maroon
        .c configure  -background FireBrick
}


proc start_I2 w {
        puts {setup for international fuzzyclock#2}
        # 8x3 panels: "quarter past three o'clock"

        destroy $w;  pack [canvas $w  -width 175  -height 260  -background grey12]
        set ::scX 8
        if {$::pos < 0} {wm geom . +820+310}

        makeText $w t_I  {It is}     $::a1
        makeText $w t_AM AM          $::b1
        makeText $w t_x  ten         $::c1

        makeText $w t_q  {a quarter} $::a2
        makeText $w t_xx twenty      $::b2
        makeText $w t_h  half        $::c2

        makeText $w t_v  five        $::a3
        makeText $w t_M  minutes     $::b3
        makeText $w t_B  before      $::c3

        makeText $w t_P  past        $::a4
        makeText $w t_0  zero        $::b4
        makeText $w t_1  one         $::c4

        makeText $w t_2  two         $::a5
        makeText $w t_3  three       $::b5
        makeText $w t_4  four        $::c5

        makeText $w t_5  five        $::a6
        makeText $w t_6  six         $::b6
        makeText $w t_7  seven       $::c6

        makeText $w t_8  eight       $::a7
        makeText $w t_9  nine        $::b7
        makeText $w t_10 ten         $::c7

        makeText $w t_11 eleven      $::a8
        makeText $w t_12 twelve      $::b8
        makeText $w t_C  o'clock     $::c8

        array set ::mTab {
                00  t_I
                01  t_I
                02  t_I

                03  {t_I t_P t_v t_M}
                04  {t_I t_P t_v t_M}
                05  {t_I t_P t_v t_M}
                06  {t_I t_P t_v t_M}
                07  {t_I t_P t_v t_M}

                08  {t_I t_P t_x t_M}
                09  {t_I t_P t_x t_M}
                10  {t_I t_P t_x t_M}
                11  {t_I t_P t_x t_M}
                12  {t_I t_P t_x t_M}

                13  {t_I t_P t_q t_}
                14  {t_I t_P t_q t_}
                15  {t_I t_P t_q t_}
                16  {t_I t_P t_q t_}
                17  {t_I t_P t_q t_}

                18  {t_I t_P t_xx t_M}
                19  {t_I t_P t_xx t_M}
                20  {t_I t_P t_xx t_M}
                21  {t_I t_P t_xx t_M}
                22  {t_I t_P t_xx t_M}

                23  {t_I t_P t_v t_xx t_M}
                24  {t_I t_P t_v t_xx t_M}
                25  {t_I t_P t_v t_xx t_M}
                26  {t_I t_P t_v t_xx t_M}
                27  {t_I t_P t_v t_xx t_M}

                28  {t_I t_h t_P}
                29  {t_I t_h t_P}
                30  {t_I t_h t_P}
                31  {t_I t_h t_P}
                32  {t_I t_h t_P}

                33  {t_I t_B t_v t_xx t_M hH}
                34  {t_I t_B t_v t_xx t_M hH}
                35  {t_I t_B t_v t_xx t_M hH}
                36  {t_I t_B t_v t_xx t_M hH}
                37  {t_I t_B t_v t_xx t_M hH}

                38  {t_I t_B t_xx t_M hH}
                39  {t_I t_B t_xx t_M hH}
                40  {t_I t_B t_xx t_M hH}
                41  {t_I t_B t_xx t_M hH}
                42  {t_I t_B t_xx t_M hH}

                43  {t_I t_B t_q t_ hH}
                44  {t_I t_B t_q t_ hH}
                45  {t_I t_B t_q t_ hH}
                46  {t_I t_B t_q t_ hH}
                47  {t_I t_B t_q t_ hH}

                48  {t_I t_B t_x t_M hH}
                49  {t_I t_B t_x t_M hH}
                50  {t_I t_B t_x t_M hH}
                51  {t_I t_B t_x t_M hH}
                52  {t_I t_B t_x t_M hH}

                53  {t_I t_B t_v t_M hH}
                54  {t_I t_B t_v t_M hH}
                55  {t_I t_B t_v t_M hH}
                56  {t_I t_B t_v t_M hH}
                57  {t_I t_B t_v t_M hH}

                58  {t_I hH}
                59  {t_I hH}
        }

        # OrangeRed4
        .c configure  -background Red4
}


# International 24h
proc start_I3 w {Dummy start_I3}


### ### ###


proc start_SG1 w {
        puts "G1: setup for german fuzzy shipclock / glasen"
        # 8x3 panels - tall: "zweite Tagwache drei Glasen und fünf und zwanzig Minuten"

        destroy $w
        pack [canvas $w -width 270 -height 260 -background gray70]
        set ::scX 12.5
        if {$::pos < 0} {wm geom . +50+15}

        makeText $w t_gI {Es ist}        $::a1
        makeText $w t_Su Sonntag         $::b1
        makeText $w t_HN Mittag          $::c1

        # 04:00
        makeText $w t_w1 erste           $::a2

        # 08:00
        makeText $w t_w2 zweite          $::b2


        # 12:00
        makeText $w t_w3 dritte          $::c2

        # 16:00
        makeText $w t_w4 vierte          $::a3
        makeText $w t_dw Tagwache        $::b3

        # 20:00 / 00:00
        makeText $w t_nw Nachtwache      $::c3

        makeText $w t_g1 {ein  Glasen}   $::a4
        makeText $w t_g2 {zwei Glasen}   $::b4
        makeText $w t_g3 {drei Glasen}   $::c4

        makeText $w t_g4 {vier Glasen}   $::a5
        makeText $w t_g5 {fünf Glasen}   $::b5
        makeText $w t_g6 {sechs Glasen}  $::c5

        makeText $w t_g7 {sieben Glasen} $::a6
        makeText $w t_g8 {acht Glasen}   $::b6
        #makeText $w t_G  Glasen         $::c6

        makeText $w t_+1 und             $::a7
        makeText $w t_gv fünf            $::b7
        makeText $w t_gx zehn            $::c7

        makeText $w t_+2 und             $::a8
        makeText $w t_gz zwanzig         $::b8
        makeText $w t_gM Minuten         $::c8


        ## see also: proc upd

        array set ::sTab {
                w1  {t_w1 t_dw}
                w2  {t_w2 t_dw}
                w3  {t_w3 t_dw}
                w4  {t_w4 t_dw}
                w5  {t_w1 t_nw}
                w0  {t_w2 t_nw}
                        0  {}
                        5  {t_+1 t_gv t_gM}
                10  {t_+1 t_gx t_gM}
                15  {t_+1 t_gv t_gx t_gM}
                20  {t_+1 t_gz t_gM}
                25  {t_+1 t_gv t_+2 t_gz t_gM}
        }

        # MediumBlue blue4
        .c configure  -background blue2
}


proc start_SG2 w {
        puts "G2: setup for german fuzzy shipclock / glasen"
        # 3x8 panels - wide: "zweite Tagwache drei Glasen und fünf und zwanzig Minuten"

        global x1 x2 x3 x4 x5 x6 x7 x8  y1 y2 y3 y4 y5 y6 y7 y8  z1 z2 z3 z4 z5 z6 z7 z8

        destroy $w;  pack [canvas $w  -width 615  -height 110  -background gray80]
        set ::scX 9.6
        if {$::pos < 0} {wm geom . +340+15}

        makeText $w t_gI {Es ist}        $::x1
        makeText $w t_Su Sonntag         $x2

        makeText $w t_HN Mittag          $z1

        # 04:00
        makeText $w t_w1 erste           $x3

        # 08:00
        makeText $w t_w2 zweite          $x4

        # 12:00
        makeText $w t_w3 dritte          $x5


        # 16:00
        makeText $w t_w4 vierte          $x6
        makeText $w t_dw Tagwache        $x7

        # 20:00 / 00:00
        makeText $w t_nw Nachtwache      $x8

        makeText $w t_g1 {ein  Glasen}   $y1
        makeText $w t_g2 {zwei Glasen}   $y2
        makeText $w t_g3 {drei Glasen}   $y3

        makeText $w t_g4 {vier Glasen}   $y4
        makeText $w t_g5 {fünf Glasen}   $y5
        makeText $w t_g6 {sechs Glasen}  $y6

        makeText $w t_g7 {sieben Glasen} $y7
        makeText $w t_g8 {acht Glasen}   $y8
        #makeText $w t_G  Glasen         $y8

        makeText $w t_+1 und             $z3
        makeText $w t_gv fünf            $z4
        makeText $w t_gx zehn            $z5

        makeText $w t_+2 und             $z6
        makeText $w t_gz zwanzig         $z7
        makeText $w t_gM Minuten         $z8


        ## see also: proc upd

        array set ::sTab {
                w1  {t_w1 t_dw}
                w2  {t_w2 t_dw}
                w3  {t_w3 t_dw}
                w4  {t_w4 t_dw}
                w5  {t_w1 t_nw}
                w0  {t_w2 t_nw}
                        0  {}
                        5  {t_+1 t_gv t_gM}
                10  {t_+1 t_gx t_gM}
                15  {t_+1 t_gv t_gx t_gM}
                20  {t_+1 t_gz t_gM}
                25  {t_+1 t_gv t_+2 t_gz t_gM}
        }

        # blue4
        .c configure  -background MediumBlue
}


###


proc start_SB1 w {
        puts {SB1: setup for international fuzzy ship's bell}
        # 8x3 panels: "Forenoon watch three bells and twenty five minutes"

        destroy $w;  pack [canvas $w  -width 260  -height 260  -background gray90]
        set ::scX 12
        if {$::pos < 0} {wm geom . +50+320}

        makeText $w t_gI {It is}         $::a1
        makeText $w t_Su Sunday          $::b1


        # 20:00
        makeText $w t_w5 First           $::c1


        # 00:00
        makeText $w t_w0 Middle          $::a2

        # 04:00
        makeText $w t_w1 Morning         $::b2

        # 08:00
        makeText $w t_w2 Forenoon        $::c2


        # 12:00
        makeText $w t_w3 Afternoon       $::a3

        # 16:00
        makeText $w t_w4 Dog             $::b3
        makeText $w t_gW watch           $::c3

        makeText $w t_g1 {one bell}      $::a4
        makeText $w t_g2 {two bells}     $::b4
        makeText $w t_g3 {three bells}   $::c4

        makeText $w t_g4 {four bells}    $::a5
        makeText $w t_g5 {five bells}    $::b5
        makeText $w t_g6 {six  bells}    $::c5

        makeText $w t_g7 {seven bells}   $::a6
        makeText $w t_g8 {eight bells}   $::b6
        #makeText $w t_G  bells           $::c6
        makeText $w t_HN Noon            $::c6

        makeText $w t_+1 and             $::a7
        makeText $w t_gx ten             $::b7
        makeText $w t_gF fifteen         $::c7

        makeText $w t_gz twenty          $::a8
        makeText $w t_gv five            $::b8
        makeText $w t_gM minutes         $::c8

        array set ::sTab {
                w0  {t_w0 t_gW}
                w1  {t_w1 t_gW}
                w2  {t_w2 t_gW}
                w3  {t_w3 t_gW}
                w4  {t_w4 t_gW}
                w5  {t_w5 t_gW}
                        0  {}
                        5  {t_+1 t_gv t_gM}
                10  {t_+1 t_gx t_gM}
                15  {t_+1 t_gF t_gM}
                20  {t_+1 t_gz t_gM}
                25  {t_+1 t_gv t_gz t_gM}
        }

        # Navy NavyBlue
        .c configure  -background MidnightBlue
}


proc start_SB2 w {
        puts {SB2: setup for international fuzzy ship's bell}
        # 3x8 panels: "Forenoon watch three bells and twenty five minutes"

        destroy $w;  pack [canvas $w  -width 515  -height 110  -background gray90]
        set ::scX 8
        if {$::pos < 0} {wm geom . +340+320}

        makeText $w t_gI {It is}         $::x1

        # 20:00
        makeText $w t_w5 First           $::x2

        # 00:00
        makeText $w t_w0 Middle          $::x3

        # 04:00
        makeText $w t_w1 Morning         $::x4

        # 08:00
        makeText $w t_w2 Forenoon        $::x5


        # 12:00
        makeText $w t_w3 Afternoon       $::x6

        # 16:00
        makeText $w t_w4 Dog             $::x7
        makeText $w t_gW watch           $::x8

        makeText $w t_g1 {one bell}      $::y1
        makeText $w t_g2 {two bells}     $::y2
        makeText $w t_g3 {three bells}   $::y3
        makeText $w t_g4 {four bells}    $::y4
        makeText $w t_g5 {five bells}    $::y5
        makeText $w t_g6 {six bells}     $::y6
        makeText $w t_g7 {seven bells}   $::y7
        makeText $w t_g8 {eight bells}   $::y8
        #makeText $w t_G bells           $::y8


        makeText $w t_Su Sunday          $::z1
        makeText $w t_HN Noon            $::z2

        makeText $w t_+1 and             $::z3
        makeText $w t_gx ten             $::z4
        makeText $w t_gF fifteen         $::z5
        makeText $w t_gz twenty          $::z6
        makeText $w t_gv five            $::z7
        makeText $w t_gM minutes         $::z8

        array set ::sTab {
                w0  {t_w0 t_gW}
                w1  {t_w1 t_gW}
                w2  {t_w2 t_gW}
                w3  {t_w3 t_gW}
                w4  {t_w4 t_gW}
                w5  {t_w5 t_gW}
                        0  {}
                        5  {t_+1 t_gv t_gM}
                10  {t_+1 t_gx t_gM}
                15  {t_+1 t_gF t_gM}
                20  {t_+1 t_gz t_gM}
                25  {t_+1 t_gv t_gz t_gM}
        }

        # MidnightBlue MediumBlue
        .c configure  -background NavyBlue
}


### Main:

wm title . "$Prog(Title) $Prog(Version)"
puts       "$Prog(Title) $Prog(Version)"

bind .  <F2>     {console show}
#catch {console show}
#catch {console hide}

# Defaults:

# Layout:  G:Glasen"=german shipclock / SB:ship's bell international
set fc DE5

# screen: -1:distribute the layouts on screen
set pos -1

# sound:   0:none  1:once on full hour  2: ship's bell
set sound  0

# time     0: current  1,2: test
set time   t0

# language: DE=germany  EN=english/international
set lang xx

# console: debug
set cons 0

# menu:    0:off  1:on
set menu 0
set test 0

if {$argc > 0} {
        gloabl $argv
        while {[llength $argv]} {
                set argv [lassign $argv[set argv {}] arg]
                swith $arg {
                        -p0 {
                                # don't set screen-position
                                set pos 0
                        }
                        -p1 {
                                # top left
                                set pos 1
                        }
                        -p2 {
                                # top right
                                set pos 2
                        }
                        -s0 {
                                # no sound
                                set sound 0
                        }
                        -s1 {
                                # once
                                set sound 1
                        }
                        -s2 {
                                # ship's bell / Glasen
                                set sound 2
                        }
                        -t0 {
                                # time - use current time
                                set time t0
                        }
                        -t1 {
                                # use time from proc t1
                                set time t1
                        }
                        -t2 {
                                set time t2
                        }
                        -m0 {
                                # no menu
                                set menu 0
                        }
                        -m1 {
                                set menu 1
                        }
                        -cS {
                                catch {console show}
                        }
                        -cH {
                                catch {console hide}
                        }
                         -test {
                                set test 1
                        }
                        default {
                                switch $arg {
                                        -* {
                                                error [list {bad option} $arg]
                                        }
                                        default {
                                                set fc $arg
                                        }
                                }
                        }
                }
        }

        if {[llength $argv]} {
                error [list {wrong # args}]
        }
}
puts "Args: fc,pos,sound,time: $fc $pos $sound $time"

if {$::menu == 1} initMenu
initKeys

switch $fc {
        1 - DE1 - DE {
                #DE1 : german fuzzyclock:   8x3  "fünf Minuten vor halb vier Uhr"
                start_DE1 .c
        }
        2 - DE2 {
                #DE2 : german fuzzyclock:        "drei Uhr fünf und zwanzig Minuten"
                start_DE2 .c
        } 3 - DE3 {
                #DE3 : german fuzzyclock:        "viertel nach drei"
                start_DE3 .c
        } 4 - DE4 {
                #DE4 : german fuzzyclock:        "viertel nach drei Uhr"
                start_DE4 .c
        } 5 - DE5 {
                #DE5 : german fuzzyclock:   5x5  ...
                start_DE5 .c
        } 6 - DE6 {
                #DE6 : german fuzzyclock:   6x4: "drei Uhr fünf und zwanzig Minuten"
                start_DE6 .c
        } 7 - DE7 {
                #DE7 : german fuzzyclock:   4x6: "drei Uhr fünf und zwanzig Minuten"
                start_DE7 .c
        } 11 - I1 - i1 {
                #11: international fuzzyclock: "three o'clock twenty five minutes"
                start_I1 .c
        } 12 - I2 - i2 {
                #12: international fuzzyclock: "quarter past three o'clock"
                start_I2 .c
        } 51 - SB1 - SB {
                set fc SB1
                #S1 : international ship's bell: "Forenoon watch three bells and twenty five minutes"
                start_SB1 .c
        } 52 - SB2 {
                #S2 : int.nat. ship's bell/wide: "Forenoon watch three bells and twenty five minutes"
                start_SB2 .c
        } 61 - G1 - G {
                set fc {G1}
                #G1 : german shipclock1: 09:55 --> "zweite Tagwache drei Glasen und fünf und zwanzig Minuten"
                start_SG1 .c
        } 62 - G2 {
                #G2 : german shipclock2: 09:55 --> "zweite Tagwache drei Glasen und fünf und zwanzig Minuten"
                start_SG2 .c
        } else {
                puts "Selection invalid: '$fc', using default layout."
                set fc I2

                #12: international fuzzyclock: "quarter past three o'clock"
                start_I2 .c
        }
}


if {$::pos == 1} p1
if {$::pos == 2} p2

if {$test} {
} else {
        focus -f .c
        update

        help

        $time
        after 250
        u

        run2
}

### EOF ###
if 0 {

Output

FuzzyClock_i2 FuzzyClock_DE FuzzyClock_SB
International FuzzyClock #2 German FuzzyClock #2 Ship's bell

FuzzyClock_SB2
Ship's bell - wide layout

Remarks

if 0 {

A

MiHa 2015-02-24 - Some bugfixes for the minute-table, and improved wiki-formatting.

MiHa 2015-03-03 - I added two more versions for a german fuzzyclock "morgens viertel nach elf Uhr", meaning "quarter past eleven".

Rearranging the panels is much more easy to do now with the spreadsheet-addressing, then with the old list of coordinates.

To avoid adding another row of panels, the entries for "PM"/"evening" and "minutes" had to be dropped.

Some ideas for further programming:

  • change font of text in lit panels to be bold
  • ESC --> Quit
  • click on panel "it is" --> update clock
  • click on panels "one", "two" etc. --> change layout
  • click on panels "before"/"after" --> change color
  • catch resize-event, and resize panels and text
  • Color-Table (needs some concept)
  • F1 --> Help / Balloon-help when hovering over panels

To sum up the experience:

  • Tcl by itself is quite simple.
  • A demo/HelloWorld-program that shows every feature should be possible in about one printed page
  • Things to be aware of:
    • comments are commands, so quotes and braces inside need to be balanced
    • when to use / not use $ with variablenames ( set i 1; puts $i; incr i $i )
  • Tk is much bigger, and needs going to the docs quite often
  • The help-docs are not bad as such, but are very frustrating to use -->
    • here is still much room for improvement
  • IDE: Geany - code completion for tcl needs work

kpv: Also check out Word Clock for another textual clock.

MiHa: Yes - it has already been on the list, right before "Designers notes".

B

MiHa 2015-03-04: Now finally with an international fuzzyclock "quarter before/past".

MiHa 2015-03-05: I changed the coordinates and scale, to get finer grained text-positioning,
as well as adjustable columnwidth for each of the layouts.
Further, I gave each layout its very own position on the screen.

When starting, the program now looks at argv, and jrocesses the commandline-arguments.
That works both with tclsh and wish.

Currently implemented commandline-arguments to control layout, sound, placement on the screen, menu, and time:

  • -s0 -s1 -s2 : no sound / simple chime (beep) at the full hour / ship's bell every half hour.
    The default is no sound.
  • -p0 -p1 -p2 : no setting of screen-position / top left / top right.
    The default is to give each layout a unique position on screen.
  • -t0 -t1 -t2 : current time / time as set by proc t1, t2 etc.
    The default is the current time.
  • -m0 -m1 : no menu / show the menu.
    The default is no menu, unless the program is started without any arguments (i.e. "interactive", via doubleclick).
  • Everything else is understood as a key to select the layout.
    If not recognized, some default-layout is used.

Recognized are DE1,DE2 .. DE7 for the german clocks,
I1,I2 for the international clocks, and G1,G2, SB1,SB2 for the ship's bells.

With all that plumbing in place, it is now easy to show all the layouts at once, and compare them.
(Re-using my test-setup as a showcase:)

To see this in action, use batchfiles (for Windows) such as the following
to start one tcl-interpreter for each of the layouts:

start wish FuzzyClock.tcl DE1
start wish FuzzyClock.tcl DE2
start wish FuzzyClock.tcl DE3
start wish FuzzyClock.tcl DE4

start wish FuzzyClock.tcl DE5
start wish FuzzyClock.tcl DE6
start wish FuzzyClock.tcl DE7
start wish FuzzyClock.tcl DE8

start wish FuzzyClock.tcl I1
start wish FuzzyClock.tcl I2
start wish FuzzyClock.tcl I3

and

start wish FuzzyClock.tcl G1
start wish FuzzyClock.tcl G2

start wish FuzzyClock.tcl SB
start wish FuzzyClock.tcl SB2 -s2

That means, all these clocks are running with no sound, except for the one with -s2, and all the layouts get distributed to different places across the screen.

C

MiHa 2015-03-13: I have created layouts for ship's bell / "Glasenuhr", http://en.wikipedia.org/wiki/Ship%27s_bell / http://de.wikipedia.org/wiki/Glasenuhr , with both a german and an international version.

My international ship's bell uses the "simpler system" according to the wikipedia-page, that is, without the dogwatch split into two parts. Not being a sailor, that looks like the Standard merchant watch system to me.

To summarise the concept for the ship's clock:

  • In the days of sailing ships, they used hour-glasses for timing, one glass running 4 hours and another glass running for 30 minutes.
  • The turning of the glasses are signalled with the ship's bell.
  • The day is divided into "watches" (working shifts) that last 4 hours. The current watch is not announced with the bell - everyone on board has to know that it is day/night/afternoon etc.
  • Each watch is divided into half-hour periods, so each watch lasts "8 bells", i.e. it starts with "8 bells" ending the previous watch, gets to "1 bell" after half an hour, "2 bells" after one hour, etc., and ends with "8 bells" after 4 hours.

To bring those shipclocks to the same "fuzzy precision" as the other clocks, I added 5-minute "lights". But they wait for the exact time, and don't round up. That means, at 19:23 the fuzzy clocks would say "twenty five minutes", but the shipclocks would then still say "twenty minutes", and wait until reaching 19:25 to show "twenty five minutes".

Finally, I changed the "every" and "sync"-mechanism to use a more gentle approach to bring the screen-updates to occur on multiples of 10 seconds. The old coding made the program unresponsive during the first few seconds.

MiHa 2015-03-22 - New: "wide layouts" 3x8, used with the new ship's bells "G2" and "SB2".

If you find a bug, or have an idea for some original layout, let me know ! Otherwise, have fun !

D

MiHa 2015-04-16: Now also with layouts of size 4x6, 6x4 and 5x5, and options -t0 -t1 etc. to set a fixed time, eg. for testing, comparisons and screenshots. On the downside, all those layouts cannot be shown on one screen (of size 1024x768), so the ships bells have been split off. During the hour after midnight, the german clocks now show "zero o'clock". }

MiHa 2015-06-06: Now featuring a real menu, so you can switch between layouts while the program is running. Finding the nice, simple and very useful menu-creator m+ by RS was a happy by-product of my work on that GUI-demo Invoice-Demo.

MiHa 2015-06-16: New: a proper helptext (copied from Spider Solitaire, proc showRules).

MiHa 2015-06-19: New: the menu can now be switched off (to save screenspace), and on again with hotkey F3.

Next up: layouts with a 24h-clock.


}