if {![info exists tkappbar(cyclesleep)]} {set tkappbar(cyclesleep) 5}
if {![info exists tkappbar(cyclestep)]} {set tkappbar(cyclestep) 5}
if {![info exists tkappbar(cyclestyle)]} {set tkappbar(cyclestyle) trail:-20}

set tkappbar(onSource,cycle_colors) {
	global tkappbar
	.f.main.m0 insert $tkappbar(mmenu_insert) command -label "Stop Color Cycling" -command normalcol -state disabled -foreground $tkappbar(fgcolor)
	set tkappbar(cycle_colors,stop) $tkappbar(mmenu_insert)
	incr tkappbar(mmenu_insert)
	.f.main.m0 insert $tkappbar(mmenu_insert) command -label "Start Color Cycling" -command psychecol -foreground $tkappbar(fgcolor)
	set tkappbar(cycle_colors,start) $tkappbar(mmenu_insert)
	incr tkappbar(mmenu_insert)
	.f.main.m0 insert $tkappbar(mmenu_insert) separator
	incr tkappbar(mmenu_insert)
}

proc normalcol {} {
	global tkappbar
	.f.main.m0 entryconfigure $tkappbar(cycle_colors,stop) -state disabled
	.f.main.m0 entryconfigure $tkappbar(cycle_colors,start) -state normal
	set tkappbar(cycleok) 0
	# unpatch Enter/Leave routines
	foreach j [winfo children .f] {
		set callback [bind $j <<Enter_p>>]
		bind $j <Enter> $callback
		event delete <<Enter_p>> <Enter>
		set callback [bind $j <<Leave_p>>]
		bind $j <Leave> $callback
		event delete <<Leave_p>> <Leave>
	}
	foreach i [after info] {
		if {[regexp "color_loop" [after info $i]]} {
			after cancel $i
		}
	}
	foreach j [winfo children .f] {
		catch {$j configure -background $tkappbar(bgcolor)}
		catch {$j configure -activebackground $tkappbar(abgcolor)}
	}
	catch {.f.main configure -image tkappbar(images,0)}
	if {[info exists tkappbar(colorlist)]} {unset tkappbar(colorlist)}
}

proc invertcol {obj} {
	# this rolls the color immediately for slow update loops
	set ccol [lindex [$obj configure -background] 4]
	regsub "#" $ccol 0x hccol
	set invcol [format %06x [expr (0xffffff-$hccol)%0xffffff]]
	$obj configure -background #$invcol
}

proc buildColorList {} {
	global tkappbar
	set base ff0000
	set tkappbar(colorlist) {}
	for {set i 1} {$i<256} {incr i $tkappbar(cyclestep)} {
		lappend tkappbar(colorlist) #$base
		set base [format %06x [expr 0x$base + (0x100 * $tkappbar(cyclestep))]]
	}
	set base ffff00
	for {set i 1} {$i<256} {incr i $tkappbar(cyclestep)} {
		set base [format %06x [expr 0x$base - (0x10000 * $tkappbar(cyclestep))]]
		lappend tkappbar(colorlist) #$base
	}
	set base 00ff00
	for {set i 1} {$i<256} {incr i $tkappbar(cyclestep)} {
		lappend tkappbar(colorlist) #$base
		set base [format %06x [expr 0x$base + (0x1 * $tkappbar(cyclestep))]]
	}
	set base 00ffff
	for {set i 1} {$i<256} {incr i $tkappbar(cyclestep)} {
		lappend tkappbar(colorlist) #$base
		set base [format %06x [expr 0x$base - (0x100 * $tkappbar(cyclestep))]]
	}
	set base 0000ff
	for {set i 1} {$i<256} {incr i $tkappbar(cyclestep)} {
		lappend tkappbar(colorlist) #$base
		set base [format %06x [expr 0x$base + (0x10000 * $tkappbar(cyclestep))]]
	}
	set base ff00ff
	for {set i 1} {$i<256} {incr i $tkappbar(cyclestep)} {
		lappend tkappbar(colorlist) #$base
		set base [format %06x [expr 0x$base - (0x1 * $tkappbar(cyclestep))]]
	}
}

proc createImgArray {} {
	global tkappbar
	set dim $tkappbar(pixl)
	foreach i [array names tkappbar psychimg,*] {
		image delete $tkappbar($i)
		unset tkappbar($i)
	}
	for {set i 0} {$i<$dim} {incr i} {
		set tkappbar(psychimg,$i) [image create photo]
		set imagel {}
		for {set x 0} {$x<$dim} {incr x} {
			set row {}
			for {set y 0} {$y<$dim} {incr y} {
				set h0 [expr round(((256.0/$dim)*$y*$x))%256]
				# use in conjunction with curved green band below to get
				# a bouncy band of variant colour:
				#set h0 [expr round(((256.0/$dim)*$y*$x))%256]
				
				# horizontal green band:
				#set h1 [expr round(((256.0/$dim)*$x))%256]
				# vertical green band:
				#set h1 [expr round(((256.0/$dim)*$y))%256]
				# black & white with phased green:
				set h1 [expr round(((256.0/$dim)*$x*$y))%256]
				# curved green band:
				#set h1 [expr round(((256.0/$dim)*sqrt($x*$y)))%256]

				# bright/dim interlaced:
				set h00 [expr round($h0 - ((512.0/$dim)*$i))]
				if {$h00<0} {set h00 [expr -$h00]}
				if {$h00>255} {set h00 [expr 511-$h00]}
				# bright on bright:
				#set h00 [expr round($h0 + ((512.0/$dim)*$i))]
				#if {$h00>255} {set h00 [expr 511-$h00]}
				#if {$h00<0} {set h00 [expr -$h00]}
				set h0 $h00
				
				set h11 [expr round($h1 + ((512.0/$dim)*$i))]
				if {$h11>255} {set h11 [expr 511-$h11]}
				if {$h11<0} {set h11 [expr -$h11]}
				# this can be used to make it black & white:
				#set h11 [expr round($h1 - ((512.0/$dim)*$i))]
				#if {$h11<0} {set h11 [expr -$h11]}
				#if {$h11>255} {set h11 [expr 511-$h11]}
				set h1 $h11
			
				lappend row [join [list #\
					[format %02x $h0]\
					[format %02x $h1]\
					[format %02x $h0]] ""]
			}
			lappend imagel $row
		}
		$tkappbar(psychimg,$i) put $imagel -to 0 0
	}
}

