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

class branch_create {

field w              ; # widget path
field w_rev          ; # mega-widget to pick the initial revision
field w_name         ; # new branch name widget

field name         {}; # name of the branch the user has chosen
field name_type  user; # type of branch name to use

field opt_merge    ff; # type of merge to apply to existing branch
field opt_checkout  1; # automatically checkout the new branch?
field opt_fetch     1; # refetch tracking branch if used?
field reset_ok      0; # did the user agree to reset?

constructor dialog {} {
	global repo_config

	make_toplevel top w
	wm title $top [append "[appname] ([reponame]): " [mc "Create Branch"]]
	if {$top ne {.}} {
		wm geometry $top "+[winfo rootx .]+[winfo rooty .]"
	}

	label $w.header -text [mc "Create New Branch"] -font font_uibold
	pack $w.header -side top -fill x

	frame $w.buttons
	button $w.buttons.create -text [mc Create] \
		-default active \
		-command [cb _create]
	pack $w.buttons.create -side right
	button $w.buttons.cancel -text [mc Cancel] \
		-command [list destroy $w]
	pack $w.buttons.cancel -side right -padx 5
	pack $w.buttons -side bottom -fill x -pady 10 -padx 10

	labelframe $w.desc -text [mc "Branch Name"]
	radiobutton $w.desc.name_r \
		-anchor w \
		-text [mc "Name:"] \
		-value user \
		-variable @name_type
	set w_name $w.desc.name_t
	entry $w_name \
		-borderwidth 1 \
		-relief sunken \
		-width 40 \
		-textvariable @name \
		-validate key \
		-validatecommand [cb _validate %d %S]
	grid $w.desc.name_r $w_name -sticky we -padx {0 5}

	radiobutton $w.desc.match_r \
		-anchor w \
		-text [mc "Match Tracking Branch Name"] \
		-value match \
		-variable @name_type
	grid $w.desc.match_r -sticky we -padx {0 5} -columnspan 2

	grid columnconfigure $w.desc 1 -weight 1
	pack $w.desc -anchor nw -fill x -pady 5 -padx 5

	set w_rev [::choose_rev::new $w.rev [mc "Starting Revision"]]
	pack $w.rev -anchor nw -fill both -expand 1 -pady 5 -padx 5

	labelframe $w.options -text [mc Options]

	frame $w.options.merge
	label $w.options.merge.l -text [mc "Update Existing Branch:"]
	pack $w.options.merge.l -side left
	radiobutton $w.options.merge.no \
		-text [mc No] \
		-value none \
		-variable @opt_merge
	pack $w.options.merge.no -side left
	radiobutton $w.options.merge.ff \
		-text [mc "Fast Forward Only"] \
		-value ff \
		-variable @opt_merge
	pack $w.options.merge.ff -side left
	radiobutton $w.options.merge.reset \
		-text [mc Reset] \
		-value reset \
		-variable @opt_merge
	pack $w.options.merge.reset -side left
	pack $w.options.merge -anchor nw

	checkbutton $w.options.fetch \
		-text [mc "Fetch Tracking Branch"] \
		-variable @opt_fetch
	pack $w.options.fetch -anchor nw

	checkbutton $w.options.checkout \
		-text [mc "Checkout After Creation"] \
		-variable @opt_checkout
	pack $w.options.checkout -anchor nw
	pack $w.options -anchor nw -fill x -pady 5 -padx 5

	trace add variable @name_type write [cb _select]

	set name $repo_config(gui.newbranchtemplate)
	if {[is_config_true gui.matchtrackingbranch]} {
		set name_type match
	}

	bind $w <Visibility> [cb _visible]
	bind $w <Key-Escape> [list destroy $w]
	bind $w <Key-Return> [cb _create]\;break
	tkwait window $w
}

method _create {} {
	global repo_config
	global M1B

	set spec [$w_rev get_tracking_branch]
	switch -- $name_type {
	user {
		set newbranch $name
	}
	match {
		if {$spec eq {}} {
			tk_messageBox \
				-icon error \
				-type ok \
				-title [wm title $w] \
				-parent $w \
				-message [mc "Please select a tracking branch."]
			return
		}
		if {![regsub ^refs/heads/ [lindex $spec 2] {} newbranch]} {
			tk_messageBox \
				-icon error \
				-type ok \
				-title [wm title $w] \
				-parent $w \
				-message [mc "Tracking branch %s is not a branch in the remote repository." [$w get]]
			return
		}
	}
	}

	if {$newbranch eq {}
		|| $newbranch eq $repo_config(gui.newbranchtemplate)} {
		tk_messageBox \
			-icon error \
			-type ok \
			-title [wm title $w] \
			-parent $w \
			-message [mc "Please supply a branch name."]
		focus $w_name
		return
	}

	if {[catch {git check-ref-format "heads/$newbranch"}]} {
		tk_messageBox \
			-icon error \
			-type ok \
			-title [wm title $w] \
			-parent $w \
			-message [mc "'%s' is not an acceptable branch name." $newbranch]
		focus $w_name
		return
	}

	if {$spec ne {} && $opt_fetch} {
		set new {}
	} elseif {[catch {set new [$w_rev commit_or_die]}]} {
		return
	}

	set co [::checkout_op::new \
		[$w_rev get] \
		$new \
		refs/heads/$newbranch]
	$co parent $w
	$co enable_create   1
	$co enable_merge    $opt_merge
	$co enable_checkout $opt_checkout
	if {$spec ne {} && $opt_fetch} {
		$co enable_fetch $spec
	}

	if {[$co run]} {
		destroy $w
	} else {
		focus $w_name
	}
}

method _validate {d S} {
	if {$d == 1} {
		if {[regexp {[~^:?*\[\0- ]} $S]} {
			return 0
		}
		if {[string length $S] > 0} {
			set name_type user
		}
	}
	return 1
}

method _select {args} {
	if {$name_type eq {match}} {
		$w_rev pick_tracking_branch
	}
}

method _visible {} {
	grab $w
	if {$name_type eq {user}} {
		$w_name icursor end
		focus $w_name
	}
}

}
