#! /bin/sh
# the next line restarts using tixwish \
exec wish4.0 "$0" "$@"

set enable(--enable-tk40) {
    {
	TK 4.0/TCL 7.4
    }
    {
	If this option is selected, it will generate a copy of the Tix
	library that uses Tcl 7.4 and Tk 4.0. The compiled binary can be
	found in the "unix-tk4.0" directory.
    }
    {
	yes
    }
}
set enable(--enable-et40) {
    {
	ET/TK 4.0/TCL 7.4
    }
    {
	If this option is selected, it will generate a copy of the Tix
	library that uses Embedded TK with Tcl 7.5 and Tk 4.1.  The
	compiled binary can be found in the "unix-et-tk4.0" directory.
    }
    {
	no
    }
}
set enable(--enable-itcl20) {
    {
	ITcl 2.0/TK 4.0/TCL 7.4
    }
    {
	If this option is selected, it will generate a copy of the Tix
	library that uses [incr tcl] version 2.0 with Tcl 7.5 and Tk 4.1.
	The compiled binary can be
	found in the "unix-itcl2.0" directory.
    }
    {
	no
    }
}
set enable(--enable-tk41) {
    {
	TK 4.1/TCL 7.5
    }
    {
	If this option is selected, it will generate a copy of the Tix
	library that uses Tcl 7.5 and Tk 4.1. The compiled binary can be
	found in the "unix-tk4.1" directory.
    }
    {
	no
    }
}
set enable(--enable-tk41_dso) {
    {
	Dynamic Library
    }
    {
	If this option is selected, it will generate a dynamic library
	(usually libtix.so) so that you can dynamically load Tix into
	wish (Tcl 7.5/Tk 4.1). The compiled dynamic library can be
	found in the "unix-tk4.1" directory.
    }
    {
	no
    }
}
set enable(--enable-cdemos) {
    {
	C Demo Programs
    }
    {
	If this option is selected, it will generate a program that
	demonstrates how to use the Tix widgets in C code.  The
	compiled binary can be found in the "demos-c" directory.
    }
    {
	yes
    }
}
set enable(--enable-debug) {
    {
	Debug Infomation
    }
    {
	If this option is selected, 
	the Tix library will be compiled with the -g flag.
    }
    {
	no
    }
}
set with(--with-tcl74_src_dir) {
    {
	TCL 7.4 source directory
    }
    {
	The absolute pathname of the TCL 7.4 source directory. 
	For example: ../tcl7.4
	If left blank, the pathname will be automatically determined.
    }
    {}
}
set with(--with-tcl75_src_dir) {
    {
	TCL 7.5 source directory
    }
    {
	The absolute pathname of the TCL 7.5 source directory. 
	For example: ../tcl7.5
	If left blank, the pathname will be automatically determined.
    }
    {}
}
set with(--with-tk40_src_dir) {
    {
	TK 4.0 source directory
    }
    {
	The absolute pathname of the TK 4.0 source directory. 
	For example: ../tk4.0
	If left blank, the pathname will be automatically determined.
    }
}
set with(--with-tk41_src_dir) {
    {
	TK 4.1 source directory
    }
    {
	The absolute pathname of the TK 4.1 source directory. 
	For example: ../tk4.1
	If left blank, the pathname will be automatically determined.
    }
    {}
}
set with(--with-itcl20_src_dir) {
    {
	ITCL 2.0 source directory
    }
    {
	The absolute pathname of the ITCL 2.0 source directory. 
	For example: ../itcl2.0
	If left blank, the pathname will be automatically determined.
    }
    {}
}
set with(--with-extra_cflags) {
    {
	Extra Compilation Flags
    }
    {
	Extra compilation flags, if they are needed, to passed to the
	compiler. For example, -Wall.
    }
    {}
}
set with(--with-extra_ldflags) {
    {
	Extra Linkage Flags
    }
    {
	Extra linkage flags, if they are needed, to passed to the
	linker. For example, -static.
    }
    {}
}
set with(--with-cc) {
    {
	C Compiler
    }
    {
	The absolute pathname of C Compiler you prefer. For example,
	/usr/bin/gcc. If left blank, the compiler will be automatically
	determined.
    }
    {}
}
set with(--prefix) {
    {
	Installation Prefix
    }
    {
	The top-level directory to install machine-independent files such
	as scripts. The default value is /usr/local.
    }
    {
	/usr/local
    }
}
set with(--exec-prefix) {
    {
	Executable Installation Prefix
    }
    {
	The top-level directories in which to install architecture-
	specific files. The default value is /usr/local.
    }
    {
	/usr/local
    }
}
set with(--x-includes) {
    {
	X Include Files Directory
    }
    {
	The directory where the X include files are located. For
	example, /usr/X386/include
	If left blank, the directory will be automatically determined.
    }
    {}
}
set with(--x-libraries) {
    {
	X Library Files Directory
    }
    {
	The directory where the X library files are located. For
	example, /usr/X386/lib
	If left blank, the directory will be automatically determined.
    }
    {}
}