proc psychecol {} {
	global tkappbar
	.f.main.m0 entryconfigure $tkappbar(cycle_colors,stop) -state normal
	.f.main.m0 entryconfigure $tkappbar(cycle_colors,start) -state disabled 
	set tkappbar(cycleok) 1
	set tkappbar(cycleptr) 0
	foreach i [after info] {
		if {[regexp "color_loop" [after info $i]]} {
			after cancel $i
		}
	}
	# build color list
	if {![info exists tkappbar(colorlist)]} {
		buildColorList
	}
	# build image array
	if {((![info exists tkappbar(psychimg,0)])||([llength [$tkappbar(psychimg,0) data]]!=$tkappbar(pixl)))} {
		createImgArray
	}
	
	# patch Enter/Leave routines
	if {[event info <<Enter_p>>]==""} {
		# save callbacks in virtual event
		event add <<Enter_p>> <Enter>
		event add <<Leave_p>> <Leave>
		foreach j [winfo children .f] {
			bind $j <<Enter_p>> [bind $j <Enter>]
			bind $j <<Leave_p>> [bind $j <Leave>]
		}
	}
	set tkappbar(hoverh) {}
	foreach j [winfo children .f] {
		set callback [bind $j <Enter>]
		set callback "set tkappbar(hoverh) $j; invertcol $j; $callback"
		regsub "(; \.\[\.a-zA-Z0-9_\]\{1,\} configure -background \[#0-9a-fA-F\]\{7\};)" $callback \; pcbfcn
		bind $j <Enter> $pcbfcn
		set callback [bind $j <Leave>]
		set callback "set tkappbar(hoverh) {}; $callback"
		regsub "(; \.\[\.a-zA-Z0-9_\]\{1,\} configure -background \[#0-9a-fA-F\]\{7\};)" $callback \; pcbfcn
		bind $j <Leave> $pcbfcn
	}

	after idle color_loop
}

proc color_loop {} {
	global tkappbar
	#set nbtn [llength [winfo children .f]]

	set cimg [string trimleft [lindex [.f.main configure -image] 4] image]
	if {[catch {set cimg [expr ($cimg+0) % $tkappbar(pixl)]}]} {set cimg 0}
	catch {.f.main configure -image $tkappbar(psychimg,$cimg)}
	
	set nbtn [expr [llength [winfo children .f]] - 1]
	switch -glob -- $tkappbar(cyclestyle) {
		same {
			foreach j [winfo children .f] {
				set bc [lindex $tkappbar(colorlist) $tkappbar(cycleptr)]
				catch {
					$j configure -background $bc
				}
				catch {
					$j configure -activebackground $bc
				}
			}
		}
		spaced {
			set oft [expr [llength $tkappbar(colorlist)]/$nbtn]
			set boft 0
			foreach j [winfo children .f] {
				set bcoft [expr ($tkappbar(cycleptr)+($boft*$oft)) % [llength $tkappbar(colorlist)]]
				set bc [lindex $tkappbar(colorlist) $bcoft]
				if {$j==$tkappbar(hoverh)} {
					regsub # $bc 0x bcc
					set bc #[format %06x [expr 0xffffff - $bcc]]
				}
				catch {$j configure -background $bc}
				catch {$j configure -activebackground $bc}
				incr boft
			}
		}
		trail* {
			set oft [lindex [split $tkappbar(cyclestyle) :] 1]
			set boft 0
			foreach j [winfo children .f] {
				set bcoft [expr ($tkappbar(cycleptr)+($boft*$oft)) % [llength $tkappbar(colorlist)]]
				set bc [lindex $tkappbar(colorlist) $bcoft]
				if {$j==$tkappbar(hoverh)} {
					regsub # $bc 0x bcc
					set bc #[format %06x [expr 0xffffff - $bcc]]
				}
				catch {$j configure -background $bc}
				catch {$j configure -activebackground $bc}
				incr boft
			}
		}
	}
	incr tkappbar(cycleptr)
	if {$tkappbar(cycleptr)>=[llength $tkappbar(colorlist)]} {
		set tkappbar(cycleptr) 0
	}
	if {$tkappbar(cycleok)} {
		after $tkappbar(cyclesleep) color_loop
	}
}

set tkappbar(onExit,cycle_colors) {normalcol}
