# Copyright (c) 2000, Red Hat, Inc.
# 
# This file is part of Source-Navigator.
# 
# Source-Navigator is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as published
# by the Free Software Foundation; either version 2, or (at your option)
# any later version.
# 
# Source-Navigator is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
# 
# You should have received a copy of the GNU General Public License along
# with Source-Navigator; see the file COPYING.  If not, write to
# the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
# MA 02111-1307, USA.
# 
##
## tmeter.tcl
##
## Implements termometers used in SN to show progress.


## by batch mode, display the files to the standard
## output
proc display_scale_window {sc line} {
	global tcl_platform
	if {[winfo exists $sc]} {
		global sn_progress_value
		$sc.i.filename config -text $line
		incr sn_progress_value
		
		if {$tcl_platform(platform) == "windows"} {
			update idletasks
			update idletasks
		}
		update idletasks
	} elseif {[sn_batch_mode]} {
		puts stdout [format [get_indep String ScanningFile] $line]
		flush stdout
	}
}

proc delete_scale_window {wdg} {
	global sn_scale_oldfocus
    catch {$wdg delete}
    catch {destroy $wdg}
    
    #restore old focus
    if {[info exists sn_scale_oldfocus] && [winfo exists $sn_scale_oldfocus]} {
    	take_focus \
			[winfo toplevel $sn_scale_oldfocus] \
			$sn_scale_oldfocus
    }
}

proc make_scale_window {filenum {enable_cancel 0}} {
	global sn_options
	global sn_progress_value
	global sn_scale_oldfocus
	
	if {[sn_batch_mode]} {
		return
	}
	
	set curs "watch"

	set sn_scale_oldfocus [focus]

	set t [Toplevel& [Toplevel& @@ next_window_name] -cursor $curs]
	$t withdraw
	$t on_close "$t.cancel invoke"
	$t title [get_indep String Scanning]

	frame $t.i
	catch {label $t.i.run -image cygnus_image -bg black}

	label $t.i.filename \
			-width 50 \
			-anchor w

	#use a normal termometer (not bad unix scaler)
	set sn_progress_value 0
	ProgressBar $t.scale \
			-maxvalue $filenum \
			-orientation horizontal \
			-showvalue 1 \
			-variable sn_progress_value

	button $t.cancel \
		-text [get_indep String Cancel] \
		-command "set ProcessingCancelled 2"

	catch {pack $t.i.run \
			-side left \
			-padx 2 \
			-pady 1 \
			-anchor w}
	pack $t.i.filename \
			-side left \
			-fill x \
			-anchor w \
			-padx 10 \
			-pady 20
	pack $t.i \
			-fill x \
			-anchor w

	pack $t.scale \
			-fill x \
			-padx 20 \
			-pady 20
	if {$enable_cancel} {
		pack $t.cancel -side top -pady 2
	}

	catch {$t resizable yes no}

	$t move_to_mouse	
	
	update idletasks
	set geom [split [lindex [split [$t geometry] "+"] 0] "x"]
	$t minsize [expr int([lindex $geom 0] / 3)] [lindex $geom 1]

	pack propagate $t.i 0
	$t.i.filename config -width 0

	catch {$t grab set}
	
	window_configure $t deiconify $t.scale
	
	return $t
}