proc SetHelp {} {
    global help

    # Some buttons
    #
    set help(sysdefault) {
	Use the default settings of the Tix package.
    }

    set help(userdefault) {
	Use the settings you chose last time when you ran the setup program.
    }

    set help(cancelbtn) {
	Cancel setup and go back to the main window.
    }

    set help(runconf) {
	Start the GNU configure with the options you have selected in
	this window. Several Makefiles will be created for you if GNU
	configure runs successfully.
    }
}

# application.
#
proc LoadOptions-Color {} {
    option clear
    option add *Font -*-helvetica-medium-r-normal-*-14-*-*-*-*-*-*-*
    option add *background lightgray
    option add *highlightBackground lightgray
    option add *Checkbutton.anchor w
    option add *Checkbutton.selectColor yellow
    option add *Checkbutton.highlightThickness 1
    option add *Label.font -*-helvetica-bold-r-normal-*-14-*-*-*-*-*-*-*
    option add *Entry.font -*-courier-medium-r-normal-*-14-*-*-*-*-*-*-*
    option add *Entry.background gray90
    option add *Scrollbar.borderWidth 1
    option add *Text.borderWidth 1

    foreach spec [. configure] {
	if {[llength $spec] > 2} {
	    set flag  [lindex $spec 0]
	    set name  [lindex $spec 1]
	    set class [lindex $spec 2]
	    set value [option get . $name $class]
	    catch {. config $flag $value}
	}
    }

    bind all <1> {
	catch {
	    if {[%W cget -highlightthickness] > 0 && 
		[%W cget -takefocus] != "0"} {
		focus %W
	    }
	}
    }
}

proc start {} {
    if {[winfo depth .] >= 8} {
	LoadOptions-Color
    }
    SetHelp
    wm withdraw .
    MakeScreen mainScreen
}

proc ScreenName {w name} {
    wm title [winfo toplevel $w] $name
}

set lastScreen {}

proc MakeScreen {screen} {
    global lastScreen scrInfo

    set w .$screen
    set scr $w.scr

    if {![winfo exists $w]} {
	toplevel $w

	if {$screen == "mainScreen"} {
	    wm protocol $w WM_DELETE_WINDOW exit
	    bind $w <Destroy> exit
	}

	frame $scr
	pack $scr -fill both -padx 5 -pady 5 -expand yes

	frame $w.help
	text $w.help.text -relief sunken -bd 1 -height 4 -width 55 \
	    -yscrollcommand  "$w.help.scb set" -state disabled -wrap word
	scrollbar $w.help.scb -orient vertical -relief sunken -bd 1 \
	    -command "$w.help.text yview" -takefocus 0
	pack $w.help.scb -side right -fill y
	pack $w.help.text -side right -expand yes -fill both
	pack $w.help -side bottom -fill both -padx 5 -pady 5

	Make_$screen $scr
    }
    after 100 raise $w
}

