proc connectByTab {field1 field2 args} {
    set code [lambda {entry} {
	focus -force $entry
    }]
    bind $field1 <Tab> [list $code $field2]
    bind $field1 <Tab> +break
    bind $field2 <Shift-Tab> [list $code $field1]
    bind $field2 <Shift-Tab> +break
    if {[llength $args] > 0} {
	eval connectByTab $field2 $args
    }
}

proc dinbrief {} {
    grid\
	[label .addresslabel -text Absender]\
	[scrolledrichtext .address -height 3 -width 25]\
	[label .phonelabel -text Telefon]\
	[entry .phone]\
	-sticky ne
    connectByTab .address .phone
    grid ^ ^\
	[label .placelabel -text Ort]\
	[entry .place]\
	-sticky se
    grid ^ ^\
	[label .datelabel -text Datum]\
	[entry .date]\
	-sticky se
    grid \
	[label .backaddresslabel -text Absenderzeile]\
	[entry .backaddress] - -\
	-sticky ne
    grid\
	[label .tolabel -text Empfänger]\
	[scrolledrichtext .to -height 4 -width 25]\
	[label .signlabel -text Zeichen]\
	[entry .sign]\
	-sticky ne
    connectByTab .backaddress .to .sign
    grid ^ ^\
	[label .writerlabel -text Sachbearbeiter]\
	[entry .writer]\
	-sticky ne
    grid ^ ^\
	[label .yourmaillabel -text {Ihr Zeichen}]\
	[entry .yourmail]\
	-sticky se
    grid\
	[label .subjectlabel -text Betreff]\
	[entry .subject] - -\
	-sticky ne
    grid\
	[label .openinglabel -text Anrede]\
	[entry .opening] - -\
	-sticky ne
    grid [scrolledrichtext .maintext -width 40 -height 10] - - - -sticky news
    grid rowconfigure . 9 -weight 1
    grid\
	[label .closinglabel -text Grußformel]\
	[entry .closing]\
	[label .pslabel -text PS]\
	[scrolledrichtext .ps -width 40 -height 4]\
	-sticky ne
    grid\
	[label .signaturelabel -text Unterschrift]\
	[entry .signature] ^ ^\
	-sticky ne
    grid\
	[label .cclabel -text {Kopie an}]\
	[entry .cc] ^ ^\
	-sticky ne
    grid\
	[label .encllabel -text Anlage]\
	[entry .encl] ^ ^\
	-sticky ne
    grid\
	[label .bottomtextlabel -text Gesellschaft]\
	[scrolledtext .bottomtext -height 2] - -\
	-sticky ne
    label .searchStringLabel -text Suche
    label .searchString -textvariable ::searchText::searchString -relief sunken
    grid configure .bottomtext -sticky news
    grid columnconfigure . 3 -weight 1
    grid configure\
	.address .backaddress .to .yourmail .writer .sign\
	.phone .place .date .subject .opening .maintext\
	.closing .signature .cc .encl .ps .bottomtext\
	-sticky news
    .maintext tag configure tab -wrap none
    focus .maintext.text
    bind .maintext.text <Key> "after idle {checkTabEvent .maintext}"
    bind .maintext.text <<Undo>> "after idle {initTabTags .maintext}"
    bind .maintext.text <<Redo>> "after idle {initTabTags .maintext}"
    bind .maintext.text <<Change>> "after idle {initTabTags .maintext}"
    bind .maintext.text <F3> {searchMode .maintext}
    bind .maintext.text <FocusIn> {
	switchMenuEdit normal 0 1 2 4 5 7 8 9
	break
    }
}

proc entry2macro {name {default {}}} {
    set field .[string tolower $name]
    set macro \\$name
    set contents ""
    switch [winfo class $field] {
	Text - Scrolledtext - Richtext - Scrolledrichtext {
	    set contents [hyphenated [unicode2tex [$field get 1.0 end-1chars]]]
	}
	Entry {
	    set contents [hyphenated [unicode2tex [$field get]]]
	}
    }
    if {$contents ne ""} {
	set result \n$macro
	append result \{ $contents \} \n
    } elseif {$default ne ""} {
	set result \n$macro
	append result \{ $default \} \n
    }
}

proc formular2tex {} {
    global documentPrefix
    set result [string trim $documentPrefix]
    if {[file exists preamble.inc.tex]} {
	append result \n [cat preamble.inc.tex] \n
    }
    append result \\usepackage\[ [globalSetting language] \] \{ babel \}
    append result \n\
 	[globalSetting verticalAddressAlign] \n\
	[globalSetting addressRules] \n\
	[globalSetting backAddressRules] \n\
	[globalSetting paperFoldMarks] \n\
	[globalSetting addressPos] \n
    if { "[.yourmail get][.sign get][.writer get]" ne ""} {
	set refLineGiven 1
	set refLineDefault \\mbox{}
    } else {
	set refLineGiven 0
	set refLineDefault ""
    }
    foreach field {
	address backaddress place date subject signature bottomtext
    } {
	append result [entry2macro $field]
    }
    foreach field {
	yourmail writer sign
    } {
	append result [entry2macro $field $refLineDefault]
    }
    set phoneFrags [split [.phone get] " /-"]
    set phone0 [lindex $phoneFrags 0]
    set phoneRest [join [lrange $phoneFrags 1 end] -]
    append result \\phone\
	\{ [unicode2tex $phone0] \}\
	\{ [unicode2tex $phoneRest] \}
    #
    append result \n\
	"\\begin{document}\n"\
	"\\begin{letter}"\
	\{ [unicode2tex [.to get 1.0 end-1chars]] \}
    if {[file exists document.inc.tex]} {
	append result \n [cat document.inc.tex] \n
    }
    if {$refLineGiven && [globalSetting refLineOverFold]} {
	# append result \n \\setupperfoldmarkvpos{108mm}
	switch [globalSetting addressPos] {
	    \\addresshigh {
		append result \n \\setreflinetop{78.5mm}
	    }
	    default {
		append result \n \\setreflinetop{96.5mm}
	    }
	}
    }
    append result \n\
	[entry2macro opening]\
	[plaintext2tex [.maintext get 1.0 end]]\
	[entry2macro closing]\
	[entry2macro ps]\
	[entry2macro cc]\
	[entry2macro encl]\
	"\n\n\\end{letter}\n\\end{document}"
}

proc getContents {} {
    set result {}
    foreach entry [winfo children .] {
	switch [winfo class $entry] {
	    Text - Scrolledtext - Richtext - Scrolledrichtext {
		lappend result $entry\
		    [unicode2asciiEncoded [$entry get 1.0 end-1chars]]
	    }
	    Entry {
		lappend result $entry [unicode2asciiEncoded [$entry get]]
	    }
	}
    }
    # return this value
    set result
}

proc saveContents {file} {
    saveString [getContents] $file
}

proc putContents {contents} {
    foreach {entry rawValue} $contents {
	set value [subst -nocommand -novariable $rawValue]
	switch [winfo class $entry] {
	    Entry {
		$entry delete 0 end
		$entry insert end $value
	    }
	    Text - Scrolledtext - Richtext - Scrolledrichtext {
		$entry delete 1.0 end
		$entry insert end $value
	    }
	}
    }
}

proc loadContents {file} {
    putContents [cat $file]
}

proc setFontSize n {
    globalSetting fontSize $n
    foreach child [winfo children .] {
	switch [winfo class $child] {
	    Label - Entry - Text - Richtext - Scrolledtext - Scrolledrichtext {
		$child configure -font "Helvetica $n"
	    }
	}
    }
    option add *Text.font [list Helvetica $n]
}
