# 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 use_ttk NS

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

	${NS}::label $w.header -text [mc "Create New Branch"] \
		-font font_uibold -anchor center
	pack $w.header -side top -fill x

	${NS}::frame $w.buttons
	${NS}::button $w.buttons.create -text [mc Create] \
		-default active \
		-command [cb _create]
	pack $w.buttons.create -side right
	${NS}::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

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

	${NS}::radiobutton $w.desc.match_r \
		-text [mc "Match Tracking Branch Name"] \
		-value match \
		-variable @name_type
	if {!$use_ttk} {$w.desc.match_r configure -anchor w}
	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

	${NS}::labelframe $w.options -text [mc Options]

	${NS}::frame $w.options.merge
	${NS}::label $w.options.merge.l -text [mc "Update Existing Branch:"]
	pack $w.options.merge.l -side left
	${NS}::radiobutton $w.options.merge.no \
		-text [mc No] \
		-value none \
		-variable @opt_merge
	pack $w.options.merge.no -side left
	${NS}::radiobutton $w.options.merge.ff \
		-text [mc "Fast Forward Only"] \
		-value ff \
		-variable @opt_merge
	pack $w.options.merge.ff -side left
	${NS}::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

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

	${NS}::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
	wm deiconify $w
	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 {$spec ne {}} {
		$co remote_source $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
	}
}

}