proc Make_mainScreen {w} {
    ScreenName $w "Welcome To The Tix Package"

    frame $w.f
    button $w.b1 -text "Read Copyright Statement" \
	-command "MakeScreen legalScreen"
    button $w.b2 -text "Read Tix FAQ" \
	-command "MakeScreen faqScreen"
    button $w.b3 -text "About The Tix Setup Program" \
	-command "MakeScreen aboutScreen"
    button $w.b4 -text "Set Up The Tix Package" \
	-command "MakeScreen setupScreen"
    button $w.b5 -text "Exit The Setup Program" \
	-command "exit"

    focus $w.b4
    pack $w.b1 $w.b2 $w.b3 $w.b4 $w.b5 -fill both -in $w.f
    pack $w.f -expand yes -padx 5 -pady 5
}

proc InfoScr {w name} {
    ScreenName $w $name

    frame $w.f1
    frame $w.f2
    text $w.f1.text -relief sunken -bd 1 -height 15 -width 80 -wrap none\
	-yscrollcommand  "$w.f1.scb set" \
	-xscrollcommand  "$w.f2.scb set" \
	-font -*-courier-medium-r-*-*-14-*-*-*-*-*-*-*
    scrollbar $w.f1.scb -orient vertical -relief sunken -bd 1 \
	-command "$w.f1.text yview" -takefocus 0
    pack $w.f1.scb -side right -fill y
    pack $w.f1.text -side right -expand yes -fill both 

    frame $w.f2.fx -width [winfo reqwidth $w.f1.scb]

    scrollbar $w.f2.scb -orient horizontal -relief sunken -bd 1 \
	-command "$w.f1.text xview" -takefocus 0
    pack $w.f2.fx -side right
    pack $w.f2.scb -side left -expand yes -fill both

    button $w.btn -text "<< Back To Main Menu" -command \
	"MakeScreen mainScreen"

    pack $w.btn -side bottom -anchor c
    pack $w.f2 -side bottom -fill x
    pack $w.f1 -side top -expand yes -fill both

    return $w.f1.text
}

proc Make_legalScreen {w} {
    set text [InfoScr $w "Tix Copyright Statement"]
    catch {
	$text insert end [exec cat docs/LEGAL.txt]
    }
}

proc Make_faqScreen {w} {
    set text [InfoScr $w "Tix Frequently Asked Questions"]
    catch {
	$text insert end [exec cat docs/FAQ.txt]
    }
}

proc Make_aboutScreen {w} {
    set text [InfoScr $w "About The Tix Setup Program"]

    $text configure -wrap word
    $text insert end {You can use this program to set up the Tix library. Please choose the "Set Up The Tix Package" button in the main menu to start.}
}


proc MkEntry {w text variable} {
    frame $w
    label $w.lab_1 -text $text \
	-font -*-helvetica-medium-r-normal-*-14-*-*-*-*-*-*-*
    entry $w.ent -textvariable $variable -width 30
    pack $w.lab_1 -side left
    pack $w.ent -side left -expand yes -fill both

    bind $w.ent <FocusIn> "HelpMessage $w $variable"

    return $w
}


proc HelpMessage {type option w} {
    upvar #0 $type data
    global help

    set text [winfo toplevel $w].help.text

    set newline [format %s \n]
    set tab [format %s \t]

    if [catch {
	set message [lindex $data($option) 1]
    }] {
	set message $help($option)
    }
    regsub -all "$tab"     $message " " message
    regsub -all "$newline" $message " " message
    regsub -all {[ ]+}     $message " " message
    regsub -all {^[ ]*}    $message {} message

    $text config -state normal
    $text delete 1.0 end
    $text insert end $message
    $text config -state disabled
}