############################################################
# Own Implementation of the ProgressBar
############################################################
itcl_class ProgressBar {
	constructor {{config ""}} {
		global sn_options
		
		set class [$this info class]
		@@rename $this $this-tmp-
		@@frame $this -class $class
		@@rename $this $this-win-
		@@rename $this-tmp- $this
		
		if {$maxvalue == 0} {
			set maxvalue 1
		}
		if {$variable == ""} {
			set variable $this-value
		}
		set canvas $this.canvas
		if {$labeltext != ""} {
			set labelw $this.label
		}
		
		global $variable
		catch {trace vdelete  $variable wu [list progress_trace_variable $this]}
		catch {trace variable $variable wu [list progress_trace_variable $this]}
		
		if {$labeltext != ""} {
			label $labelw -text $labeltext
			pack $labelw -side left
		}
		canvas $canvas \
			-highlightthickness 0 \
			-bd 1 \
			-relief ridge \
			-width $width \
			-height $height
		@@bind $canvas <Configure> [list $this resize %w %h]
		pack $canvas -side left -fill x -expand y
		
		$canvas create rect \
				-1 0 0 25 \
				-fill $indicatorcolor \
				-tags bar -outline {}
		$canvas create text 25 12 \
				-fill $foreground \
				-tags text \
				-font $sn_options(def,layout-font) \
				-anchor c
		$canvas xview moveto 0
		$canvas yview moveto 0
	}
	destructor {
		#delete the bound tracing script
		catch {trace vdelete $variable wu [list progress_trace_variable $this]}
	}
	method config {config} {
	}
	method tracevariable args {
		resize [winfo width $canvas] [winfo height $canvas]
	}
	method resize {W H} {
		upvar #0 $variable value
		
		#it can happen, that value isn't availiable yet.
		if {![info exists value]} {
			return
		}
		
		#steped display
		if {$displayed_value > 0 && \
			[expr $value - $displayed_value] < $step && \
			$displayed_value < $value} {
			return
		}
		#don't display values >100%
		if {$value > $maxvalue} {
			set maxvalue [expr {$value + 1}]
		}
		set pcnt [expr {$value/double($maxvalue)}]
		if {[string match "h*" $orientation]} {
			$canvas coords bar -1 0 [expr {int($pcnt*$W)}] $H
		} else {
			## Vertical orientation needs testing
			$canvas coords bar -1 $H $W [expr {int($pcnt*$H)}]
		}
		
		if {$showvalue} {
			$canvas coords text [expr {$W/2}] [expr {$H/2-2}]
			$canvas itemconfigure text \
				-text "$beforetext[expr int($pcnt*100.0)]$aftertext"
		} else {
			$canvas coords text $W $H
		}
		
		set displayed_value $value
		
		update idletasks
	}
	method bind args {
	    @@eval bind $canvas $args
	    @@eval bind $labelw $args
	}
	method balloon {txt} {
		balloon_bind_info $canvas $txt
		balloon_bind_info $labelw $txt
	}
	public value 1 {
		upvar #0 $variable var
		@@set var $value
	}
	public fromvalue 1
	public maxvalue 100 {
		if {$maxvalue == 0} {
			set maxvalue 1
		}
	}
	public labeltext "" {
		if {[winfo exists $labelw]} {
			$labelw config -text $labeltext
		}
	}
	protected displayed_value 0
	public beforetext ""
	public aftertext "%"
	public canvas ""
	public labelw ""
	public orientation "horizontal"
	public showvalue 1
	public height 24
	public width 100
	public foreground     "black"
	public indicatorcolor "#5ae6fe"
	public step 5
	public variable ""
}
proc progress_trace_variable {this name name2 op} {
	global $name
	if {[winfo exists $this]} {
		eval $this tracevariable $name $name2 $op
	} else {
		trace vdelete $name wu [list progress_trace_variable $this]
	}
}

###########################################################
## Procedures for displaying the loading window on startup.
###########################################################
proc hide_loading_message {{wdg ".loading"}} {
	catch {destroy $wdg}
	update idletasks
}

