# git-gui console support
# Copyright (C) 2006, 2007 Shawn Pearce

class console {

field t_short
field t_long
field w
field w_t
field console_cr
field is_toplevel    1; # are we our own window?

constructor new {short_title long_title} {
	set t_short $short_title
	set t_long $long_title
	_init $this
	return $this
}

constructor embed {path title} {
	set t_short {}
	set t_long $title
	set w $path
	set is_toplevel 0
	_init $this
	return $this
}

method _init {} {
	global M1B

	if {$is_toplevel} {
		make_toplevel top w -autodelete 0
		wm title $top "[appname] ([reponame]): $t_short"
	} else {
		frame $w
	}

	set console_cr 1.0
	set w_t $w.m.t

	frame $w.m
	label $w.m.l1 \
		-textvariable @t_long  \
		-anchor w \
		-justify left \
		-font font_uibold
	text $w_t \
		-background white -borderwidth 1 \
		-relief sunken \
		-width 80 -height 10 \
		-wrap none \
		-font font_diff \
		-state disabled \
		-xscrollcommand [cb _sb_set $w.m.sbx h] \
		-yscrollcommand [cb _sb_set $w.m.sby v]
	label $w.m.s -text [mc "Working... please wait..."] \
		-anchor w \
		-justify left \
		-font font_uibold
	pack $w.m.l1 -side top -fill x
	pack $w.m.s -side bottom -fill x
	pack $w_t -side left -fill both -expand 1
	pack $w.m -side top -fill both -expand 1 -padx 5 -pady 10

	menu $w.ctxm -tearoff 0
	$w.ctxm add command -label [mc "Copy"] \
		-command "tk_textCopy $w_t"
	$w.ctxm add command -label [mc "Select All"] \
		-command "focus $w_t;$w_t tag add sel 0.0 end"
	$w.ctxm add command -label [mc "Copy All"] \
		-command "
			$w_t tag add sel 0.0 end
			tk_textCopy $w_t
			$w_t tag remove sel 0.0 end
		"

	if {$is_toplevel} {
		button $w.ok -text [mc "Close"] \
			-state disabled \
			-command [list destroy $w]
		pack $w.ok -side bottom -anchor e -pady 10 -padx 10
		bind $w <Visibility> [list focus $w]
	}

	bind_button3 $w_t "tk_popup $w.ctxm %X %Y"
	bind $w_t <$M1B-Key-a> "$w_t tag add sel 0.0 end;break"
	bind $w_t <$M1B-Key-A> "$w_t tag add sel 0.0 end;break"
}

method exec {cmd {after {}}} {
	if {[lindex $cmd 0] eq {git}} {
		set fd_f [eval git_read --stderr [lrange $cmd 1 end]]
	} else {
		lappend cmd 2>@1
		set fd_f [_open_stdout_stderr $cmd]
	}
	fconfigure $fd_f -blocking 0 -translation binary
	fileevent $fd_f readable [cb _read $fd_f $after]
}

method _read {fd after} {
	set buf [read $fd]
	if {$buf ne {}} {
		if {![winfo exists $w_t]} {_init $this}
		$w_t conf -state normal
		set c 0
		set n [string length $buf]
		while {$c < $n} {
			set cr [string first "\r" $buf $c]
			set lf [string first "\n" $buf $c]
			if {$cr < 0} {set cr [expr {$n + 1}]}
			if {$lf < 0} {set lf [expr {$n + 1}]}

			if {$lf < $cr} {
				$w_t insert end [string range $buf $c $lf]
				set console_cr [$w_t index {end -1c}]
				set c $lf
				incr c
			} else {
				$w_t delete $console_cr end
				$w_t insert end "\n"
				$w_t insert end [string range $buf $c [expr {$cr - 1}]]
				set c $cr
				incr c
			}
		}
		$w_t conf -state disabled
		$w_t see end
	}

	fconfigure $fd -blocking 1
	if {[eof $fd]} {
		if {[catch {close $fd}]} {
			set ok 0
		} else {
			set ok 1
		}
		if {$after ne {}} {
			uplevel #0 $after $ok
		} else {
			done $this $ok
		}
		return
	}
	fconfigure $fd -blocking 0
}

method chain {cmdlist {ok 1}} {
	if {$ok} {
		if {[llength $cmdlist] == 0} {
			done $this $ok
			return
		}

		set cmd [lindex $cmdlist 0]
		set cmdlist [lrange $cmdlist 1 end]

		if {[lindex $cmd 0] eq {exec}} {
			exec $this \
				[lrange $cmd 1 end] \
				[cb chain $cmdlist]
		} else {
			uplevel #0 $cmd [cb chain $cmdlist]
		}
	} else {
		done $this $ok
	}
}

method insert {txt} {
	if {![winfo exists $w_t]} {_init $this}
	$w_t conf -state normal
	$w_t insert end "$txt\n"
	set console_cr [$w_t index {end -1c}]
	$w_t conf -state disabled
}

method done {ok} {
	if {$ok} {
		if {[winfo exists $w.m.s]} {
			bind $w.m.s <Destroy> [list delete_this $this]
			$w.m.s conf -background green -text [mc "Success"]
			if {$is_toplevel} {
				$w.ok conf -state normal
				focus $w.ok
			}
		} else {
			delete_this
		}
	} else {
		if {![winfo exists $w.m.s]} {
			_init $this
		}
		bind $w.m.s <Destroy> [list delete_this $this]
		$w.m.s conf -background red -text [mc "Error: Command Failed"]
		if {$is_toplevel} {
			$w.ok conf -state normal
			focus $w.ok
		}
	}
}

method _sb_set {sb orient first last} {
	if {![winfo exists $sb]} {
		if {$first == $last || ($first == 0 && $last == 1)} return
		if {$orient eq {h}} {
			scrollbar $sb -orient h -command [list $w_t xview]
			pack $sb -fill x -side bottom -before $w_t
		} else {
			scrollbar $sb -orient v -command [list $w_t yview]
			pack $sb -fill y -side right -before $w_t
		}
	}
	$sb set $first $last
}

}