proc Make_setupScreen {w} {
    global app

    ScreenName $w "Tix Setup"
    set f [frame $w.f]

    option add *setupScreen*lab_1.anchor e
    option add *setupScreen*lab_1.width  23
    option add *setupScreen*lab_2.anchor e
    option add *setupScreen*lab_2.width  15
    option add *setupScreen*lab_2.font   \
	-*-courier-medium-r-*-*-14-*-*-*-*-*-*-*

    # The Help Message Frame
    #
    set f0 [frame $f.f0 -bd 0]
    pack $f0 -side top -fill x -padx 4 -pady 10
    label $f0.m -text "Click on an item for explanation" -anchor c
    frame $f0.f -bd 1 -relief sunken -height 2 -width [winfo reqwidth $f0.m]
    pack $f0.m -expand yes -fill both
    pack $f0.f -anchor c

    # The Button Frame
    #
    set f2 [frame $f.f2]

    set b2 [button $f2.b2 -text "Set System Default" -command \
	"SetSysDefault"]

    set b0 [button $f2.b0 -text "Set User Default" -command \
	"SetUserDefault"]

    set b1 [button $f2.b1 -text "Cancel" -command\
	"MakeScreen mainScreen"]

    set b3 [button $f2.b3 -text "Run GNU configure .." \
	-command "RunConfigure"]

    bind $b2 <FocusIn> "HelpMessage {} sysdefault $w"
    bind $b0 <FocusIn> "HelpMessage {} userdefault $w"
    bind $b1 <FocusIn> "HelpMessage {} cancelbtn $w"
    bind $b3 <FocusIn> "HelpMessage {} runconf $w"

    pack $b2 $b0 -side top -fill x
    pack $b3 $b1 -side bottom -fill x
    pack $f2 -side right -fill y -padx 10

    # Toolkit compilation options
    #
    MkGroup $f "Tix Toolkit Compilation Options :"
    MkEnable $f --enable-debug

    # Compilation Target Options
    #
    MkGroup $f "Compilation Targets:"
    MkEnable $f --enable-tk40
    MkEnable $f --enable-tk41
    MkEnable $f --enable-tk41_dso
    MkEnable $f --enable-et40
    MkEnable $f --enable-itcl20
    MkEnable $f --enable-cdemos 

    # Source of Required Packages
    #
    MkGroup $f "Source of Required Packages:"
    MkWith $f --with-tcl74_src_dir
    MkWith $f --with-tcl75_src_dir
    MkWith $f --with-tk40_src_dir
    MkWith $f --with-tk41_src_dir
    MkWith $f --with-itcl20_src_dir

    # X Window Files
    #
    MkGroup $f "X Window Files:"
    MkWith $f --x-includes
    MkWith $f --x-libraries

    # Compiler Options
    #
    MkGroup $f "Compiler Options"
    MkWith $f --with-cc
    MkWith $f --with-extra_cflags
    MkWith $f --with-extra_ldflags


    # Installation Options
    #
    MkGroup $f "Installation Options"
    MkWith $f --prefix
    MkWith $f --exec-prefix

    # Done
    #
    pack $f -expand yes -anchor nw -fill x -padx 4

    SetUserDefault
}

proc GetCounter {f type} {
    global app

    if {![info exists app($type,$f)]} {
	set app($type,$f) 0
    }
    incr app($type,$f)

    return $type$app($type,$f)
}

proc GetSysDef {type option} {
    upvar #0 $type data

    return [Trim [lindex $data($option) 2]]
}

proc Trim {str} {
    regsub [format %s \n] $str "" str
    regsub [format %s \t] $str " " str
    set str [string trim $str]

    return $str
}

proc MkWith {f option} {
    global with var

    set c [GetCounter $f with]
    set text [Trim [lindex $with($option) 0]]
    set var($option) [GetSysDef with $option]

    set fc [frame $f.$c]
    set lab [label $fc.lab -text "$text: " \
	-font -*-helvetica-medium-r-normal-*-14-*-*-*-*-*-*-* -anchor e\
	-width 25]
    set ent [entry $fc.ent -textvariable var($option) -width 30]

    pack $lab -side left
    pack $ent -side right -expand yes -fill both

    pack $fc -anchor w -padx 15 -fill both
    bind $ent <FocusIn> "HelpMessage with $option $ent"
}