proc sn_loading_message {{str ""} {title ""} {first_interp 1} {hide_toplevel 0}} {
	global sn_options
	global sn_product_name
	global older_sn_loading_message_title
	global tcl_platform

	#interactive mode
	if {[sn_batch_mode]} {
		puts stdout $str
		return
	}
	
	if {$title == ""} {
		set title $sn_product_name
	}
	if {$str == ""} {
		set str [get_indep String Loading]
	}
	
	set w .loading
	
	if {![winfo exists $w]} {
		if {$hide_toplevel} {
			wm withdraw .
		}
		if {![info exists sn_options(def,layout-font)]} {
			init_some_font_attributes
		}
		set bg #c0c0c0
		set cursor "watch"
		
		#delete loading message window
		hide_loading_message
		
		#format
		# ---------------------
		#|     COPY-RIGHT      |
		#| IMAGE TEXT          |
		#| IMAGE               |
		#|                     |
		#|        Stop         |
		# ---------------------
		toplevel $w \
				-bg $bg
		wm transient $w .
		wm title $w $title
	
		frame $w.m -bg $bg
		pack $w.m -fill both -expand y
	
		if {$first_interp} {
			global cygnus_copyright
			label $w.m.copyr \
					-bg $bg \
					-fg black \
					-font $sn_options(def,layout-font) \
					-cursor $cursor \
					-anchor center \
					-text $cygnus_copyright
			pack $w.m.copyr -pady 5 -fill x -expand y -side top
		}
		
		catch {
		    label $w.m.img \
					-bg $bg \
					-cursor $cursor \
					-image cygnus_image \
					-anchor w
		    pack $w.m.img -padx 5 -pady 5 -side left -anchor w -side left
		}
		
		frame $w.m.cfr -bg $bg
		pack $w.m.cfr -side left -fill both -expand y -side left -pady 5
		
		set cmd [list label $w.m.cfr.lbl \
					-bg $bg \
					-cursor $cursor \
					-anchor w \
					-width 40\
					-font [list $sn_options(def,layout-font)] \
					-text [get_indep String Loading]]
		if {$sn_options(iscolor)} {
			lappend cmd -fg blue
		}
		eval $cmd
		pack $w.m.cfr.lbl \
					-side top \
					-fill x \
					-anchor w \
					-expand y
		
		button $w.btn \
				-bg $bg \
				-font $sn_options(def,layout-font) \
				-text [get_indep String Cancel] \
				-command "sn_loading_cancel" \
				-state disabled

		set x [expr [winfo screenwidth .] / 6 * 2]
		set y [expr [winfo screenheight .] / 6 * 2]
		wm geometry $w "+$x+$y"
		
		global sn_force_flag
		eval focus $sn_force_flag [focus -lastfor $w]
		#focus $img
		
		set older_sn_loading_message_title $title
	} else {
		raise $w
	}
	
	if {$older_sn_loading_message_title != $title} {
		wm title $w $title
		set older_sn_loading_message_title $title
	}
	
	catch {$w.m.cfr.lbl config -text $str}
	
	#wait to let the window be drawn (needed for windows)
	if {$tcl_platform(platform) == "windows"} {
		sn_wait 150
	}
	update idletasks
}
proc sn_loading_cancel {} {
	global SN_Loading_Cancel_Var
	if {! [info exists SN_Loading_Cancel_Var]} {
		return
	}
	upvar #0 $SN_Loading_Cancel_Var var
	set var cancel
}
proc sn_loading_enable_cancel {var} {
	global SN_Loading_Cancel_Var
	set SN_Loading_Cancel_Var $var
	pack .loading.btn -pady 5 -side bottom -anchor c
	.loading.btn config -state normal
	grab set .loading
}

proc sn_loading_disable_cancel {} {
	global SN_Loading_Cancel_Var
	set SN_Loading_Cancel_Var ""
	.loading.btn config -state disabled
	pack forget .loading.btn
	grab release .loading
}

proc sn_wait {{msec 10}} {
	global sn_str_wait
	update idletasks
	set sn_str_wait nomore
	after $msec "set sn_str_wait nomore"
	#make sure that 'tkwait' terminates!
	after [expr {$msec + 2000}] "set sn_str_wait nomore"
	tkwait variable sn_str_wait
	catch {unset sn_str_wait}
	update idletasks
}