proc MkEnable {f option} {
    global enable var

    set c [GetCounter $f enable]
    set text [Trim [lindex $enable($option) 0]]
    set var($option) [GetSysDef enable $option]

    set btn [checkbutton $f.$c -text $text -variable var($option) \
	-onvalue yes -offvalue no]
    pack $btn -anchor w -padx 15

    bind $btn <FocusIn> "HelpMessage enable $option $btn"
}

proc MkGroup {f label} {
    global app

    if {![info exists app(groups,$f)]} {
	set app(groups,$f) 0
    }
    incr app(groups,$f)

    set lab [label $f.group$app(groups,$f) \
	-text $label -anchor w]
    pack $lab -side top -anchor w
}

proc SetSysDefault {} {
    global var enable with

    foreach n [array names enable] {
	set var($n) [Trim [lindex $enable($n) 2]]
    }
    foreach n [array names with] {
	set var($n) [Trim [lindex $with($n) 2]]
    }
}

proc SetUserDefault {} {
    global var

    if [catch {uplevel #0 source tixConfig.tcl}] {
	SetSysDefault
	return
    }
    if {$var(--with-cc) == "default"} {
	set var(--with-cc) ""
    }
    if {$var(--exec-prefix) == {${prefix}}} {
	set var(--exec-prefix) $var(--prefix)
    }
}

proc MakeConfigureWindow {w} {
    global app

    if [winfo exists $w] {
	destroy $w
    }
    toplevel $w

    set f [frame $w.top -relief raised -bd 1]
    set f1 [frame $f.f1]
    set t  [text $f1.t]
    set v  [scrollbar $f1.v -orient vertical]
    pack $v -side right -fill y
    pack $t -side top -expand yes -fill both

    set f2 [frame $f.f2]
    set h  [scrollbar $f2.h -orient horizontal]
    set x  [frame $f2.x -width [winfo reqwidth $v]]
    pack $x -side right -fill y
    pack $h -expand yes -fill both

    pack $f2 -side bottom -fill x
    pack $f1 -expand yes -fill both

    $t config -xscrollcommand "$h set" -yscrollcommand "$v set"
    $h config -command "$t xview"
    $v config -command "$t yview"

    set bot [frame $w.bot -relief raised -bd 1]
    set b [button $bot.b -text Cancel -command CancelConfig -width 7]
    pack $b -expand yes -padx 10 -pady 15
    pack $bot -side bottom -fill both
    pack $f -expand yes -fill both

    set app(w:text) $t
    set app(w:cancelBtn) $b
    set app(w:dialog) $w
    grab $w
}

proc RunConfigure {} {
    global app var

    set program "|./configure"

    foreach option [lsort [array names var]] {
	set value [Trim $var($option)]
	if {$value != {}} {
	    lappend program $option=$value
	}
    }

    set w .configure

    MakeConfigureWindow $w

    eval set app(pipe) [open $program  "r"]
    after idle [list catch [list fileevent $app(pipe) readable GetConfigure]]

    $app(w:text) insert end "executing $program\n\n"
}

proc CancelConfig {} {
    global app

    if {[$app(w:cancelBtn) cget -text] == "Close"} {
	destroy $app(w:dialog)
    } else {
	$app(w:cancelBtn) config -text Close -width 7 
	catch {
	    close $app(pipe)
	}
    }
}

proc GetConfigure {} {
    global app

    if {[$app(w:text) dlineinfo insert] != {}} {
	set setend 1
    } else {
	set setend 0
    }

    if {[gets $app(pipe) line] >= 0} {
	$app(w:text) insert end "$line\n"
	after idle [list catch [list fileevent $app(pipe) readable GetConfigure]]
    } else {
	catch {
	    close $app(pipe)
	}
    	grab release $app(w:dialog)
	$app(w:text) insert end "  ----- Done -------\n"
	$app(w:text) insert end " you can run \"make\" now\n"
	$app(w:cancelBtn) config -text Close
	SetUserDefault
    }

    if {$setend} {
	$app(w:text) see end
    }
}

start

